Compare commits

...

2580 commits

Author SHA1 Message Date
isaac
6e370e06d1 Force build 2026-06-05 01:05:54 +02:00
isaac
35711ec6ad Localize rich-text message preview labels; split audio into voice/music
Thread PresentationStrings through RichText/InstantPageBlock/InstantPage
previewText(), replacing the hardcoded //TODO:localize placeholders
("Photo", "Fx", "Table", "Map", ...) with localized keys and reusing the
existing Message.Photo/Video/Location strings. Add RichTextPreview.Formula
("[formula]"), RichTextPreview.Table ("[table]"), and RichTextPreview.Music
("Music").

The .audio block previously rendered the wrong label (Message.Audio is
"Voice Message"). Thread InstantPage.media down so the block can resolve
media[id] as TelegramMediaFile and split: isVoice -> "Voice Message",
otherwise -> "Music", mirroring MessageContentKind's voice/music handling.

Update both previewText() call sites (MessageContentKind, ChatListItemStrings)
to pass strings, and complete the InstantPageListItem migration that was
left on the old signature.

Also remove the dead streaming-status ("Thinking...") rendering block from
ChatMessageTextBubbleContentNode (guarded by an always-false `!"".isEmpty`)
along with the now-orphaned streamingTextFrame layout machinery it fed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 00:18:24 +02:00
isaac
0050cc7a08 Rich-message media in gallery/shared-media/preview pipelines via Message.effectiveMedia
Add Message/EngineMessage.effectiveMedia (= message.media when non-empty, else
richText.instantPage.allMedia()) and route the media-consuming sites through it
so a rich message's instant-page media participates in the same pipelines as
normal message.media: shared-media grids/file-rows, search media grid, gallery
open + item nodes + footer, the peer audio/voice playlist, secret-media preview,
resource-by-id resolution, recent downloads, downloaded-media store, delete-time
resource cleanup, cache-usage stats, the in-chat download manager, and the
context-menu / share actions (Save to Camera Roll, copy image, save audio/music
to files). For normal messages effectiveMedia == message.media, so each swap is
behavior-preserving; rich messages render their own bubble via
ChatMessageRichDataBubbleContentNode (not the text/file bubbles), so those paths
are deliberately untouched, as are the forward path (the attribute travels with
the forward) and the markdown-based rich-edit path. First-media scope for now.

See docs/instantpage-richtext.md for the full architecture + invariants.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:46:56 +02:00
isaac
c95e014681 InstantPage rich messages: index embedded media into shared-media tags
Add InstantPage.allMedia() (recursive gatherer over the page's blocks —
audio/collage/cover/details/image/list/slideshow/video — resolving each via
the page's [MediaId: Media] dict) and feed it into tagsForStoreMessage, so a
rich message's instant-page media is indexed into MessageTags
(photo/photoOrVideo/video/gif/voice/file). Rich messages now appear in the
per-peer shared-media tabs and tag-queried surfaces.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:46:16 +02:00
isaac
41aef1c928 InstantPage: exclude audio/music from the rich-content gallery
openInstantPageMedia builds the gallery from allMedias() filtered to
.image / .file. An audio track is an EngineMedia.file (a TelegramMediaFile
with an .Audio attribute), so it passed the .file case and appeared as a
gallery entry. Audio is enrolled in allMedias() only so the audio player
can gather sibling tracks for its playlist (handleOpenAudioTap); it is not
visual gallery content.

Split the .file case to keep videos/gifs/documents but drop music and
voice (!file.isMusic && !file.isVoice). No-op for V1 full-page Instant
View (its mediasFromItems never enrolled audio); fixes the V2 rich bubble.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:49:24 +02:00
isaac
0a92dbddc3 InstantPage V2: fix inline emoji/image/formula x-offset on RTL lines
Inline attachments anchored their left edge at
CTLineGetOffsetForStringIndex(line, range.location), which is the glyph's
LEFT edge for LTR runs but its RIGHT edge for RTL runs (string index
increases leftward). On an RTL line (e.g. an Arabic thinking block) this
shoved emoji/images/formulas ~one advance (~24pt) too far right while the
CoreText-drawn text stayed correct.

Add v2LeadingOffsetForRange(_:range:), which returns
min(offset(start), offset(end)) with directional-boundary secondary-offset
handling — the true leading edge in both directions. Mirrors
Display.TextNode.addEmbeddedItem and the strikethrough/underline/spoiler
decorations already in this file (which used the min/abs form; the inline
attachments had regressed to a single offset). Applied at all 5 sites:
the emoji/image/formula display frames and the emoji/image characterRect
(reveal mask). Widths unchanged; only x corrected. LTR is byte-identical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:39:13 +02:00
isaac
52db80698c Merge commit '248ee44e30' 2026-06-04 20:20:35 +02:00
isaac
dce6a8bef7 Rich messages: "Show more" to load the full page for partial InstantPages
Server-sent rich messages can arrive partial (RichMessage isPartial ->
instantPage.isComplete == false). The bubble renders the partial page with
an inline "Show more" link; tapping it fetches the full page once and
expands in place.

- RichTextMessageAttribute keeps the partial instantPage and gains an
  optional fullInstantPage, filled by engine.messages.requestFullRichText
  via transaction.updateMessage. The seed-config merge preserves a fetched
  fullInstantPage across later server updates.
- ChatMessageRichDataBubbleContentNode: node-local, per-message expand
  state (collapsed on every fresh display, even when fullInstantPage is
  already cached); renders (expanded ? fullInstantPage : nil) ?? instantPage;
  gates the link on !expanded && !isComplete (+ not streaming, Cloud-only,
  not preview/messageOptions); expand state threaded through both layout
  caches; shimmer while fetching (instant when cached); bubble grows
  downward on expand via setInvertOffsetDirection.
- New localized string Chat.RichText.ShowMore; docs in
  docs/instantpage-richtext.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 20:18:15 +02:00
Ilya Laktyushin
248ee44e30 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-06-04 19:49:10 +02:00
Ilya Laktyushin
45cc8468bb Various fixes 2026-06-04 19:49:04 +02:00
isaac
ef9c1def4e Update API 2026-06-04 16:37:07 +02:00
isaac
a5825d5a67 Rich text wip 2026-06-04 15:54:27 +02:00
isaac
0d5b051820 InstantPage V2: support nested <details> blocks
A details block nested inside another rendered (title + chevron) but could not
expand: its body is hosted by a fresh InstantPageV2View whose detailsTapped
closure was never wired (only the top-level view's is, by the bubble), so the
nested title's tap hit a nil closure and was dropped. Wire the body view's
detailsTapped to chain through this view's onTitleTapped, which makeItemView
already routes to the owning view's detailsTapped -> the bubble's toggle
handler; this chains up through arbitrary nesting depth.

Also make the bubble's defaultExpanded(forDetailsIndex:) recurse into expanded
bodies so a nested details whose model default is expanded toggles from the
correct state (the flat top-level scan missed nested indices).

Known pre-existing limitation (unchanged): V2 keys expansion state by a flat
DFS index, so expanding a nested details can shift sibling indices.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 15:30:28 +02:00
isaac
a4cddb74d6 InstantPage V2: inset + round code blocks nested in blockquotes
A code block inside a blockquote was pinned to local x=0 / full width, so its
background bled out under the quote bar instead of insetting to the quote's
content gutter like the quote's text. Detect quote nesting via the raised
child inset (threaded as LayoutContext.pageHorizontalInset) and, when nested,
inset the background to honor horizontalInset and give it an 8pt rounded
corner. Top-level and <details> code blocks stay flush, full-width, and square
(matching V1) — the bubble's own rounded clip handles their edges.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 15:19:59 +02:00
isaac
9dada484aa InstantPage V2: proper RTL layout for rich messages
When a rich message's page-level rtl flag is set, mirror every V2 block
ornament and content column onto the trailing (right) edge, gated solely on
the explicit flag (no content auto-detection, no send/wire change, V2 only):

- Two centralized leading/trailing geometry helpers (instantPageV2ContentColumnX
  / instantPageV2LeadingEdgeX) as the single source of truth for gutter side.
- Lists: content column mirrors to match the marker (8pt trailing gap).
- Blockquotes: bar + text gutter on the trailing edge, single- and multi-block
  (multi-block child band rigid-translated; caption uses its own single-inset
  delta).
- <details>: chevron + title indented from the right (rtl flag on the item).
- Uniform trailing alignment for paragraph/heading/simple-text.
- Keep the full bounding width for non-leading alignment so display-time
  alignment lands at the true edge: .right (RTL text) was collapsing short
  content to the leading edge under fitToWidth (the list-gap), and .center
  (pull quotes) was failing to center body + author. Only .natural shrinks.

LTR output is unchanged (.right/.center are only produced under RTL contexts /
pull quotes). Builds clean; runtime-verified on an rtl message with lists,
blockquotes, pull quotes, and inline formatting.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 15:01:59 +02:00
isaac
a731f8bdc0 Implement textDate autoformatter for InstantPage V2 rich bubbles
Render RichText.textDate (API constructor textDate(flags, text, date)) as a
locale/timezone-correct, relative-aware, tappable date inside V2 rich-message
bubbles, reusing the existing stringForEntityFormattedDate autoformatter.

- Model: add RichText.textDate(text📅format:) with Postbox coding,
  FlatBuffers schema (RichText.fbs; flatc regenerates), Equatable and plainText;
  parse flags->DateTimeFormat? at the API boundary (flags==0 => nil, matching
  the messageEntityFormattedDate convention) with a symmetric apiRichText()
  round-trip. The new case is handled in every exhaustive RichText switch
  (SyncCore, ApiUtils, InstantPageTextItem, InstantPageAnchorPath,
  InstantPagePreviewText, BrowserReadability, BrowserMarkdown).
- Render: attributedStringForRichText gains an optional formatDate closure;
  the V2 layout builds it from the message's strings/dateTimeFormat and threads
  it to every text-building call site, formatting the timestamp and tagging the
  run with TelegramTextAttributes.Date.
- Tappable: the Date attribute is added to linkSelectionRects hit-testing and
  mapped in the rich bubble's entityTapContent to the existing .date tap action
  (opens the date context menu).
- Live update: the V2 layout accumulates a page-wide formattedDateUpdatePeriod
  (>=10s) for relative dates; the rich bubble schedules a refresh timer on it,
  recreating it only when the period changes. The currentPageLayout cache is
  bypassed for relative-date pages so the timer-driven relayout actually
  re-formats the date.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 13:45:48 +02:00
isaac
0b912f26de Merge commit 'ec72568429' 2026-06-04 01:46:28 +02:00
isaac
cbf8f6b3f4 Filter url 2026-06-04 01:46:25 +02:00
Ilya Laktyushin
ec72568429 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-06-04 01:44:43 +02:00
Ilya Laktyushin
ec8bd9acdd Various improvements 2026-06-04 01:44:36 +02:00
isaac
a81d0ee944 Anchor navigation in InstantPage V2 / rich-content bubbles
Tapping an intra-message #fragment link in a rich-data bubble now scrolls
the chat so the matching anchor lands just below the content-area top,
expanding any enclosing collapsed <details> first. Anchors come from
server/AI-sent InstantPages (block .anchor or inline RichText.anchor); the
compose path is unchanged.

- InstantPageV2View.anchorFrame(name:) resolves an anchor's frame in the
  live layout (text/codeBlock/thinking/details/table), mirroring findTextItem.
- instantPageAnchorPath(in:name:) is a pure model walk returning the
  <details>-sibling-ordinal path to an anchor; its recursion set matches
  exactly the containers the V2 layout flattens through layoutBlock
  (.blockQuote/.cover/.list .blocks), keeping ordinals consistent with the
  layout's detailsIndexCounter.
- InstantPageV2View.firstCollapsedDetails(forOrdinalPath:) maps that path to
  the first not-yet-expanded details' live index (read, never reproduced).
- The rich bubble fills the two stubbed seams: getAnchorRect, and a
  fragment-link route in tapActionAtPoint that drives a resolve -> expand ->
  scroll state machine (pendingScrollAnchor + progress guard + a
  post-relayout hook). Taps are gated off while the message streams.

Verified by the full Bazel build; runtime behavior not yet exercised.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 01:11:27 +02:00
isaac
c46249178d Disable forward name hiding for rich messages 2026-06-02 21:18:17 +02:00
isaac
4c5c53ec0b Disable auto parsing rich messages 2026-06-02 21:13:59 +02:00
isaac
689f0408d2 Cleanup 2026-06-02 21:13:03 +02:00
isaac
9a86e79b5c Add design spec: gate Rich Text messages behind Premium
Non-premium users are blocked at send/edit when typed markdown would
produce a RichTextMessageAttribute, and shown a .premiumPaywall toast
(todo-gate pattern). Saved Messages and premium-disabled regions are
exempt. Receiving/rendering rich messages is unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 18:02:42 +02:00
isaac
cfe335d124 Merge commit '11a4dbf0a0' 2026-06-02 17:49:38 +02:00
isaac
e0fe0301bf Update layout 2026-06-02 17:49:01 +02:00
isaac
f6da30da70 InstantPage V2: audio/music rendering, playback, and file-bubble styling
Render and play InstantPageBlock.audio in the InstantPage V2 renderer
(rich-data message bubbles + the rich send preview), where audio was
previously an inert grey placeholder.

- New InstantPageV2AudioContentNode replicates the standard music message
  bubble (ChatMessageInteractiveFileNode's music layout): a SemanticStatusNode
  control (album art via playerAlbumArt + play/pause) with a download/progress
  overlay, title + "duration · performer" lines, exact fonts/colors from
  theme.chat.message.{incoming|outgoing}. Tap is driven by a
  UITapGestureRecognizer (ASControl .touchUpInside is cancelled by the chat
  ListView's gesture system). V1's InstantPageAudioNode is unchanged.
- Playback runs on InstantPageMediaPlaylist with a discriminated, message-scoped
  InstantPageMediaPlaylistId (.instantPage / .richMessage) so concurrent
  rich-message audio bubbles don't collide; the big control's play/pause comes
  from filteredPlaylistState, the overlay's download/progress from
  messageMediaFileStatus, and fetch goes through the fetch manager.
- Rich-message audio fetches via a MessageReference (threaded through the V2
  render context) instead of the synthesized webpage; FetchedMediaResource's
  .message revalidation arm now also searches RichTextMessageAttribute instant
  pages, so a stale instant-page audio/image reference can recover. Corrected a
  dormant inverted InstantPagePlaylistLocation.isEqual.
- New .mediaAudio laid-out item + layout/reveal-cost arms; the audio block lays
  out full-width at the file node's music normHeight.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 17:44:45 +02:00
isaac
899030184a InstantPageUI: fix photo gallery open transition flying off-screen
InstantImageGalleryItem.animateIn animated the transition surface-copy view
to transformedCopyViewFinalFrame (a point in the gallery item node's own
coordinate space) instead of transformedSurfaceFinalFrame (that point expressed
in the transition surface's space). ChatImageGalleryItem and
UniversalVideoGalleryItem both use the surface-space frame here; only
InstantImageGalleryItem (the InstantView photo item) had the slip.

It was harmless in V1's full-page Instant View because the surface was
window-scale and roughly aligned with the gallery, but in the V2 rich-data
chat bubble the surface is the bubble's container inside the scrolled,
flipped chat list (observed window frame ~ y:-1097 h:2107), so the
gallery-space target landed ~1100pt off-screen and the photo snapshot flew
away on open. Video used UniversalVideoGalleryItem and was unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 14:23:28 +02:00
isaac
ab68a1af82 InstantPage V2: render collage & slideshow blocks
Port V1's collage and slideshow InstantPage blocks into the V2 renderer
(previously grey-box placeholders).

- Collage: layoutCollage computes the mosaic (MosaicLayout, the grouped-message
  engine) over inner image/video sizes and flattens it into existing top-level
  .mediaImage/.mediaVideo items + a caption, so gallery / reveal-cost / registry
  / hidden-media all handle the cells with no collage-specific code. Right-edge
  cells bleed 4pt for the bubble's rounded clip.
- Slideshow: a new .slideshow laid-out item + InstantPageV2SlideshowView, an
  eager paged carousel (UIScrollView + PageControlNode) of InstantPageImageNode
  pages, wired through frame/offsetBy/collectMedias/stableId/reuse/makeItemView
  and the reveal-cost non-text list.
- Gallery transitions generalized onto InstantPageItemView via
  instantPageTransitionNode(for:)/instantPageUpdateHiddenMedia(_:) (default
  nil/no-op; explicit per-class witnesses on the 4 static media views, the
  slideshow forwards to its live pages) so the multi-media slideshow can
  participate alongside single-media views.

Docs: document both in docs/instantpage-richtext.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 13:50:40 +02:00
Ilya Laktyushin
11a4dbf0a0 Various improvements 2026-06-02 13:31:23 +02:00
Ilya Laktyushin
b15b6ebf50 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-06-02 12:46:22 +02:00
isaac
071799368d InstantPage V2: fall back to 600x300 for zero-dimension map blocks
AI/server-sent .map blocks can arrive with dimensions == 0x0 (the wire
w/h are required Int32, but the sender may put 0; our parse and both
serializers preserve whatever arrives). A zero naturalSize.height hit
instantPageV2MediaFrame's else branch and returned a height-0 frame:
the map collapsed to no space, the caption slid up into it, and the V1
node's pin floated over the caption. A zero-sized MapSnapshotMediaResource
would also make MKMapSnapshotter render nothing.

Substitute PixelDimensions(600, 300) (2:1) whenever width <= 0 ||
height <= 0, feeding effectiveDimensions to BOTH the layout naturalSize
AND the InstantPageMapAttribute so the snapshot resource is non-zero and
actually renders. Scoped to the V2 .map arm; V1 (real web articles)
always carries real dimensions and never trips this.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 11:36:18 +02:00
Ilya Laktyushin
e232a854a2 Various fixes 2026-06-02 10:48:17 +02:00
isaac
9b1573e87e InstantPage V2: flush, un-rounded block media (except audio)
All block-media kinds except .audio now lay out edge-to-edge (0 inset) with
cornerRadius 0; the bubble's existing rounded containerNode clip rounds media at
the bubble edge. Small images keep natural size (not upscaled); captions stay
inset. Shared instantPageV2MediaFrame helper + flush flag on the two media
layout helpers. V1 unchanged. Invariants documented in docs/instantpage-richtext.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 00:32:24 +02:00
isaac
973c232c21 docs: implementation plan for flush InstantPage V2 block media
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:14:26 +02:00
isaac
9dc990d5d6 docs: spec for flush un-rounded InstantPage V2 block media
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:02:52 +02:00
isaac
804c02743a docs: slim CLAUDE.md, extract rich-text/InstantPage notes
Remove stale data from CLAUDE.md and split out the large InstantPage V2 /
rich-text feature documentation into its own file.

- Drop two dead spec links (table inset/corner-radius design docs no longer
  exist), the orphaned debugRichText cleanup note (flag is read by nothing),
  and the stale "238 waves as of 2026-05-04" count.
- Remove the duplicated Postbox "Wave-selection guidance" and "facade
  inventory" subsections; both live in docs/superpowers/postbox-refactor-log.md
  and TelegramEngineResources.swift (pointer folded into the Historical record).
- Move the 13 InstantPage V2 / rich-text sections to
  docs/instantpage-richtext.md, leaving a brief pointer in CLAUDE.md.

CLAUDE.md: 507 -> 161 lines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 20:33:41 +02:00
isaac
83297bec0e Re-apply dynamic watch bundle id
Re-applies commit 1120b9084e (reverted in ef2c1d47cc during install
debugging). The install failure was proven to be the oversized watch
binary (fixed by DEAD_CODE_STRIPPING), not the bundle-id mechanism — which
was verified to produce a byte-identical artifact for ph.telegra.Telegraph.

xcodebuild bakes PRODUCT_BUNDLE_IDENTIFIER=<host>.watchkitapp and the watch
Info.plist derives WKCompanionAppBundleIdentifier via
$(PRODUCT_BUNDLE_IDENTIFIER:base), so the embedded watch app is correct for
any host (ph.telegra.Telegraph and org.telegram.TelegramInternal/enterprise)
with no post-build plist patching.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 18:07:34 +02:00
isaac
62d707b3b9 Merge branch 'watch2' 2026-06-01 18:01:00 +02:00
isaac
1872832e28 Improve InstantPage V2 layout: true font-height line boxes + code-block style
- layoutTextItem now sizes a text item to the true font line height (A + D)
  instead of the cap box: the line stack starts at lineBoxTopInset (the
  ascender headroom, max(0, fontAscent - fontLineHeight)) and the returned
  height is padded by the last line's descender. Inter-line advance is
  unchanged and per-line frames stay the cap box, so the baseline draw,
  decorations, reveal mask, and inline attachments translate consistently;
  the page grows.
- Size inline custom emoji to ~the font line height
  (font.ascender - font.descender + 4*pointSize/17) so they fit the taller
  line box instead of overflowing it; the line is not inflated.
- Add a dedicated code-block text style for rich messages (monospace font +
  codeBlock theme attribute) threaded through the rich-data bubble and send
  preview; unify the bubble code-block/separator colors.
- Adjust inter-block spacings and assorted V2 layout/divider details.
- Document the true-font-height box and emoji sizing in CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 17:33:01 +02:00
isaac
7e531ca57b temp 2026-06-01 17:23:05 +02:00
isaac
bf2f6eb560 Improve instant view v2 layout 2026-06-01 17:22:29 +02:00
isaac
5403ffa8b0 Update tgwatch 2026-06-01 15:00:17 +02:00
isaac
e0899a01d5 Adjust spacings 2026-06-01 14:59:55 +02:00
isaac
18d124ab17 InstantPage V2: text items measure true font height (A + D)
Shift the line stack down by the ascender headroom (A - L, as
`lineBoxTopInset` to avoid colliding with the existing formula-bleed
`topInset` local) and pad the returned height by the last line's
descender (D), so a single-line V2 text item is a true ascent/descent
line box measuring exactly A + D instead of the cap box A - L. Inter-line
advance unchanged; formulas still inflate via lineAscent/extraDescent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 02:20:10 +02:00
isaac
758e596bf9 InstantPage: add code-block text style for rich messages
Local in-progress work (committed at the author's request as a checkpoint
before unrelated true-font-height work lands on top): introduces a
dedicated `codeBlock` InstantPage font/text style (.monospace / .codeBlock
font cases + monospace font resolution), adds a `codeBlock` field to the
InstantPage text-attributes theme and threads it through the rich-data
bubble and the send preview, and unifies the rich-bubble code-block
background/secondary-control colors.
2026-06-01 02:14:59 +02:00
isaac
5893b574a8 Add implementation plan: V2 text items as true font-height line boxes
Task 1: 3-line metric change in layoutTextItem (topInset shift + descender
pad). Task 2: re-tune the streaming chat-bubble bottom inset (the now-
contained descender makes the +6.0 hack partly redundant). Task 3: broad
visual verification of the remaining consumers (decorations, reveal mask,
lists, blockquotes, tables, title) with one gated table-inset fix. Task 4:
spec acceptance checklist. Verification model adapted to this repo: full
Bazel build + simulator visual checks (no unit tests exist).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 02:07:03 +02:00
isaac
625aac9294 Add design spec: V2 text items as true font-height line boxes
Approach 2 (true proper line box): shift the line stack down by the
ascender headroom (exact A - L, not pixel-snapped) and pad the returned
height by the last line's descender, so a single-line V2 text item
measures exactly the true font height (A + D) instead of the cap box
(A - D). Inter-line advance unchanged; formulas still inflate.
Documents the affected height/frame consumers (chat-bubble height +
status node, streaming clip, table cells, title centering, reveal cost)
and the verification plan.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 01:59:38 +02:00
isaac
9205fb2303 Fix inline emoji/image line-height inflation in InstantPage V2
The V2 line-breaker used `lineAscent` as both the line height and the
baseline offset, then inflated it to each inline emoji/image's full visual
size and bottom-aligned the attachment on that inflated baseline. A 24pt
emoji on a ~17pt line therefore doubled the line height and shoved the
text baseline (and all text on the line) down.

Stop inflating the line for emoji/images (only formulas, which carry their
own metrics, still grow it) and center each attachment on the font line
box at `baselineY - fontLineHeight/2 - size/2`, matching V1
`layoutTextItemWithString` and the chat `InteractiveTextComponent`. The
attachment now bleeds symmetrically instead of moving the baseline.
`extraDescent` absorbs tall-attachment bottom overflow so the next line is
not overlapped, and the streaming-reveal `characterRect` is centered in
lockstep so the reveal mask tracks the cell (reveal cost stays width-only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 18:28:05 +02:00
isaac
a3492c0cb0 Update tgwatch 2026-05-31 18:13:57 +02:00
isaac
750911ce3c Merge commit '14ade58f34' 2026-05-31 18:05:01 +02:00
isaac
471ae08219 Merge commit 'e2de53ea17' 2026-05-31 18:04:21 +02:00
isaac
14ade58f34 Merge commit 'e2de53ea17' 2026-05-31 18:00:47 +02:00
isaac
6bcf266118 Remove stop button 2026-05-31 18:00:38 +02:00
isaac
ef2c1d47cc Revert "Update tgwatch signing"
Revert the universal/dynamic watch bundle id change (commit 1120b9084e)
back to the static 0682 shape, for install testing.

This reverts the PRODUCT_BUNDLE_IDENTIFIER override + $(...:base) companion-id
derivation; the watch app again bakes the hardcoded ph.telegra.Telegraph.watchkitapp
and literal WKCompanionAppBundleIdentifier=ph.telegra.Telegraph.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 17:58:30 +02:00
isaac
3ed8c926a8 Custom emoji in markdown rich messages (send + round-trip)
Parse custom emoji into RichText.textCustomEmoji when sending markdown
rich messages, and round-trip them through edit, copy, and paste using a
shared tg://emoji?id=<fileId> markdown-link marker.

- Send: rewrite each customEmoji input attribute into a
  [<alt>](tg://emoji?id=<fileId>) marker before the CommonMark parse, then
  intercept the marker URL afterward to emit .textCustomEmoji. Only rich
  messages are affected; a custom emoji alone stays on the entity path.
- Reverse: InstantPageToMarkdown (whole-message copy + edit reconstruction)
  and InstantPageMultiTextAdapter (selection copy) emit the marker;
  edit-load and chat paste reattach it as a live customEmoji attribute.
- Marker helpers shared in TextFormat/CustomEmojiMarkdownMarker.swift.
- Rich sends now pass inlineStickers so recipients can fetch the files.

Follow-up to verify at runtime: recipient rendering goes out with
Api.InputRichMessage.documents: nil; if recipients see only the fallback
glyph, populate documents: in apiInputRichMessage().

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 17:51:37 +02:00
Ilya Laktyushin
e2de53ea17 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-05-31 17:35:39 +02:00
Ilya Laktyushin
622f9d970a Various fixes 2026-05-31 17:35:32 +02:00
isaac
6408175725 InstantPage V2 thinking block: text-item sizing, overhang, inline emoji/images
Make the thinking block render consistently with a normal text item:

- Size the `.thinking` item frame text-width at the page inset
  (`(horizontalInset, 0, textWidth, height)`), identical to a `.text`
  item, instead of a full-bleed `(0, 0, boundingWidth, height)` box, by
  laying the text out flush and moving the inset onto the block frame.
  The shimmer (sized to `item.frame.size`) now hugs the text.

- Size the shimmer + its gradient mask to the clipping-inset-expanded
  frame (shifted `-inset`) so the mask no longer crops glyph ascenders,
  descenders and the last line's underline, mirroring how a `.text`
  view's frame is inset-expanded.

- Visit the thinking block's shimmer-wrapped inner text view in
  updateInlineEmoji / updateInlineImages so its inline custom emoji and
  images get layers created, positioned and revealed. They were skipped
  because the page only iterated top-level InstantPageV2TextView items.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 15:49:33 +02:00
isaac
1120b9084e Update tgwatch signing 2026-05-31 15:34:43 +02:00
isaac
d4736fe59f Revert tgwatch signing 2026-05-31 15:04:50 +02:00
isaac
f6dc52c533 Update layout 2026-05-30 23:27:26 +02:00
isaac
3525bcacb2 Add watch profile guard 2026-05-30 22:16:10 +02:00
isaac
dbd53522be Merge commit '98d148e08d' 2026-05-30 18:49:56 +02:00
isaac
eb1b918a77 InstantPage V2 table: cell layout polish (insets, text category, border width)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 18:47:04 +02:00
isaac
3d9fbdec3c InstantPage V2 table: rounded corners and corner-cell fill rounding
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 18:47:04 +02:00
isaac
79bcc7bc34 InstantPage V2 table: flush frame, inset borders
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 18:47:03 +02:00
isaac
e8de87dc7b InstantPage V2: render server-sent thinking blocks
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 18:47:03 +02:00
Ilya Laktyushin
98d148e08d Various fixes 2026-05-29 16:46:38 +02:00
isaac
484b66f28c Add implementation plan: InstantPage V2 thinking-block + cross-update view reuse
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 16:36:40 +02:00
isaac
a50f40476d Add design spec: InstantPage V2 thinking-block rendering + cross-update view reuse
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 16:28:37 +02:00
isaac
79ee96306b Update tgwatch 2026-05-29 16:08:23 +02:00
isaac
354e1c7a66 Implement InstantPageBlock.thinking (pageBlockThinking) parsing & serialization
Add a first-class InstantPageBlock.thinking(RichText) case mirroring .kicker:
- enum case + InstantPageBlockType.thinking = 30; Postbox coding & equality
- FlatBuffers InstantPageBlock_Thinking schema (appended last) + Swift codecs
- API parse at InstantPage.swift; output-only on send (apiInputBlock returns nil)
- no-op stubs in the two exhaustive switches (preview text, V2 layout)

Rendering is out of scope. Verified by a full Bazel build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 16:07:09 +02:00
isaac
bd8886b0f0 Merge commit '4b2a826682' 2026-05-29 15:47:41 +02:00
isaac
5950bbe8a1 Fix code 2026-05-29 15:47:37 +02:00
isaac
1d8931b334 Render markdown rich-text preview in send-message context screen
When the user long-presses Send in the main chat and the composed text passes the
same rich-markdown gate used at send time (richMarkdownAttributeIfNeeded), the
send-options preview bubble renders the message as rich InstantPage content,
crossfading from the raw text as the menu animates in. Plain text and custom chat
contents / edit previews are unchanged.

ChatSendMessageActionUI cannot depend on InstantPageUI (it closes a dependency
cycle via LocationUI -> AttachmentUI -> ... -> ChatTextInputActionButtonsNode), so
the rich view is built in TelegramUI (ChatSendMessageRichTextPreview, wrapping
InstantPageV2View + the outgoing message theme) and injected into the screen via a
new ChatSendMessageContextScreenRichTextPreview protocol, mirroring the existing
media-preview pattern. The main-chat send call site classifies the compose text
and injects the preview; MessageItemView lays it out within the send-button-bounded
bubble envelope and crossfades between the raw text and the rich layout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 15:46:16 +02:00
isaac
471d11df16 Copy rich messages as markdown (whole message + partial selection)
Rich messages (RichTextMessageAttribute, text == "") are copyable as
markdown two ways: the context-menu Copy action copies the whole
message, and a text selection inside the rich-data bubble copies just
the selected range. Both reconstruct markdown mirroring the edit
round-trip (markdownStringFromInstantPage).

Implements the full RichText entity case set
(mention/hashtag/cashtag/bot-command/bank-card/auto url/email/phone) with
tap interaction, the InstantPage -> markdown inverse converter and edit
round-trip, markdown-context stamping during V2 layout
(InstantPageMarkdownBlockContext: heading level, list/code/table/quote
depth), partial-selection markdown emission
(InstantPageMultiTextAdapter.markdownForRange), and numerous converter
edge-case fixes (tables, links, fenced code, blockquote line coalescing,
compact nested >> markers).

CLAUDE.md documents the feature; the spec/plan scratch docs generated
during development are not committed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 13:52:47 +02:00
Ilya Laktyushin
4b2a826682 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-05-29 10:01:53 +02:00
Ilya Laktyushin
e0f4655cc5 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-05-29 09:24:16 +02:00
isaac
65eac2fa94 Update tgwatch 2026-05-29 02:03:31 +02:00
isaac
befacaa5fe InstantPage: distinct per-level heading sizes 2026-05-29 01:54:03 +02:00
isaac
28763bb92d InstantPage blockQuote: nested-blocks payload
Upgrade InstantPageBlock.blockQuote from (text, caption) to
(blocks: [InstantPageBlock], caption). Legacy inbound shapes (API
pageBlockBlockquote, Postbox "t", FlatBuffers text) lift into
[.paragraph(text)]; outbound stays on the legacy wire constructor for
empty/single-paragraph quotes and uses pageBlockBlockquoteBlocks
otherwise. V1/V2 renderers recurse into child blocks with a fixed 10pt
inter-child gap; markdown forward/reverse, entity-expressibility, and
preview text updated. pullQuote is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:00:47 +02:00
isaac
ef7d582849 Update consumers for regenerated TL API
Regenerated TelegramApi sources and updated the affected consumers:
- InstantPage ordered-list encode: inputPageBlockOrderedList -> pageBlockOrderedList
- ChatContextResult: handle new constructor (exhaustive switch)
- JoinChannel/JoinLink: chatInviteJoinResultWebView now (botId, webview, users)
- WebUI chat-context-result preview consumers
2026-05-29 00:55:12 +02:00
isaac
54958c5b19 Fix parsing 2026-05-28 23:38:11 +02:00
isaac
4c254fe5b4 Spec: InstantPage blockQuote nested-blocks payload
Upgrades the InstantPageBlock.blockQuote case from a text-only
payload to a nested-blocks payload, covering API parse, Postbox +
FlatBuffers serialization, API encode, V1/V2 layout, markdown
forward/reverse, entity-expressibility, and preview text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 22:19:28 +02:00
isaac
a2548088f6 Update watch app 2026-05-28 22:07:52 +02:00
isaac
0be58ef45a Enable watch app cache 2026-05-28 21:23:34 +02:00
isaac
3a62d3417f Update tgwatch 2026-05-28 21:10:19 +02:00
isaac
55619c54f9 Fix crash 2026-05-28 19:31:09 +02:00
isaac
a3131ba4d2 Update watch signing 2026-05-28 19:31:00 +02:00
isaac
aa6314e5c4 Fix layout 2026-05-28 19:00:59 +02:00
isaac
045ba10386 Update tgwatch 2026-05-28 19:00:35 +02:00
isaac
8f4f463265 Fix layout 2026-05-28 18:17:02 +02:00
isaac
7b11a88231 Update CI 2026-05-28 17:25:20 +02:00
isaac
dce321c77a Fix build 2026-05-28 17:23:58 +02:00
isaac
a7440dea94 Merge commit '7ca10eb91e' 2026-05-28 16:56:18 +02:00
isaac
9195cfa7ca Rich data bubble: restore bottom inset during streaming
The bubble's bottom inset is supplied by the `statusBottomEdge + 6.0`
max() in the measure closure, but that branch is gated by `!hasDraft`.
During streaming (status hidden, alpha=0) the gate skips the max() and
nothing else supplies the inset — boundingSize.height ends up at only
`revealedContentSize.height + 2` (= bounds.maxY + closingPad + rim),
so descenders of the last revealed line sit cramped against the bubble's
bottom edge and the bubble visibly grows by 6pt the moment streaming
ends and the status node fades in.

Adds an explicit `if hasDraft { boundingSize.height += 6.0 }` after
the streamingHeaderOffset application — same 6pt the status max() would
contribute, so the streaming bubble's bottom breathing room matches its
post-stream height and the grow-pop disappears.

The `hadDraft && !hasDraft` finalize pass already gets the inset via
the status max() (since `!hasDraft` is true), so it's untouched. The
non-streaming path is also untouched.

TextBubble doesn't have this issue because it computes a position-based
`bottomInset` and adds it to boundingSize.height unconditionally (see
ChatMessageTextBubbleContentNode.swift:234-256, :827). RichData absorbed
that value into the `+ 6.0` constant inside its `!hasDraft` status
max(), which made it disappear during streaming. CLAUDE.md gains a
sibling bullet flagging that future refactor-the-constant-into-bottomInset
work must remove both ends in the same commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 16:53:34 +02:00
Ilya Laktyushin
3e6363abf9 Various improvements 2026-05-28 16:50:05 +02:00
Mikhail Filimonov
7ca10eb91e Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-05-28 15:18:03 +01:00
Mikhail Filimonov
366b85f770 guard bots 2026-05-28 15:17:57 +01:00
isaac
c13118921d Sync watch app 2026-05-28 14:26:40 +02:00
isaac
1d82735d61 InstantPage V2: render inline RichText images
Renders `RichText.image(id:, dimensions:)` runs as real fetched images
inside `ChatMessageRichDataBubbleContentNode` / `InstantPageV2View`,
replacing the gray `InstantPageV2MediaPlaceholderView`. Source is
whatever populates `instantPage.media[id]` (server-pushed webpage
InstantPages); the markdown converter is unchanged
(`markdownImageParsingEnabled` stays false).

Architecture mirrors inline custom emoji: inline images are NOT
top-level `InstantPageV2LaidOutItem`s. `InstantPageV2View` walks each
text view's `line.imageItems`, resolves each MediaId against
`layout.media`, and creates `InstantPageV2InlineImageView` children
inside a new `imageContainerView` on each `InstantPageV2TextView`
(sibling of `renderContainer`, above the reveal mask, below
`emojiContainerView`).

Streaming reveal participation: image cells contribute their full
width to the per-line character rects (mirrors emoji), so the cost map
charges the cursor by the image's width when crossing it. When the
cursor crosses the cell, `updateImageReveal` pops the view in
(opacity 0→1 + scale 0.1→1.0 over 0.2s ease-out), matching
`updateEmojiReveal` exactly. `applyReveal` calls both alongside each
other.

Non-interactive (V1 parity): `isUserInteractionEnabled = false` lets
URL-wrapping `RichText.url(text: .image(...))` route taps through to
the underlying text view's URL handler.

Key files:
- New `InstantPageV2InlineImageView.swift`: lightweight
  `TransformImageNode`-backed view. Picks the fetch signal by
  EngineMedia kind (.image → chatMessagePhoto; image-mime .file →
  instantPageImageFile; video .file → chatMessageVideo single frame).
  `MetaDisposable` cancels fetches on dealloc.
- `InstantPageV2Layout.swift`: `media`/`webpage` fields on the layout
  struct; image cells contribute to char rects; the gray-placeholder
  branch in `layoutTextItem` is removed; the dead `media`/`webpage`
  params on `layoutTextItem` are dropped along with their 13 call
  sites.
- `InstantPageRenderer.swift`: `imageContainerView` on text view
  (sibling of `renderContainer`, between it and `emojiContainerView`);
  `InlineImageKey` + `InstantPageInlineImageData` types;
  `updateInlineImages()` + `updateImageReveal()` on
  `InstantPageV2View`; wired into `update(layout:theme:animation:)`.
- `InstantPageV2RevealCost.swift`: `applyReveal` calls
  `updateImageReveal` next to `updateEmojiReveal` in both the
  clear-path branch and the entry-walking branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 14:21:25 +02:00
Mikhail Filimonov
0ba45f3b11 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-05-28 09:00:27 +01:00
isaac
ddf6999908 Optimize watch building 2026-05-28 02:45:47 +02:00
isaac
0be476ff79 Strip watch app 2026-05-28 02:13:30 +02:00
isaac
c3ab3ff218 Animate InstantPage V2 details (collapsible) expand/collapse
Thread the chat list's animated transition through InstantPageV2View.update so
reused-item frame changes animate: the toggled details view's own frame-height
(clipsToBounds) clip-reveals/clip-hides its body, sibling items below slide, and
the chevron rotates — all on the one transition the bubble already drives for its
outer height. On expand the body is added up-front; on collapse it is kept and
torn down in finalizePendingCollapse(), called from the completion of the
frame-shrink (clip) animation that hides it. Drop the forced scroll-to-center on
toggle so the bubble grows in place.

Also render the chevron as a UIImageView with a template image + tintColor (the
message's primary text color) instead of baking the tint into a CALayer's cgImage
contents, which dropped the color and rendered it black.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 02:12:02 +02:00
Ilya Laktyushin
c9a9f8a060 Various fixes 2026-05-27 19:05:44 +02:00
Ilya Laktyushin
21d5b4879b Various fixes 2026-05-27 19:05:44 +02:00
isaac
93aff4b716 Document InstantPage task-list checkboxes in CLAUDE.md
Add a section covering the first-class InstantPageListItem.checked field:
where things live, the API flags.0/flags.1 transmission, tri-state Postbox/
FlatBuffers persistence, V1/V2 detection + V2 CheckNode hosting, and the
markdown round-trip contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 18:35:32 +02:00
Mikhail Filimonov
4cb80e456b Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-05-27 16:11:06 +01:00
isaac
0a9f93abd6 Fix build command path in list-checkbox plan (Make/Make.py)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 16:45:06 +02:00
isaac
81e3be1923 InstantPage list checkboxes (task-list style): parse, serialize, render
Add a first-class `checked: Bool?` to InstantPageListItem (orthogonal to the
ordered-list `num`), replacing the prior sentinel-string-in-num prototype.

- Data model: enum third associated value on .text/.blocks; Postbox + a new
  FlatBuffers `checkState` tri-state field (0=nil,1=unchecked,2=checked,
  backward-compatible); Equatable.
- Transmission: read/write the native API `checkbox`=flags.0 / `checked`=flags.1
  bits on all four PageListItem / PageListOrderedItem constructors, so checkbox
  state survives the server round-trip for sender and recipients.
- Markdown: forward parser routes detected `[ ]`/`[x]` into `checked` (keeping
  the real number for ordered items); reverse converter emits `- [ ]`/`- [x]`
  so editing a rich message round-trips.
- Display: V1 + V2 layout detect via `item.checked`; the V2 renderer draws real
  CheckNode artwork (was a placeholder); preview text shows a checkbox glyph
  instead of leaking the old sentinel.

Spec: docs/superpowers/specs/2026-05-27-instantpage-list-checkbox-design.md
Plan: docs/superpowers/plans/2026-05-27-instantpage-list-checkbox.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 16:44:47 +02:00
isaac
ebe37cc714 Implementation plan: InstantPage list checkboxes (task-list style)
11 tasks: data model (enum + Postbox + FlatBuffers + Equatable), API
transmission via checkbox/checked flag bits, markdown forward/reverse,
preview text, V1/V2 layout detection, V2 CheckNode artwork, build-to-green,
and manual round-trip verification.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 15:52:58 +02:00
isaac
6bfb4857b2 Design spec: InstantPage list checkboxes (task-list style)
First-class checked: Bool? on InstantPageListItem (orthogonal to num),
replacing the prior sentinel-in-num prototype. Covers parsing, Postbox +
FlatBuffers serialization, API transmission via the native checkbox/checked
flag bits, V2 CheckNode artwork, edit round-trip, and preview text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 15:45:24 +02:00
Mikhail Filimonov
a91c1d5e8a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-05-27 12:55:06 +01:00
Mikhail Filimonov
a4b44a4739 same origin 2026-05-27 12:54:59 +01:00
isaac
0682ac9d57 Update signing 2026-05-27 01:06:41 +02:00
isaac
64190e2c34 Bump version 2026-05-27 00:06:37 +02:00
isaac
81d8ae4c67 Update CI 2026-05-26 23:32:44 +02:00
isaac
a250c71991 Update CI 2026-05-26 23:24:45 +02:00
isaac
abbd5aef9d Adjust layout 2026-05-26 23:22:50 +02:00
isaac
8b77eb7c81 Update CI 2026-05-26 23:22:37 +02:00
isaac
78267e8902 Vendor tgwatch sources into Telegram/WatchApp; build from in-repo snapshot
Vendor the standalone tgwatch watch-app sources into Telegram/WatchApp/ as a
tracked snapshot and build it from there by default (tracked Bazel inputs).
Make.py drives embedding via --embedWatchApp (--watchAppSourcePath removed);
the filegroup excludes .swiftpm/.build. Documented in CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:12:16 +02:00
isaac
64c9e72fad Embed xcodebuild-built tgwatch app into the Bazel Telegram IPA
Add the apple_prebuilt_watchos_application rule (prebuilt_watchos.bzl + its
worker) that runs xcodebuild on the watch app, codesigns the .app and nested
framework, and feeds it to the Telegram ios_application's watch_application
slot, gated on //Telegram:embedWatchApp. Make.py gains device-gated watch
embed flags (--watchApiId/--watchApiHash/--watchSigningIdentity/
--watchProvisioningProfile), and the embedded app's version is matched to the
host (versions.json + buildNumber).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:11:36 +02:00
isaac
675252724f Make formulas trigger rich messages (strict math detection)
$…$/$$…$$ (and \(…\)/\[…\]) math now sends a rich message, gated by a
strict boundary rule so casual $ usage stays plain: inline detection uses a
4-way boundary check (rejecting $5-$10, $FOO=$BAR) and block $$ requires an
exact/bare opener. Math delimiters are added to the rich pre-filter.
Documented in CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:11:17 +02:00
isaac
a9f8b0d067 Make rich messages editable via InstantPage↔markdown round-trip
Reconstruct markdown source from a stored InstantPage to populate the edit
field, then re-classify on save (the inverse of the send path). Adds the
InstantPageToMarkdown converter, edit-field population and save-time
re-classification in ChatControllerLoadDisplayNode, and a shared InstantPage
previewText surfaced through MessageContentKind for reply/pinned/forward
previews. Documented in CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:10:48 +02:00
isaac
e1b48665a8 Auto-detect rich vs. entity markdown on send
Classify typed markdown on send: structure the message-entity set can't
represent (headings, lists, tables) is sent as a rich message
(RichTextMessageAttribute carrying an InstantPage); everything else takes
the existing entity path. Adds the parse-then-inspect classifier in
BrowserMarkdown, gates it in ChatControllerNode.sendCurrentMessage
(replacing the debugRichText flag), drops formulas/dividers as triggers,
and cleans up heading blocks for the chat path. Documented in CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:10:15 +02:00
Mikhail Filimonov
348718de5e Merge branch 'experimental-3' 2026-05-26 11:58:59 +01:00
isaac
38464954b0 Update API 2026-05-24 00:24:21 +04:00
isaac
8b9f498d53 RichText.textSpoiler: dust overlay + tap-to-reveal in rich-data bubbles
Add the RichText.textSpoiler case end-to-end: model + Postbox coding,
FlatBuffers schema/codec, and Api.RichText parsing/serialization (lossless).
Display attaches the spoiler attribute, collects per-line spoiler rects in
the V2 layout, clips obscured glyphs and draws an energy-gated dust overlay
in the V2 text view, propagates the reveal flag across the nested V2 tree
(building dust for freshly-created text views), and wires tap-to-reveal
routing in the rich-data bubble.

Also seeds the streaming reveal cursor across chunk rebuilds and refines
status date positioning.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 22:12:47 +04:00
isaac
99e4c41b24 RichText: entity cases (mention / hashtag / cashtag / bot command / bank card / auto link)
Implement the nine message-entity RichText cases (textMention,
textMentionName, textHashtag, textCashtag, textBotCommand, textBankCard,
textAutoUrl, textAutoEmail, textAutoPhone): model + Postbox coding,
FlatBuffers schema/codec, Api.RichText parsing/serialization (lossless),
InstantPage display attaching the matching TelegramTextAttributes keys, and
tap routing in the rich-data bubble mirroring ChatMessageTextBubbleContentNode.
mentionName display resolves via EnginePeer.Id (PeerId not in scope).

Also lets rich-data text selection reach a line's trailing edge and fixes
the date/status node positioning to match TextBubble.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 22:12:47 +04:00
isaac
b48b96ecd9 RichText.textCustomEmoji: inline animated custom emoji in rich-data bubbles
Add the RichText.textCustomEmoji(fileId:alt:) case end-to-end: model +
Postbox coding, FlatBuffers schema/codec, and Api.RichText
parsing/serialization (lossless), plus display in the InstantPage V2
renderer. The emoji renders as an InlineStickerItemLayer that participates
in the streaming reveal (pops in as the reveal cursor crosses it) and is
gated by the bubble's visibility rect, propagated recursively through the
nested V2 view tree. Also frees the CTRunDelegate extent buffers for the
image/formula/custom-emoji attachment arms and documents the feature in
CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 22:12:47 +04:00
isaac
ded413ae74 Add design spec: RichText.textCustomEmoji parsing, serialization & display
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 17:02:47 +08:00
Mikhail Filimonov
8a62072984 macos 2026-05-21 20:04:05 +01:00
isaac
3c939d0c87 Update xcodebuildmcp config 2026-05-20 00:34:25 +08:00
isaac
dd9adeeaf2 Update gitignore 2026-05-20 00:34:25 +08:00
isaac
3f09a1f325 WIP 2026-05-20 00:34:25 +08:00
isaac
562de27c30 InstantPage V2: AI streaming animation for rich-data bubbles
Spec, plan, and full implementation of the AI-message streaming
animation in ChatMessageRichDataBubbleContentNode. Extracts
TextRevealController into a shared StreamingTextReveal submodule;
precomputes per-character rects in V2 layout (RTL-safe, glyph-ink
bounds); splits InstantPageV2TextView into render container + render
view with a reveal mask layer; implements mask + snippet pop-in
reveal; adds a per-text-view reveal cost map + applyReveal extension;
switches reveal cost to a width-based unit; sizes / clips the bubble
to the revealed prefix during streaming; aligns the Thinking… header
with TextBubble; floors table cell reveal cost at cell frame width;
includes layout closing pad in revealedContentSize; documents the
non-obvious invariants in CLAUDE.md.
2026-05-20 00:34:07 +08:00
isaac
a53ef1f299 InstantPage V2: inline-formula baseline alignment
Snapshot list marker subviews/sublayers before iteration, anchor
strike/underline drawing to item frame height, baseline-align inline
text, images, and formulas. Also: implementation plan and two spec
refreshes (clarify extraDescent nudge removal; refresh stale line
numbers).
2026-05-20 00:33:55 +08:00
isaac
8dbbf0f715 Rich-bubble text selection (post-V2 fix)
Design and plan, then implementation: include the details title in
selectableTextItems, restore V2 text selection in the rich bubble,
drop the InstantPageMultiTextAdapter init parameter-name split, and
split LinkHighlightingNode modern-path groups on disjoint rects.
Also includes the IP V2 inline-formula baseline alignment design doc.
2026-05-20 00:33:47 +08:00
isaac
3a22e7c81b Fix clipping 2026-05-20 00:33:32 +08:00
isaac
e2da230af6 InstantPage V2: media rendering (image / video / map / cover)
Design and plan, then the implementation: extract a shared
openInstantPageMedia helper for V1+V2 reuse, add typed media item
cases + allMedias() helper, introduce InstantPageV2RenderContext and
thread it through the view tree, add four media wrapper views, route
layout dispatch through typed media items, let the chat bubble build
the render context so real media renders, wire gallery tap routing,
cache V2View by message id + stableVersion, add stable-id identity +
per-class update(item:theme:), reuse item views on re-layouts via
stable-id harvest, preserve TextView clipping inset on reuse, and let
the use site control media-reference construction.
2026-05-20 00:33:28 +08:00
isaac
0a3030deed InstantPage V2: formula display
Design, plan, and implementation. Adds .formula item case +
InstantPageV2FormulaView, bumps InstantPageMathAttachment fields to
public, routes block and inline formulas through .formula items,
aligns the scroll view with V1 (alwaysBounceHorizontal = false), and
reports narrow block formula natural width so the fitToWidth bubble
shrinks.
2026-05-20 00:33:18 +08:00
isaac
6a0c8d9e07 Fix gif rendering issues 2026-05-20 00:33:11 +08:00
isaac
13a153aff2 WIP 2026-05-20 00:33:08 +08:00
isaac
50da64adfa InstantPage V2: TextView clipping inset
Design and plan, then the implementation: grow InstantPageV2TextView
frame by 4pt on each side to avoid clipping descenders and italic
overhangs.
2026-05-20 00:33:04 +08:00
isaac
c32ef046b7 InstantPage V2: implementation
Initial design, plan, scaffold, and the full incremental implementation
of InstantPage V2 used by ChatMessageRichDataBubbleContentNode: layout
data types and driver, shared text helpers, text view / divider /
anchor, lists, code blocks, block/pull quotes, media placeholders,
details (with recursion), tables, hit-test / selection / last-line
helpers, V1→V2 swap in the rich-data bubble, and post-swap fix-ups
(cache key, RTL paragraphs, list geometry, lazy pageView construction,
fitToWidth horizontal inset, V2View.update() no longer writes
self.frame).
2026-05-20 00:32:44 +08:00
isaac
cea2846249 Reveal pacing: switch to predicted-arrival algorithm
Adds the V2 reveal-pacing simulator and switches the live pacing
controller from the EWMA inter-arrival approach to a predicted-arrival
algorithm.
2026-05-20 00:32:08 +08:00
isaac
e06e154396 Rich bubble: add statusNode
Spec, plan, and implementation of the date / checks / reactions /
effects status node on ChatMessageRichDataBubbleContentNode. Hoists
layout work out of the inner closure and anchors the status frame top
at text maxY.
2026-05-20 00:30:48 +08:00
isaac
39d33d998c Fix audio route button 2026-05-20 00:30:43 +08:00
isaac
9e3c16cde5 Live typing draft reveal pacing
Smooth-pace reveal of incoming live typing drafts. Adds the design
doc, implementation plan, the EWMA inter-arrival → velocity-smoothed
cursor core, handling for text shrink / item loss, and debug logs.
2026-05-20 00:30:39 +08:00
isaac
b8ee5493d9 Postbox refactor waves 427-437: combinedView → engine.data migrations
Squashed batch of 14 consumer-side migrations from Postbox
combinedView/subscribe patterns to TelegramEngine.data.subscribe /
.get, plus two engine-data-item additions.

- Wave 427: DataAndStorageSettingsController preferences subscribe
- Wave 428: SaveIncomingMediaController inner preferences subscribe
- Wave 429: SaveIncomingMediaController top-level preferences subscribe
- Wave 430 (reverted + retried as 430-retry):
    initial TabBarChatListFilterController globalNotifications attempt
    landed and was reverted; replaced by ChatControllerContentData
    messageAndTopic collapse via additive Messages.MessageCount
    handleThreads/namespace parameter
- Wave 431: ChatControllerContentData savedMessagesPeer collapse via
    new Peer.MainPeer(id:) engine data item
- Wave 432 (+ followup): 6 messageHistoryThreadInfo sites to
    Messages.ThreadInfo
- Wave 433: ChatListController cachedPeerData → engine.data.get
- Wave 434: 8 orderedItemList sites to Collections.Featured*Packs
- Wave 435: StorageUsageExceptionsScreen preferences combinedView
- Wave 436: FeaturedStickersScreen 2 itemCollectionInfos sites
- Wave 437: extends Messages.PeerUnreadCount with handleThreads
    parameter + migrates AccountContext unreadCount site
2026-05-20 00:18:15 +08:00
Ilya Laktyushin
5fbe230308 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-05-14 12:49:09 +02:00
Ilya Laktyushin
91eb779ae2 Merge commit 'c64653ed37' 2026-05-14 12:45:26 +02:00
isaac
c64653ed37 Bump version 2026-05-07 07:40:39 +02:00
isaac
4107263747 Postbox refactor waves 358-426
Squashed range bf01b4c..a66739c (70 commits) covering 69 waves of the
Postbox -> TelegramEngine consumer migration plus a few BUILD-dep
followups.

Notable additions to TelegramCore in this range:
- Engine typealiases: EngineRawPeerPresence, EngineRawValueBoxKey,
  EngineSimpleDictionary, EngineRawPeerView, EngineRawPostboxViewKey,
  EngineRawPreferencesView, EngineRawMessageHistoryView (+ entry/attrs/
  read-state), EngineMessageIdNamespaces, EngineHistoryViewInputAnchor,
  EngineRawUnreadMessageCountsItem, EngineRawMessageHistorySavedMessages
  IndexView, EngineRawChatInterfaceStateView, EngineRawOrderedItemList
  View, EngineRawMessageHistoryThreadIndexView, EngineRawCombinedRead
  StateView, EngineRawMessageHistoryThreadInfoView, EngineRawBasicPeer
  View, EngineRawCachedPeerDataView, EngineMessageHistoryThreadData,
  EngineViewUpdateType, EngineInitialMessageHistoryData,
  EnginePeerGroupId, EngineChatLocationInput, EngineHistoryViewInputTag.
- Engine data items: Peer.CachedData, ItemCollections.InstalledPackInfos,
  ItemCollections.InstalledPackIds.
- Engine facade: TelegramEngine.ItemCollections.allItems(namespace:).
- Free function: engineAreMediaArraysEqual forwarder.

Net effect: 65+ consumer modules drop "import Postbox"; 131 files
changed (+1386 / -1493). Build green at HEAD.
2026-05-07 07:36:30 +02:00
isaac
bf01b4c858 Postbox refactor wave 357: drop orphan //submodules/Postbox BUILD deps
Sweep 14 BUILD files whose modules no longer have any source file with
`import Postbox`. All targets are ChatMessage*BubbleContentNode subclasses
plus WallpaperPreviewMedia — modules whose Swift sources stopped importing
Postbox in earlier waves but whose BUILD deps were not cleaned up.

Pre-flight: for each `BUILD` containing `"//submodules/Postbox"`, verified
no source file under `<module>/Sources` matches `^import Postbox$`. 14
modules met the criterion.

Build: 15s warm-cache verify, 0 errors.

Modules:
- ChatMessageActionBubbleContentNode
- ChatMessageEventLogPreviousDescriptionContentNode
- ChatMessageEventLogPreviousLinkContentNode
- ChatMessageEventLogPreviousMessageContentNode
- ChatMessageFileBubbleContentNode
- ChatMessageGameBubbleContentNode
- ChatMessageInvoiceBubbleContentNode
- ChatMessageMapBubbleContentNode
- ChatMessageMediaBubbleContentNode
- ChatMessageProfilePhotoSuggestionContentNode
- ChatMessageStoryMentionContentNode
- ChatMessageWallpaperBubbleContentNode
- ChatMessageWebpageBubbleContentNode
- WallpaperPreviewMedia

Pre-wave attempt failure note: tried 5 source-side `import Postbox` drops
first (StatsMessageItem, StarsAvatarComponent, PeerListItemComponent,
WebAppMessagePreviewScreen, OpenChatMessage). All 5 hit hidden bare
`Media`/`Message`/`PeerStoryStats`/`areMediaArraysEqual` references that
the prior pre-flight regex missed. Reverted source edits; only the
risk-free BUILD-dep sweep survives in this commit.

Lesson: pre-flight regex MUST include bare Postbox protocols
`\bMedia\b`, `\bMessage\b`, `\bPeer\b`, plus the Postbox helper
`areMediaArraysEqual` and the `PeerStoryStats` type. The previous
identifier-typealias-only regex was insufficient.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 21:01:48 +02:00
isaac
71ac72d463 Upate webrtc 2026-05-05 20:32:33 +02:00
isaac
05fe27d0f7 Update tgcalls 2026-05-05 20:28:43 +02:00
isaac
3e9b0742d1 Fix custom emoji 2026-05-05 20:23:06 +02:00
isaac
05f1f19ab0 Context controller portal-view transition 2026-05-05 20:26:25 +02:00
isaac
3051b1f3e4 Add implementation plan: context controller portal-view transition
Eight-task plan covering ContextUI struct field additions,
PortalTransitionStaging helper, CCEPN animateIn/animateOut wiring,
ChatControllerNode contextTransitionContainer, two adopter sources,
and manual visual verification.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 17:26:09 +02:00
isaac
4de5eeccd2 Various improvements 2026-05-05 16:53:47 +02:00
isaac
aafe6d8dab Add implementation plan for ShimmeringMaskView
Three task plan: (1) trim ShimmeringMask BUILD deps, (2) replace stub
with full reveal-mask CAGradientLayer implementation, (3) wrap
streamingStatusTextNode in ChatMessageTextBubbleContentNode. Plus a
manual-verification task since the project has no unit-test harness.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:53:13 +02:00
isaac
797326d669 Add design spec for ShimmeringMaskView
Reusable view that applies a moving alpha-mask shimmer (rest=1.0,
dip=peakAlpha) to its contentView. First consumer: the streaming-status
text node in ChatMessageTextBubbleContentNode for ChatGPT-style
"thinking" effect.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:41:05 +02:00
isaac
f7dcf20f69 Add design spec: context controller portal-view transition
Replaces CCEPN's manual visible-area clipping with a portal-based
transition mirroring CMTN's primitive. Adds optional
sourceTransitionSurface to TakeViewInfo/PutBackInfo; chat is the
first adopter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:27:20 +02:00
Ilya Laktyushin
7a7333edab Various improvements 2026-05-05 14:57:06 +02:00
isaac
e918b353ec Postbox refactor waves 278-356: squash
Squashes 79 sequential refactor waves into a single commit.

Highlights:
- Drop `import Postbox` (and matching `//submodules/Postbox` BUILD deps) from a wide swath of consumer files: ChatList, ChatMessage*BubbleContentNode subclasses, ListMessageNode/ListMessageItem, GalleryData, ChatHistorySearchContainerNode, ChatPanelInterfaceInteraction, ChatControllerInteraction, ChatMessageStickerItemNode, ChatMessageReplyInfoNode, ChatMessageInstantVideoItemNode, ChatPresentationInterfaceState, BrowserMarkdown/Readability, MediaResources, LocalMediaResources, ICloudResources, FetchManager, ShareController, OpenChatMessage, GalleryController, GroupStickerSearchContainerNode, GroupStickerPackCurrentItem, ChatPinnedMessageTitlePanelNode, OverlayAudioPlayerController, PresentationThemeSettings, StatisticsUI/StoryIconNode, TextFormat/StringWithAppliedEntities, GalleryUI/VideoAdComponent, StickerPackPreviewUI, WallpaperPreviewMedia, WallpaperResources, YoutubeEmbedImplementation, InstantPageExternalMediaResource, PlatformRestrictionMatching, TelegramUIDeclareEncodables, ChatListNode/ChatListSearchContainerNode.
- Add `TelegramEngine` facades: `Themes.wallpapers`, `Themes.themes`, `AccountData.addAppLogEvent`.
- Add `EngineMessageHistoryEntryLocation` wrapper.
- Add `EngineRaw*` escape-hatch typealiases (`EngineRawMessage`, `EngineRawPeer`, `EngineRawMedia`, `EngineRawMediaResource`, `EngineRawMediaResourceData`, `EngineRawItemCollectionItem`, `EngineRawItemCollectionInfo`) and `engineDeclareEncodable` forwarder.
- Drop unused `account:`/`postbox:`/`network:` parameters from several public functions and delete the dead overloads/types/functions left over: `automaticThemeShouldSwitchNow`, `cancelFreeMediaFileInteractiveFetch`, `legacyEnqueueVideoMessage`, `TelegramMediaFileReference`, plus assorted dead public TelegramCore/AccountContext SecureId entry points.
- Delete entire dead modules: `LegacyDataImport`, `TonBinding`, `SpotlightSupport`, `SvgRendering`, third-party `AppCenter`/`VectorPlus`/`SwiftColor`/`SwiftSVG`.
- Drop orphan `//submodules/Postbox` BUILD deps across 3 cleanup rounds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:11:06 +02:00
isaac
ea0f6a685c Postbox refactor wave 277: cachedWallpaper(account:) → cachedWallpaper(engine:network:)
Migrate `cachedWallpaper(account: Account, ...)` in WallpaperCache.swift to
take `(engine: TelegramEngine, network: Network, ...)` instead of the umbrella
Account parameter. Body drops the local `let engine = TelegramEngine(account:)`
since engine is now a parameter; `account.network` is now `network`.

19 context-based callers (`account: context.account` /
`self.context.account` / `component.context.account`) update via perl
sweep to pass `engine: context.engine, network: context.account.network`.

3 internal-Account-typed callers (WallpaperResources.swift × 2,
ThemeUpdateManager.swift × 1) bridge with adhoc
`engine: TelegramEngine(account: account), network: account.network`
since they're inside functions that still take `account: Account` and have
heavier Postbox uses we can't migrate yet.

Drops `import Postbox` from WallpaperCache.swift since the only remaining
Postbox-ish identifier was `ValueBoxKey`, which swaps to `EngineDataBuffer`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 00:54:26 +02:00
isaac
ab7fc69e16 Merge commit '93244da737' 2026-05-05 00:45:32 +02:00
isaac
69bfc65da7 Postbox refactor waves 138–276: 168-commit squash
Consolidates 137 wave commits + 31 supporting commits (CLAUDE.md bump,
typealias additions, AnyObject→EngineMedia restoration) into one squashed
commit. Migrates dozens of consumer-side public APIs, struct fields,
protocol methods, and enum payloads from Postbox protocols/structs to
TelegramEngine engine wrappers and typealiases. Drops `import Postbox`
from many files. Adds new TelegramCore typealiases and one
TelegramEngineUnauthorized facade.

Notable changes by category:

**TelegramCore typealias additions** (rule 2 — narrow utility typealiases):
- EngineChatListIndex, EngineTempBoxFile, EngineItemCollectionItemIndex,
  EngineItemCollectionViewEntryIndex, EngineValueBoxEncryptionParameters,
  EngineMessageAndThreadId, EnginePeerStoryStats, EngineMessageHistoryAnchorIndex,
  EngineChatListTotalUnreadStateCategory, EngineChatListTotalUnreadStateStats,
  EnginePeerSummaryCounterTags, EngineChatListTotalUnreadState,
  EngineItemCacheEntryId, EngineHashFunctions,
  EngineCachedMediaResourceRepresentationResult,
  EngineMediaResourceDataFetchResult, EngineMediaResourceDataFetchError,
  EngineMediaResourceStatus, EngineCachedPeerData

**TelegramCore engine extensions/forwarders**:
- EngineMessage.engineMedia, EngineMessage.enginePeers,
  EngineMessage.adAttribute, EngineMessage.effectivelyIncoming
- engineFileSize forwarder
- TelegramEngine.Resources.clearCachedMediaResources(mediaResourceIds: Set<EngineMediaResource.Id>)
- TelegramEngine.Resources.fetchStatus(id:resourceSize:)
- TelegramEngineUnauthorized.UnauthorizedResources facade with storeResourceData

**Public API/struct migrations to engine types**:
- ChatAvailableMessageActions.banAuthor/banAuthors → EnginePeer?/[EnginePeer]
- WebSessionsContextState.peers → [EnginePeer.Id: EnginePeer]
- CacheUsageStats.peers → [EnginePeer.Id: EnginePeer]
- PeerCommand.peer → EnginePeer
- PeerInfoControllerMode.calls(messages:) → [EngineMessage]
- CallControllerNodeProtocol.updatePeer → EnginePeer params
- ChatHistoryListNode.messageInCurrentHistoryView (and 4 variants) → EngineMessage?
- ChatHistorySearchContainerNode.messageForGallery → EngineMessage?
- PeerInfoPaneNode.findLoadedMessage / ensureMessageIsVisible /
  transitionNodeForGallery → engine-typed
- GalleryHiddenMediaTarget.getTransitionInfo /
  GalleryHiddenMediaManager.findTarget → engine-typed
- ChatPanelInterfaceInteraction.presentReactionDeletionOptions /
  presentBan*MessageOptions → EnginePeer
- DrawingMessageRenderer.messages → [EngineMessage]
- ChatVideoGalleryItemScrubberView.setFetchStatusSignal →
  EngineMediaResource.FetchStatus
- ChannelDiscussionGroupActionSheetItem.peer, VoiceChatPeerEntry.peer,
  VoiceChatFullscreenParticipantItem.peer, MediaStreamComponent.chatPeer,
  MediaStreamVideoComponent.callPeer, ChatMessageContactBubbleContentNode.contactPeer,
  ChatMessageForwardInfoNode.peer, ChatMessageCommentFooterContentNode.replyPeers,
  ChatReportPeerTitlePanelNode.peer, ChatMessageActionUrlAuthController.bot,
  PeerMediaCollectionInterfaceState.peer, ChatMessageCallBubbleContentNode.peopleAvatars,
  ChatLoadingNode.renderedPeer (→ EngineRenderedPeer) — all to engine types

**Wave-71-shadow stored-field migrations** (Postbox Peer/Message → Engine wrapper):
- LegacyCallControllerNode.peer
- CallStatusBarNode.currentPeer

**Dead-code / dead-field removals**:
- CallController.peer, CallControllerNodeV2.account,
  ContactMultiselectionController PeerNameIndex fields,
  preparedChatListNodeViewTransition account: Account param,
  FetchResource.swift entirely (unused function)

**Module-level Postbox import drops**: 30+ files including TelegramRootController,
EditStories, GiftViewScreen, AnimatedStickerUtils, FetchPhotoLibraryImageResource,
PeerInfoGiftsPaneNode, PeerInfoPaneContainerNode, PresentAddMembers,
PeerInfoProfileItems, ChatControllerAdminBanUsers, PresentationData typealiases,
DefaultDayPresentationTheme, ChatListViewTransition, GalleryHiddenMediaManager,
RecentSessionsController, GifContext, AuthorizationSequenceController,
PeerInfoHeaderEditingContentNode, PeerInfoHeaderNode,
PeerAllowedReactionListController, CallControllerNodeV2, and 6 PeerInfo pane files.

**AnyObject restoration**: rule 8 added (never substitute Postbox protocols
with Any/AnyObject) — undid previous AnyObject substitutions in waves 141/143
back to EngineMedia.

Doc maintenance: CLAUDE.md updated to reflect new typealiases and forwarders.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 00:44:27 +02:00
isaac
631df15f40 Refactoring 2026-05-03 10:31:22 +02:00
isaac
86d1456552 Postbox -> TelegramEngine waves 107-137 (squashed)
31 waves of consumer-side migration from `import Postbox` to TelegramEngine
typealiases. Net: 173 import drops + 39 BUILD-dep drops + 1 new typealias
(`EngineStoryId = StoryId`, wave 113).

Wave shapes used:
- Orphan-import sweeps (107, 108, 128): drop `import Postbox` from files
  whose only Postbox-symbol reference was the import line itself, then
  resolve build failures. Methodology requires token-level (`grep -oE`)
  filtering, not line-level, to avoid masking real Postbox usage on lines
  that also contain `Namespaces.X` references.
- Identifier-swap mini-waves (109-127, 129-134, 136-137): rename
  Postbox-typealiased identifiers to engine equivalents
  (PeerId -> EnginePeer.Id, MessageId -> EngineMessage.Id,
  MediaId -> EngineMedia.Id, MessageIndex -> EngineMessage.Index,
  StoryId -> EngineStoryId, ItemCollectionId -> EngineItemCollectionId,
  PreferencesEntry -> EnginePreferencesEntry,
  FetchResourceSourceType/Error -> EngineFetchResourceSourceType/Error,
  MemoryBuffer -> EngineMemoryBuffer, MessageTags -> EngineMessage.Tags,
  MessageAttribute -> EngineMessage.Attribute,
  TempBox -> EngineTempBox).
- Asset-string FP-only orphans (124).
- Typealias addition + drain (113): added `EngineStoryId` typealias to
  TelegramCore, then drained 3+11 consumer sites.

Hard blockers identified during these waves (must restore `import Postbox`
when present): MediaResource[A-Za-z]* (any suffix -- the literal
`MediaResource` matches don't catch MediaResourceData/MediaResourceId/etc.),
Postbox/MediaBox/MediaResource raw types, PostboxCoding/PostboxEncoder/
PostboxDecoder, TempBoxFile, ValueBoxKey, PostboxView, combinedView,
HashFunctions, postboxLog, openPostbox, declareEncodable, PeerView,
MessageHistoryView, MessageHistoryThreadData, CachedPeerData, RenderedPeer,
SelectivePrivacyPeer, SimpleDictionary, ItemCollectionInfosView,
ItemCollectionItem, ItemCollectionItemIndex, ItemCollectionViewEntryIndex,
ChatListIndex, ChatListEntrySummaryComponents, CodableEntry,
MessageHistoryThread, MessageHistoryAnchorIndex,
MessageHistoryEntryLocation, PeerStoryStats, PeerNameIndex,
PeerSummaryCounterTags, ChatListTotalUnreadStateCategory/Stats,
arePeersEqual. Protocol-shape blockers: bare `Peer`/`Message`/`Media`
in function signatures, generic args, enum-case payloads, or dict value
types (e.g., `[PeerId: Peer]`, `case messages([Message])`,
`Signal<(Peer?, ...), NoError>`).

`replace_all PeerId -> EnginePeer.Id` is dangerous: mangles compound
names like `failedPeerId`, `ContactListPeerId`, `nextRemoteMediaId`,
`replyToMessageId`. Pre-flight grep `\b[a-z][a-zA-Z]*PeerId\b` and only
replace_all if 0 matches.

Also removes unneeded design/plan docs from a separate (link-highlighting)
feature branch:
- docs/superpowers/plans/2026-05-02-link-highlighting-modern-path-fixes.md
- docs/superpowers/specs/2026-05-02-link-highlighting-modern-path-fixes-design.md

Squashed commits: 6d82c2980d..e6de5d53a3 (59 commits, including
per-wave content commits and per-wave CLAUDE.md bumps).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 10:28:50 +02:00
Mikhail Filimonov
93244da737 macos 2026-05-02 11:56:45 +01:00
isaac
b1aab0839c LinkHighlightingNode: ceil instead of floor for stair-step radii
drawRectsImageContent's modern path computed nextRadius and
prevRadius as min(outerRadius, floor(|Δx| * 0.5)). When |Δx| < 2
the floor produces 0 and the addArc call becomes a no-op,
leaving an unsmoothed corner at the stair-step. Replace floor
with ceil so any non-zero edge mismatch rounds up to at least
1 px. Exact-equality cases (Δx == 0) are unaffected — they take
the else branch with a straight addLine.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 11:46:38 +02:00
isaac
d1c5d66bd3 LinkHighlightingNode: fix X-edge snap unreachable after midY snap
In drawRectsImageContent's modern path the snap loop runs midY
trimming first, leaving rects[i].maxY == rects[i+1].minY for
adjacent line rects. The X-edge snap guard then evaluated
rects[i].insetBy(dx: 0.0, dy: 1.0).intersects(rects[i+1]) — but
positive dy shrinks the rect, so after the trim the guarded
rectangle no longer intersects its neighbor (CGRect.intersects
requires positive-area overlap). Flip dy to -1.0 so the temp
rect grows and touching neighbors satisfy the guard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 11:44:05 +02:00
isaac
6e318f314e Add implementation plan: modern path link-highlighting fixes (#3, #7)
Plan covers two single-line edits in LinkHighlightingNode.swift's
modern branch (X-snap dy direction; floor → ceil for stair-step
fillet radii), each landed as its own commit, with a final
full-project build for validation since this repo has no tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 11:37:29 +02:00
isaac
42498cd06c Add design spec: modern path link-highlighting fixes (#3, #7)
Document the analysis and intended fixes for two bugs in
LinkHighlightingNode's modern path branch: the X-edge snap is
unreachable after the midY snap (positive dy in insetBy shrinks
rect[i] so it can't intersect the touching neighbor), and the
floor() in nextRadius/prevRadius can produce zero-radius arcs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 11:32:04 +02:00
Mikhail Filimonov
5b56675b06 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
# Conflicts:
#	submodules/MetalEngine/Sources/MetalEngine.swift
2026-05-02 10:10:18 +01:00
Mikhail Filimonov
5b8e5e0f95 metal transaction 2026-05-02 10:07:13 +01:00
isaac
a1b37776a8 Merge commit '533a179131' 2026-05-02 10:58:57 +02:00
isaac
d5823cd5c7 Merge commit 'ffd82647ee' 2026-05-02 10:58:51 +02:00
isaac
da5a92c1be InstantPage tables: stroke all borders in one path
drawInTile previously stroked each cell's full perimeter, double-drawing
every interior gridline; visible now that the rich-data chat bubble uses
tableBorderColor at 0.25 alpha. Stroking each segment in its own
strokePath call would also have left ~1pt² overdraw at every interior
4-cell junction (where a horizontal divider crosses a vertical one) and
at every T-junction with the outer rounded rect — each strokePath
rasterizes independently and composites against the previous result.

Build a single CGMutablePath containing each cell's interior top/left
segment (skipping cells on the table's top/left boundary) plus the outer
rounded perimeter rect, and call strokePath once. CGContextStrokePath
fills the union of all stroke geometries as a single fill op, so each
pixel is painted exactly once regardless of how many segments overlap.

Empty cells (text == nil) are no longer skipped wholesale: their fill
and text remain gated on text != nil (preserves today's no-fill-for-
empty behavior), but their interior divider segments still get appended
so divider continuity is preserved around them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 10:58:18 +02:00
isaac
ae37006ee4 Cleanup 2026-05-02 00:52:37 +02:00
isaac
6561adff94 Update tgcalls 2026-05-02 00:40:06 +02:00
isaac
972cdf0658 Rich bubble: text selection in context-preview mode
Adds drag-handle text selection driven by TextSelectionNode. Exposes
attributedString and selection helpers on InstantPage text items, and
introduces a multi-text adapter aggregating items as a TextNodeProtocol.
Gates selection actions on reply-options and fixes highlight z-order.
2026-05-02 00:36:35 +02:00
isaac
fdb2f369ec Rich bubble: scrollToAnchor + getAnchorRect
Adds a base getAnchorRect on ChatMessageBubbleContentNode, the rich-bubble
override (including titleHeight in details recursion), bubble-item
forwarding to content nodes, ChatControllerInteraction.scrollToMessageIdWithAnchor,
and a scrollToAnchor that lands the anchor at the top of the content area /
its line. Threads anchor/scroll params through ChatController and related
call sites.
2026-05-02 00:36:34 +02:00
isaac
f29af03cd7 InstantPage: underline rendering
Render underline runs in layoutTextItemWithString and position them below
the baseline rather than above the text.
2026-05-02 00:36:34 +02:00
isaac
528807a24b Spec: InstantPage table borders, stop drawing shared edges twice
Documents a two-pass refactor for InstantPageTableItem.drawInTile that
draws each interior divider exactly once (top+left of each cell that
isn't on the table boundary) plus a single rounded-rect outer-perimeter
stroke. Needed now that tableBorderColor is being made semi-transparent
(0.25 alpha) by the rich-data chat bubble; current per-cell whole-bounds
strokes overdraw shared edges.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 00:36:33 +02:00
isaac
d02019f985 Rich bubble: instant-page link handling
Adds ChatControllerInteraction dependency, link-progress state, URL tap
detection, press-highlight separation from in-flight URL shimmer, media-tap
routing through openMessage with explicit IV media subject, and gallery↔bubble
transition with hidden-media coordination. Stops re-appending to
currentLayoutItemsWithNodes across re-layouts. Drops a leftover MetalEngine
debug print as well.
2026-05-02 00:36:33 +02:00
isaac
999aac6eb3 ListView: cap pin-to-edge item visible portion at half area
When a pinToEdgeWithInset item is taller than half of the visible
area (visibleSize.height - insets.top - insets.bottom), cap its
visible portion at halfArea. The remaining height extends past
visibleSize - insets.bottom into the bottom-inset region (occluded
by overlay UI like the chat input panel).

A new private helper `pinToEdgeBottomExtension(forPinnedHeight:)`
returns max(0, pinnedHeight - halfArea). Three sites consume it:
- calculatePinToEdgeTopInset caps the pinned item's contribution
  to totalAboveAndPinned via `pinnedHeight - extension`.
- replayOperations isPinToEdgeTarget anchors the pinned item's
  apparent maxY at visibleSize - insets.bottom + extension.
- isStrictlyScrolledToPinToEdgeItem matches the new anchor.

Both isPinToEdgeTarget and isStrictlyScrolledToPinToEdgeItem fire
when either calculatePinToEdgeTopInset() > 0 OR extension > 0, so
the cap also applies when items above the pinned item overflow
the visible area (in which case calculatePinToEdgeTopInset returns
0 but extension is still positive).

When the pinned item fits within halfArea, extension == 0 and
behavior is identical to before this change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 00:36:33 +02:00
isaac
f25d0776c7 Visual improvements 2026-05-02 00:36:33 +02:00
isaac
ce5e3f4911 ReferenceImpl: reactive audio-SSRC discovery via per-receiver frame transformer
Includes spec and plan.
2026-05-02 00:36:33 +02:00
isaac
c256a9eb17 Add plan: ListView pin-to-edge half-area cap
Implementation plan for the spec from
docs/superpowers/specs/2026-05-01-listview-pin-to-edge-half-cap-design.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 00:36:32 +02:00
isaac
4c3437b575 Add spec: instant-page link handling in rich-data bubble
Wire URL tap detection, link-highlight feedback, and item-callback
routing in ChatMessageRichDataBubbleContentNode, with stubbed
intra-page anchor handling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 00:36:32 +02:00
isaac
4406fc6239 Spec: ListView pin-to-edge half-area cap
Cover clipping behavior and bottom-inset overflow.
2026-05-02 00:36:32 +02:00
Ilya Laktyushin
ffd82647ee Various fixes 2026-05-01 15:29:18 +02:00
Ilya Laktyushin
533a179131 Auth payment improvements 2026-05-01 15:28:26 +02:00
Ilya Laktyushin
2481687329 Add auth product 2026-05-01 15:08:48 +02:00
isaac
2edd2ffea7 Update instructions and fix build 2026-05-01 00:49:47 +02:00
Ilya Laktyushin
43b0124790 Fix poll countries limit 2026-05-01 00:09:52 +02:00
isaac
ebe43c72c6 Merge commit '8dc06f48ce'
# Conflicts:
#	submodules/TgVoipWebrtc/tgcalls
2026-04-30 22:24:28 +02:00
isaac
c63d2b115c Update submodules 2026-04-30 22:22:56 +02:00
Isaac
8dc06f48ce Merge commit '5b013073bf'
# Conflicts:
#	CLAUDE.md
#	MODULE.bazel.lock
#	submodules/TgVoipWebrtc/tgcalls
#	third-party/td/build-td-bazel.sh
#	third-party/webrtc/webrtc
2026-04-30 22:20:45 +02:00
Isaac
203727d4fb Extract tgcalls helpers into tgcalls 2026-04-30 22:13:55 +02:00
Isaac
5962a563e4 feat: tgcalls CLI test tool with group SFU, video, and adaptation
Squashed buildout of the tgcalls testbench:

- CLI test tool with --mode p2p/reflector/group/group-churn,
  cross-version interop (--version, --version2), and quiet/summary output
- Linux toolchain + Docker multi-stage build, AWS Fargate mass test harness,
  local parallel mass test harness with signaling loss simulation
- SCTP writable gate, retransmission timer tuning, role-based handshake
- InstanceV2CompatImpl (PeerConnection backend with V2Impl signaling) and
  SignalingTranslator for v14.0.0 interop
- In-process Go/Pion SFU (ICE+DTLS+SRTP+SCTP per participant) with audio
  RTP forwarding, ActiveAudio/VideoSsrcs data channel broadcast, RTCP
  feedback path, and CGo c-archive integration
- GroupInstanceReferenceImpl (PeerConnection group-call) and mixed-impl
  group mode (--reference-participants), with SDP munging for simulcast
- H264 simulcast group video (FakeVideoTrackSource pattern generator,
  FakeVideoSink frame counting, --video flag, two-pass channel setup,
  reactive video setup from ActiveVideoSsrcs)
- Group churn stress mode (--mode group-churn, --churn-cycles)
- SFU stream-quality adaptation: BandwidthEstimator, LayerSelector
  state machine, RtxRingBuffer, simulcast SSRC rewrite
- Transport-cc feedback generation, NetworkSimulator (delay/jitter/loss/
  token-bucket bandwidth), --network-scenario step-down-up
- CLAUDE.md updates throughout

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 18:28:43 +02:00
isaac
6758c94e33 Reapply "Update tgcalls"
This reverts commit 4e81b79254.
2026-04-30 17:31:21 +02:00
Ilya Laktyushin
9b8abdb5ee Fix 2026-04-30 16:51:22 +02:00
Ilya Laktyushin
5b013073bf Fix 2026-04-30 16:50:01 +02:00
Ilya Laktyushin
0664197b53 Poll improvements 2026-04-30 15:43:05 +02:00
Ilya Laktyushin
4ca7d4231b Poll improvements 2026-04-30 15:42:18 +02:00
Ilya Laktyushin
e8baaa5a22 Poll improvements 2026-04-30 15:36:13 +02:00
Ilya Laktyushin
9c3cab27e1 Fix time-limited poll closing 2026-04-30 13:14:56 +02:00
Ilya Laktyushin
fce36108da Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-30 13:14:18 +02:00
Ilya Laktyushin
5a2d6658e7 Fix time-limited poll closing 2026-04-30 13:12:46 +02:00
isaac
4e81b79254 Revert "Update tgcalls"
This reverts commit 5588a3996b.
2026-04-30 14:53:16 +04:00
isaac
5588a3996b Update tgcalls 2026-04-30 14:49:43 +04:00
isaac
207c971358 Merge commit '330fed199d' 2026-04-30 14:43:45 +04:00
isaac
266b1c5941 Fix ListViewProtocol 2026-04-30 14:43:41 +04:00
Ilya Laktyushin
29ecff3728 Various fixes 2026-04-30 12:43:12 +02:00
Ilya Laktyushin
330fed199d Improve quick share toast 2026-04-30 12:39:54 +02:00
Ilya Laktyushin
15f6811a5f Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-30 12:15:44 +02:00
Ilya Laktyushin
b222387923 Make origin check optional 2026-04-30 12:14:39 +02:00
isaac
7ef7f16727 Improve animations 2026-04-30 12:56:55 +04:00
isaac
d6899098a6 Merge branch 'draft-improvements' 2026-04-30 12:18:38 +04:00
isaac
06d744495c Improve draft sorting 2026-04-30 12:15:57 +04:00
isaac
e7662a3de5 Add typing-draft send delay
Delay outgoing messages while the peer in the same (peerId, threadId)
chat is live-typing an incoming message, gated via a new per-account
Postbox `.allTypingDrafts` view feeding a synchronous Set membership
check inside PendingMessageManager.

Postbox:
- Add `AllTypingDraftsView` tracking `Set<PeerAndThreadId>` of active
  typing drafts; expose via `PostboxViewKey.allTypingDrafts`.
- Disambiguate `PostboxViewKey` hash arms for `.typingDrafts` (constant
  prefix 23) and `.contacts` (16 → 24) to avoid runtime collisions
  with peerId-only arms and `.combinedReadState`. Hash values are
  runtime-only, so this is safe.

PendingMessageManager:
- Add `.waitingForSendGate(groupId:content:)` parking state for single
  messages and albums whose upload finished but are gated on a
  typing-draft-clearing event; update `groupId` accessor and
  `dataForPendingMessageGroup` so partially-parked albums drain on
  gate open.
- Add `.waitingForForwardSendGate` parking state for forwards (no
  associated values) so drain section (1) routes single non-grouped
  messages via `commitSendingSingleMessage` and section (3) routes
  forwards via `sendGroupMessagesContent`, avoiding the double-dispatch
  that occurred when forwards reused `.waitingForSendGate`.
- Subscribe to `.allTypingDrafts`; wire the gate at single-message,
  album, and forward send paths and at drain.
- Cleanup parked forwards on pending-message removal; snapshot
  Dictionary keys before iterating to avoid mutation during iteration.

Specs and plan documents are included under `docs/superpowers/`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 12:15:55 +04:00
Ilya Laktyushin
00f87c7b6e Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-29 23:29:49 +02:00
Ilya Laktyushin
c74220300f Various fixes 2026-04-29 23:29:42 +02:00
isaac
f34fdef432 Bump version 2026-04-29 23:55:11 +04:00
isaac
f92aabea7e Merge commit 'fd75bdb356' 2026-04-29 23:35:40 +04:00
isaac
1c27b2c426 Animation and cleanup 2026-04-29 23:35:19 +04:00
isaac
dda6054ef1 Spec: ListView.isStrictlyScrolledToPinToEdgeItem
Design doc for filling in the empty stub at ListView.swift:2674.
Defines the "strictly scrolled" condition as the equation that the
pin-to-edge scroll math at line 3115 lands on:
apparentFrame.maxY == (visibleSize.height - insets.bottom) + scrollPositioningInsets.bottom
with a 0.5pt tolerance.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 23:18:17 +04:00
Ilya Laktyushin
fd75bdb356 Fix 2026-04-29 21:15:55 +02:00
Ilya Laktyushin
5c2cebc7bf Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-29 20:27:28 +02:00
Ilya Laktyushin
14bbdca050 Various improvements 2026-04-29 20:24:29 +02:00
isaac
301be02a89 Update localization 2026-04-29 21:23:36 +04:00
isaac
53ed837123 Filter draft events 2026-04-29 21:22:51 +04:00
Ilya Laktyushin
06a0031bdd Various improvements 2026-04-29 18:22:42 +02:00
isaac
fefea439ba Merge commit '37d1e2d93e' 2026-04-29 18:45:34 +04:00
isaac
6eb2014650 Fix web 2026-04-29 18:45:26 +04:00
Ilya Laktyushin
37d1e2d93e Various fixes 2026-04-29 15:49:21 +02:00
isaac
3188c793bc Merge commit 'd25010c1cb' 2026-04-29 16:55:40 +04:00
isaac
96089108ca Fixes 2026-04-29 16:55:37 +04:00
Ilya Laktyushin
d25010c1cb Various fixes 2026-04-29 12:46:08 +02:00
Ilya Laktyushin
5d7edcf36f Various fixes 2026-04-29 04:35:17 +02:00
Ilya Laktyushin
837acfa784 Various fixes 2026-04-29 04:26:58 +02:00
Ilya Laktyushin
7ab4685940 Various fixes 2026-04-29 03:52:19 +02:00
Ilya Laktyushin
8a7daf3662 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-29 00:17:29 +02:00
Ilya Laktyushin
ea090a6858 Various improvements 2026-04-28 23:53:26 +02:00
isaac
96de278d49 Merge commit '92c350b559' 2026-04-29 01:33:08 +04:00
isaac
fb4f11e54f Roll back reply changes 2026-04-29 01:33:00 +04:00
Ilya Laktyushin
92c350b559 Fix external text sharing 2026-04-28 21:18:02 +02:00
Ilya Laktyushin
d212968040 Update API 2026-04-28 20:35:06 +02:00
Ilya Laktyushin
dbcef2ac87 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-28 19:16:15 +02:00
Ilya Laktyushin
bde3418ce5 Various fixes 2026-04-28 19:16:08 +02:00
isaac
a386e79f59 Fix emoji status selection search 2026-04-28 19:19:33 +04:00
isaac
d83734eb46 Various improvements 2026-04-28 19:00:04 +04:00
isaac
1ae854e2e9 Merge commit '73d25e7be3' 2026-04-28 17:00:21 +04:00
isaac
bc5c462eea Fix rtl reveal 2026-04-28 17:00:16 +04:00
isaac
027ac77ad7 Various improvements 2026-04-28 16:58:04 +04:00
isaac
51a7348db6 Separate failed message events between main and scheduled 2026-04-28 16:57:44 +04:00
isaac
a79447e430 Remove debugging 2026-04-28 16:57:08 +04:00
isaac
511a58e51a Sticker pack improvements 2026-04-28 16:56:02 +04:00
Ilya Laktyushin
73d25e7be3 Various improvements 2026-04-28 14:31:17 +02:00
Ilya Laktyushin
1793490519 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-28 00:13:29 +02:00
Ilya Laktyushin
1dba0dbb65 Fix deleted messages grouping in recent actions 2026-04-28 00:13:22 +02:00
isaac
bf68a7db3d Fix forum replies 2026-04-28 01:35:23 +04:00
isaac
49709e3231 Merge commit '12bb7a851c' 2026-04-28 00:44:58 +04:00
isaac
55b2b47797 Various improvements 2026-04-28 00:44:54 +04:00
Ilya Laktyushin
12bb7a851c Clean up 2026-04-27 20:09:27 +02:00
Ilya Laktyushin
d600b7b32e Clean up 2026-04-27 19:32:42 +02:00
Ilya Laktyushin
d574182374 Markdown improvements 2026-04-27 18:45:30 +02:00
Ilya Laktyushin
7fdc1ea1d2 Game link support 2026-04-27 16:57:23 +02:00
Ilya Laktyushin
e97422e333 Various fixes 2026-04-27 04:40:29 +02:00
Ilya Laktyushin
2c002ba3a7 Various fixes 2026-04-27 03:07:38 +02:00
Ilya Laktyushin
12d5336af9 Fix 2026-04-27 01:39:39 +02:00
Ilya Laktyushin
c4e1049396 Various fixes 2026-04-27 01:36:16 +02:00
isaac
1b85d8ccb0 Postbox -> TelegramEngine wave 106 (pivot: engine data() incremental facade + 1-site drain)
Original wave 106 pure import-drop sweep abandoned: 576 candidate files
all genuinely reference Postbox-tier tokens; wave 93's pattern exhausted
at file granularity (no single-file orphans remain).

Pivot: extend engine.resources.data(resource:) facade with
`incremental: Bool = false` parameter (wires to ResourceDataRequestOption).
Drain the 1 live consumer site (ChatInterfaceStateContextMenus:1327)
plus consumer-side `data.complete` -> `data.isComplete` rename.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 22:49:53 +04:00
isaac
40e1a5c7e5 docs: plan for postbox wave 106 pivot — engine data(incremental:) facade + drain
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 22:43:53 +04:00
isaac
5a3a4f5536 docs: plan for postbox wave 106 — speculative import Postbox drop sweep round 2
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 22:21:14 +04:00
isaac
59e3e714fa docs: spec for postbox wave 106 — speculative import Postbox drop sweep round 2
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 22:12:54 +04:00
isaac
7ccb382f53 Postbox -> TelegramEngine waves 103-105 (squashed)
Wave 103 (original): ChatRecentActionsControllerNode.peer Peer ->
EnginePeer migration ABANDONED after pre-flight discovered a 75-site
ADD-bridge cascade through chatRecentActionsHistoryPreparedTransition
into Message.peers SimpleDictionary<PeerId, Peer> store sites.
Lessons captured in docs/superpowers/postbox-refactor-log.md "Wave 103
ABANDONED" section + ~/.claude/projects/-Users-isaac-build-telegram
-telegram-ios/memory/feedback_wave71_shadow_risk.md (4-layer pre-flight
checklist for stored-Peer-field migrations).

Wave 103 (retry, 92230b0691): drained 5 accountManager.mediaBox
.storeResourceData Shape-A sites against the wave-94 facade. 2 files /
3 Edit calls (1 single + 2 replace_all) / 1-iter / 29.5s build. Closes
the storeResourceData accountManager-side drain entirely.

Wave 104 (08fc3f721e): drained 3 of 8 accountManager.mediaBox.resourceData
Shape-A sites against the wave-32/wave-94 AccountManagerResources.data
(resource:) facade + 3 consumer-side .complete -> .isComplete renames
(EngineMediaResource.ResourceData field rename). 1 file / 6 Edit calls
/ 1-iter / 11.7s build. 5 of 8 candidates deferred behind Postbox-typed
-function-parameter barriers (fetchCachedScaled*Representation cascade,
combineLatest typed-tuple coupling). Established the "Postbox-typed
-function-parameter barrier registry" pattern.

Wave 105 (0c76724409): DeviceContactInfoSubject enum 3 case Peer?
payloads + 2 callback signatures + 1 computed property migrate to
EnginePeer?. 5 files / 17 edits / 1-iter / 203s build (foundational
AccountContext touch). Net wrap delta -8 (10 drops, 2 ADD bridges, 1
downcast->case-let). First wave-71-shadow-style migration after the
wave-103 abandonment forced a discipline reset; first-pass-clean via
thorough pre-flight inventory (~15 min).

Net session progress: -16 wraps across 4 wave attempts plus durable
scaffolding (feedback memory, barrier registry, 4-layer pre-flight
checklist).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 16:57:55 +04:00
isaac
0a0ca093f4 docs: spec for postbox wave 103 — ChatRecentActionsControllerNode peer migration
Closes the wave-71-shadow ratchet: caller already holds EnginePeer and
demotes once at the boundary. Migration drops the demote, drops `import
Postbox` from the node, and rewrites 3 `as? TelegramChannel` downcasts
to `case let .channel(channel)`. 7 edits across 2 files, 1-iter target.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 14:47:49 +04:00
Ilya Laktyushin
adc0d5ba6e Various improvements 2026-04-26 01:22:29 +02:00
Ilya Laktyushin
53c2da81fe Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-26 01:07:19 +02:00
Ilya Laktyushin
3c6ea30767 Various fixes 2026-04-26 01:07:12 +02:00
isaac
a04db4a2a6 Merge commit '6b78a35695' 2026-04-26 02:52:26 +04:00
isaac
e9d958809a Fix 2026-04-26 02:46:44 +04:00
isaac
2ac8a490b0 Postbox -> TelegramEngine waves 94-102 (squashed)
Adds AccountManagerResources facade in TelegramCore mirroring
TelegramEngine.Resources, drains the entire accountManager-side
mediaBox refactor across consumer modules, and validates the
Shape-C/D handle-migration pattern (account: Account ->
engine: TelegramEngine) on three classes.

Wave 94 (AccountManagerResources facade + 8 sites): new
AccountManagerResources class in TelegramCore with
storeResourceData, completedResourcePath (resource + id overloads),
status (with approximateSynchronousValue), moveResourceData,
fetch. Migrate EditThemeController (5 storeResourceData + 2
completedResourcePath) and WebBrowserSettingsController (1
storeResourceData).

Wave 95 (10 sites): WallpaperUtils.swift sweep, 5 distinct
storeResourceData patterns, replace_all on the two repeated ones.

Wave 96 (7 sites): theme controller triple — TPC (1 store + 2
moveResourceData), TPCN (1 status + 1 fetch + closure type
MediaResourceStatus -> EngineMediaResource.FetchStatus + rename
account local to engine), TAC (1 completedResourcePath + 1 store).

Wave 97 (9 sites): WallpaperGalleryController.swift, 4
completedResourcePath + 5 storeResourceData via replace_all.

Wave 98 (2 files): WallpaperGallery status-type cascade
Promise<MediaResourceStatus> -> Promise<EngineMediaResource.FetchStatus>
across WallpaperGalleryItem.swift + WallpaperGalleryController.swift.
Drops cosmetic `_asStatus()` unwrap.

Wave 99 (2 facade extensions + 7 sites): adds
AccountManagerResources.data() and approximateSynchronousValue
to engine.resources.status(). Migrates OpenResolvedUrl (data +
storeResourceData with .complete -> .isComplete cascade),
SettingsThemeWallpaperNode (paired engine + accountManager
status), WallpaperUploadManager, OpenChatMessage,
LiveChatReactionStreamView.

Wave 100 (Shape-C/D, free function): legacyWebSearchItem
account: Account -> engine: TelegramEngine. 4 files.

Wave 101 (Shape-C/D, small class): VerticalListContextResults
ChatInputPanelItem stored field migration. 2 files. Drops
`|> map(EngineMediaResource.FetchStatus.init)` redundancy.

Wave 102 (Shape-C/D, medium class with weak-context retention):
SharedMediaPlayer account: Account -> engine: TelegramEngine.
Engine field is intentionally a strong handle since the class
stores context as `weak var`. 2 files.

After this squash the accountManager-side mediaBox refactor is
essentially complete; only Postbox-protocol-blocked
cachedResourceRepresentation triple remains as the foundational
deferred item.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 02:46:44 +04:00
Ilya Laktyushin
6b78a35695 Various fixes 2026-04-25 19:53:39 +02:00
isaac
7ce00a00fa Merge commit '6df5f10973' 2026-04-25 20:50:35 +04:00
isaac
d1aa0db537 Postbox -> TelegramEngine waves 46-93 (squashed)
Squash of 63 commits spanning waves 46-93 (plus interspersed docs commits)
of the gradual Postbox->TelegramEngine consumer-side migration.

Scope: 139 files changed, 2123 insertions(+), 452 deletions(-).

## Themes by wave-block

**Waves 46-58 — Peer field migrations + facade additions**
Foundational EnginePeer convenience init additions (PeerReference, RenderedPeer,
SelectivePrivacyPeer). Multiple `peer: Peer` field migrations across PeerInfo,
ChatList, and SettingsUI components.

**Waves 59-73 — peer field cascade + EnginePeer wrap drops**
Series of single- to two-file peer-field migrations; consumer-side wrap
removal (`EnginePeer(peer)` -> direct EnginePeer use); `as? TelegramUser`
cast conversion to `case let .user(...)` enum match. Wave 64: RenderedPeer
convenience init. Wave 68: SelectivePrivacyPeer convenience init.

**Waves 74-83 — controller-Node bridge cleanup + small migrations**
Wave-71 shadow-pattern cleanup at controller->Node bridges. Migrations of
ChatRecentActionsController.peer (74), PeerInfoMember (75), MentionChatInputPanelItem
(76), PassportUI SecureIdAuthController (77), AccountWithInfo + ShareController
(78), peerInputActivitiesPromise (79), InactiveChannel (80), BlockedPeers (81),
openHashtag resolveSignal (82), NotificationExceptionsList (83).

**Waves 84-90 — TelegramEngine.Resources facade migrations**
Per-method Shape-A/B sweeps converting `<ctx>.account.postbox.mediaBox.X(...)`
to `<ctx>.engine.resources.X(...)`. Wave 90 was a single-commit big sweep:
40 fetchedMediaResource sites in 25 files migrated to engine.resources.fetch
facade in one atomic pass with first-pass-clean build.

Methods covered: storeResourceData, completedResourcePath, cancelInteractiveResourceFetch,
resourceRangesStatus, resourceStatus, fetch (fetchedMediaResource).

**Waves 91-92 — additional type migrations**
Wave 91: ItemListWebsiteItem.peer + RecentSessionsController enum-case payload
+ openWebSession callback Peer? -> EnginePeer?.
Wave 92: ChatListController StateHolder.EntryContext status type
MediaResourceStatus -> EngineMediaResource.FetchStatus.

**Wave 93 — speculative `import Postbox` drop sweep**
Drop import from 7 wave-touched files where it became unused; restore in 5
files where bare PeerId/Message/MediaId/StoryId references escaped the
pre-flight regex. Includes one MediaId(...) -> EngineMedia.Id(...) swap in
InAppPurchaseManager to unlock its import drop.

## Build state

Final state at squash: clean Telegram/Telegram build at debug_sim_arm64.

## Persistent-state notes

- Pre-existing WIP unchanged across the squashed range:
  - build-system/bazel-rules/sourcekit-bazel-bsp submodule marker
  - Untracked: build-system/tulsi/, submodules/TgVoip/, third-party/libx264/

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 20:48:15 +04:00
Ilya Laktyushin
6df5f10973 Fix build 2026-04-25 18:35:36 +02:00
Ilya Laktyushin
5f7bcb7746 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-25 17:41:48 +02:00
Ilya Laktyushin
9c15b8c27d Various improvements 2026-04-25 17:32:26 +02:00
isaac
6b7a23867c Postbox -> TelegramEngine wave 45
PeerInfoHeader* update(peer:) bundle: Peer? -> EnginePeer?.
Four update methods across PeerInfoHeaderNode, PeerInfoHeaderEditingContentNode,
PeerInfoEditingAvatarNode, PeerInfoEditingAvatarOverlayNode.
Drops wave-43 ADD-WRAP bridges (net ~-11 wraps). Stored
PeerInfoHeaderNode.peer: Peer? field stays raw (out of scope).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 00:02:22 +04:00
isaac
de21dedbe3 Fix offsets 2026-04-24 23:42:53 +04:00
isaac
4e192fda4d Fix reply panel animation 2026-04-24 23:24:20 +04:00
isaac
bd6523bb34 docs: log wave 44 outcome
Wave 44 (RenderedChannelParticipant.peers [PeerId: Peer] →
[EnginePeer.Id: EnginePeer]) landed as ca69fa8cbb. Closes the wave-41
RCP foundational-type ratchet. 14 files, 38 inserts / 38 deletes,
2-iteration convergence. Iteration-1 surfaced new.peers enum-destructure
binding (case let .participantSubscriptionExtended(prev, new)) at
ChatRecentActionsHistoryTransition:2272 — plan's participant.peers
pre-flight grep missed it. Widened lesson documented.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:21:05 +04:00
isaac
c0acc09cb1 Postbox -> TelegramEngine wave 44
Migrate RenderedChannelParticipant.peers from [PeerId: Peer] to
[EnginePeer.Id: EnginePeer]. Closes the wave-41 ratchet — the public
struct no longer leaks raw Peer types in any field (presences stays
Postbox-typed; separate migration).

Consumer-surface: -10 bridges. Dropped 6 EnginePeer(peer) read-wraps
at participant.peers[...] extraction sites across
ChannelAdminsController, ChannelMembersSearchContainerNode,
ChannelBlacklistController. Dropped 5 .mapValues({ $0._asPeer() })
constructor-unwrap transforms in ChannelAdminsController,
ChannelMembersSearchContainerNode, ChannelMembersSearchControllerNode.
Added 2 ._asPeer() unwraps in ChatRecentActionsHistoryTransition at
the two iteration sites (line 673 via participant.peers, line 2273
via new.peers in participantSubscriptionExtended) where the iterated
value is inserted into a raw-Peer SimpleDictionary.

TelegramCore producers: 8 files build the local peers dict inside
postbox.transaction and wrap at the insertion point. ChannelMembers,
RequestStartBot, ChannelOwnershipTransfer, JoinChannel, AddPeerMember,
PeerAdmins, ChannelBlacklist, Ranks.

2-iteration build convergence. Iteration-1 surfaced new.peers at
ChatRecentActionsHistoryTransition:2272 that the plan's participant.peers
pre-flight grep missed; wider grep now confirms the two iteration sites
are the complete surface.

No unit tests in this project; full Telegram/Telegram build verified
under configuration=debug_sim_arm64.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:21:05 +04:00
isaac
68a95f53f2 Various improvements 2026-04-24 23:21:05 +04:00
isaac
6c2f370a8f Fix fast-send morph starting position
The bubble-in-text-input morph ran concurrently with listNode's
scroll-to-item sublayerTransform animation, but its source rect was
computed via CALayer.convert which uses model transforms only and so
missed the pending additive sublayerTransform. The morph's `from`
ended up calibrated to the post-scroll state while playback started
from the pre-scroll state, offsetting the bubble at t=0.

Add convertAnimatingSourceRectFromWindow: walks the layer chain
top-down and at each parent->child step subtracts the parent's pending
additive sublayerTransform translation in the parent's bounds space
before descending, so the result reflects the t=0 presentation state
even through rotations/scales later in the chain. Parent
animatingItemNode under itemNode so listNode is on its ancestor chain
and its pending sublayerTransform is picked up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:21:04 +04:00
isaac
493f3103b3 Postbox -> TelegramEngine waves 37-43 + wave 44 design/plan (squashed)
Squashes 20 commits — the implementation and outcome commits of
waves 37 through 43 plus wave 44's spec and implementation-plan
docs — into a single commit. Per-wave lessons remain recorded in
docs/superpowers/postbox-refactor-log.md. The unrelated "Add swift
svg" commit is preserved separately outside this squash.

Wave 37 — peerTokenTitle: peer Peer → EnginePeer (1 file)
Wave 38 — canSendMessagesToPeer: peer Peer → EnginePeer (12 files)
Wave 39 — AccountContext.makePeerInfoController: peer Peer → EnginePeer (52 files)
Wave 40 — makeChatQrCodeScreen + makeChatRecentActionsController bundle (8 files)
Wave 41 — RenderedChannelParticipant.peer: Peer → EnginePeer (28 files)
Wave 42 — PeerInfoScreenData.peer: Peer? → EnginePeer? (17 files)
Wave 43 — PeerInfoScreen 6 helpers: peer Peer? → EnginePeer? (12 files)
Wave 44 — RenderedChannelParticipant.peers design doc + implementation plan
         (impl and outcome land in subsequent commits, not part of squash)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:19:43 +04:00
isaac
e51fef57d8 Add swift svg 2026-04-24 23:19:15 +04:00
isaac
ce64d84013 docs: wave 37 design — peerTokenTitle peer parameter Peer → EnginePeer
Private free function in ContactMultiselectionController.swift. Five
_asPeer() bridges drop in one atomic single-file commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:29:25 +04:00
isaac
f5cb1391aa Merge commit '96b1432434' 2026-04-24 11:24:47 +04:00
isaac
97f8c53814 Various improvements 2026-04-24 11:24:14 +04:00
isaac
8408e0ae19 Postbox -> TelegramEngine waves 27-36
Consumer-sweep, facade-addition, and Peer→EnginePeer migrations:

- Wave 27: preferencesView consumer sweep
- Wave 28: resourceData consumer sweep
- Wave 29: resourceStatus consumer sweep
- Wave 30: _asStatus() bridge cleanup
- Wave 31: unused-import sweep re-run
- Wave 32: resourceStatus residue sweep
- Wave 33: loadedPeerWithId consumer sweep
- Wave 34: FoundPeer.peer Peer -> EnginePeer
- Wave 35: SendAsPeer.peer Peer -> EnginePeer
- Wave 36: ContactListPeer.peer Peer -> EnginePeer

Also includes per-wave specs, implementation plans, outcome logs, and
a CLAUDE.md wave-counter update.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:24:13 +04:00
isaac
9187fbb6db docs: reorganize CLAUDE.md — extract wave history and verbose guidance to log
Trims the Postbox-refactor section of CLAUDE.md from ~750 lines to ~160
by moving per-wave outcomes, the running tally of Postbox-free modules,
and verbose wave-selection guidance backstory into
docs/superpowers/postbox-refactor-log.md. Also adds a spec document for
the reorganization.

Kept in-place in CLAUDE.md: standing rules, engine typealias cheat sheet,
MediaResource consumer-migration patterns, TelegramEngine.Resources facade
inventory, and terse bullet-form guidance with log cross-references.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:20:55 +04:00
Ilya Laktyushin
96b1432434 Various improvements 2026-04-24 04:55:22 +02:00
Ilya Laktyushin
f41630083a Various improvements 2026-04-24 03:16:14 +02:00
Ilya Laktyushin
32b2ede5aa Fix data image sharing 2026-04-23 01:48:48 +02:00
Ilya Laktyushin
e3bf0cd30c Various fixes 2026-04-23 01:26:13 +02:00
Ilya Laktyushin
7d3a497db6 Fix build 2026-04-23 00:07:09 +02:00
Ilya Laktyushin
1fe13a7630 Fix build 2026-04-22 23:51:28 +02:00
Ilya Laktyushin
11af61f32e Fix build 2026-04-22 23:34:39 +02:00
Ilya Laktyushin
dbd40fe7d3 Various improvements 2026-04-22 23:03:51 +02:00
isaac
1dd23f6641 Bump version 2026-04-22 03:04:50 +04:00
isaac
f77eafacff Merge commit 'f185b602ea' 2026-04-22 00:32:48 +04:00
isaac
524c29cbe3 Various improvements 2026-04-22 00:32:34 +04:00
isaac
59dc46e0f5 docs: TextStyleEditScreen caret-tracking plan
Task-by-task implementation plan for the caret-tracking auto-scroll
design. Single-file change in TextStyleEditScreen.swift: tag both text
fields, walk the transition's TextFieldComponent.AnimationHint userData
on .textChanged, compute caret rect, and adjust the enclosing
ResizableSheetComponent scroll view's bounds.
2026-04-21 23:58:07 +04:00
isaac
bf74b055cf docs: TextStyleEditScreen caret-tracking spec
Design for auto-scrolling the ResizableSheetComponent scroll view on text
change so the caret in either ListMultilineTextFieldItemComponent stays
visible above the soft keyboard.
2026-04-21 23:55:09 +04:00
isaac
2dd07ef8cc TelegramApi: regenerate Api*/SecretApiLayer*.swift with safe flag unwrap
Mechanical regeneration after the SwiftTL fix. Every
'if Int(_N!) & Int(1 << K) != 0 {...}' gate and matching
'_cM = (Int(_N!) & ...) == 0) || ...' validation in parse_<ctor>
now reads 'Int(_N ?? 0)' instead of force-unwrapping. ~2168 sites
changed across the 41 flat Api*.swift files plus the 11 layered
SecretApiLayer*.swift files. No other content change.

Full Bazel build verified green with the regenerated sources.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 23:44:35 +04:00
isaac
90b2ba0bd4 SwiftTL: avoid trap when flags field fails to parse
Generated parse_<ctor>(...) for constructors with conditional fields
used to emit 'if Int(_N!) & Int(1 << K) != 0 { ... }' as the gate,
and 'let _cM = (Int(_N!) & Int(1 << K) == 0) || _M != nil' as the
per-field validation. Both force-unwrap _N (the flags field read)
before the bottom-of-function '_cN = _N != nil' validation runs,
so a buffer short enough to fail the flags read traps
deterministically instead of returning nil.

Replace the force-unwraps with (_N ?? 0). Missing flags then reads
as "all bits off": every gated branch is skipped, each flag-gated
_cM short-circuits to true via the '== 0' clause, and the flags
field's own _cN = _N != nil still fails so the overall constructor
validation falls through to return nil — matching the intended
"return nil on truncated buffer" contract.

Touches both generator emit paths (flat generateImplFile and layered
emitLayeredType). Regenerated Api*/SecretApiLayer*.swift follow in a
separate commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 23:44:26 +04:00
Mikhail Filimonov
f185b602ea ap update 2026-04-21 20:29:39 +01:00
isaac
3559ee9f1d TelegramApi: regenerate SecretApiLayer*.swift via SwiftTL
Replaces the hand-written layer 8/46/73/101/144 files with SwiftTL
output and adds the previously-unpublished layers 17/20/23/45/66/143.
Per-layer struct names (SecretApi8, SecretApi46, ...) and public
enum case signatures are unchanged for the consumers.

The regenerated cumulative snapshots now include every constructor
declared in secret_scheme.tl, including decryptedMessageActionTyping
(layer 17) which the hand-written files had elided. Switch statements
over DecryptedMessageAction in ProcessSecretChatIncomingDecryptedOperations
gain the missing case alongside .decryptedMessageActionNoop (both are
no-ops in the consumer-side state-machine).

BUILD uses glob("Sources/**/*.swift") so no BUILD update required.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 23:02:42 +04:00
isaac
e7956e0e70 Cleanup 2026-04-21 22:04:58 +04:00
isaac
da1629328f Fix resample 2026-04-21 22:04:47 +04:00
isaac
4464802051 Remove deprecated MTInputStream methods 2026-04-21 21:10:33 +04:00
isaac
2516f0005d CLAUDE.md: record full Make.py build command
Documents the actual build invocation (with codesigning + cache +
configuration arguments) at the top of the file, alongside the
existing notes that only Bazel + the codesigning env var were
mentioned. Removes the duplicate "Build environment quirk" footer
section since its content now lives at the top.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 16:05:12 +04:00
isaac
57bfe559ea SwiftTL: main.swift branches on ParsedSchema
Flat schemas keep the existing generate(...) pipeline. Layered
schemas iterate resolveLayeredTypes and write one
{apiPrefix}Layer{N}.swift per layer via generateLayered.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:56:05 +04:00
isaac
803bf23269 SwiftTL: add CodeGenerator.generateLayered for per-layer output
Emits one {apiPrefix}Layer{N}.swift file per layer: file-scope
dispatch table, public struct {apiPrefix}{N} with parse/parseVector/
serializeObject, nested public enums for each sum type using the
inline-args shape. Int256 dispatch entry emitted only when a layer's
constructors reference it. Reuses typeReferenceRepresentation /
generateFieldSerialization / generateFieldParsing unchanged, passing
the struct name as the apiPrefix so nested type refs render correctly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:54:09 +04:00
isaac
10054efd81 SwiftTL: add Resolver.resolveLayeredTypes
Walks layer sections in order, threads a running constructor-name map
with last-wins semantics, and snapshots [SumType] at each layer
boundary. Constructors appearing only in later layers do not leak into
earlier layers' snapshots.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:46:48 +04:00
isaac
dba8a67bcb SwiftTL: add ParsedSchema + layered schema parsing
DescriptionParser.parse(data:) now returns ParsedSchema (.flat or
.layered) based on the presence of ===N=== markers. Layered schemas
split constructor lines per layer; pre-marker constructors attach to
the lowest-numbered layer; ---functions--- is rejected in layered
mode; non-ascending markers throw.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:36:09 +04:00
isaac
248c69a6d0 SwiftTL: plan for layered schema generation
Six-task implementation plan covering the parser / resolver / codegen
extension path described in the 2026-04-21 design spec. Tasks land
end-to-end, with a final Bazel build verification of the regenerated
SecretApiLayer*.swift files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:25:19 +04:00
isaac
bb29084392 SwiftTL: thread apiPrefix, drop dead CLI flags and LegacyOrderParser
Preparation for layered schema generation. Threads apiPrefix: String
through CodeGenerator.generate / generateMainFile / generateImplFile
/ typeReferenceRepresentation so the output's namespace name can
come from the --api-prefix=<prefix> CLI flag rather than a hard-coded
"Api". Drops the --stub-functions and --print-constructors=N-M flags
(both unused) and the LegacyOrderParser.swift file (obsolete migration
helper that re-parsed hand-emitted Api0.swift).

No behavior change for the flat Api*.swift output when
--api-prefix=Api (the default). Enables the upcoming layered secret-
scheme pipeline to reuse the same generator helpers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:24:14 +04:00
Mikhail Filimonov
365d44f03a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-21 12:11:20 +01:00
Mikhail Filimonov
fe6836ab02 flag 2026-04-21 12:11:11 +01:00
isaac
25ddc21780 Update API 2026-04-21 15:09:07 +04:00
isaac
9ed75ca048 Fix build 2026-04-21 15:08:45 +04:00
isaac
afe119a73f SwiftTL: design for optional layered schema generation
Adds the design spec for extending SwiftTL to parse TL schemas
with ===N=== layer markers (secret_scheme.tl), emitting one
cumulative-snapshot Swift file per declared layer. Flat schemas
are unchanged. No CLI surface changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 14:47:17 +04:00
isaac
a7e9375d55 Fix sticker display 2026-04-21 14:00:16 +04:00
isaac
615becca7a Update tgcalls 2026-04-21 13:59:36 +04:00
isaac
1ef7b9732e CLAUDE.md: add TelegramEngine.Resources facade inventory + wave-shape-G recipe
Consolidates the post-wave-26 state. Adds:
- Facade inventory table covering all mediaBox facades landed through wave 26.
- Swift-stdlib-vs-third-party-module name collision lesson from wave 26.
- Wave-27+ candidates section (cached-representation triple, resourceData sweep,
  resourceStatus sweep, storageBox wrap, preferencesView, loadedPeerWithId,
  Postbox-class-move opportunities, unused-import sweep re-run).
- Wave-shape-G recipe documented: facade addition + consumer sweep in one commit,
  validated at scale across waves 19-26.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:23:48 +04:00
isaac
fa68639b25 Postbox -> TelegramEngine wave 26: resourceRangesStatus + removeCachedResources facades + sweep
Adds two TelegramEngine.Resources facades and migrates 4 Shape-A sites across 3 consumer files.
Also imports RangeSet in TelegramEngineResources.swift to disambiguate the RangeSet type from
Swift stdlib's iOS-18-only type.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 04:18:03 +04:00
isaac
939873f6f4 Postbox -> TelegramEngine wave 25: copyResourceData facades + consumer sweep
Adds two TelegramEngine.Resources.copyResourceData overloads and migrates 4 Shape-A sites
across 3 consumer files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 04:09:42 +04:00
isaac
a0ba3fa29c Postbox -> TelegramEngine wave 24: moveResourceData facades + consumer sweep
Adds two TelegramEngine.Resources.moveResourceData overloads and migrates 6 Shape-A sites
across 4 consumer files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 04:04:08 +04:00
isaac
d78fe8e8b8 Postbox -> TelegramEngine wave 23: cancelInteractiveResourceFetch facade + consumer sweep
Adds TelegramEngine.Resources.cancelInteractiveResourceFetch(id:) and migrates 5 of 7 Shape-A
sites. Two sites in ChatMessageInteractiveMediaNode.swift skipped to avoid mixing with
pre-existing uncommitted WIP in that file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 03:57:46 +04:00
isaac
4879d89a92 Postbox -> TelegramEngine wave 22: storeResourceData facade + consumer sweep
Same shape as wave 21. Adds TelegramEngine.Resources.storeResourceData(id:, data:, synchronous:)
and sweeps 46 context.account.postbox.mediaBox.storeResourceData sites across 17 files.

The range-store overload and accountManager.mediaBox sites are explicitly out of scope.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 03:51:11 +04:00
isaac
53f023ea52 Postbox -> TelegramEngine wave 21: completedResourcePath facade + consumer sweep
Combined wave-19+wave-20 shape. Adds TelegramEngine.Resources.completedResourcePath(id:, pathExtension:)
facade and sweeps 29 consumer sites across 14 files in one atomic commit.

Shape A/B migrated. Shape C (5 sites with raw account: Account) and Shape D
(3 sites with local postbox: Postbox field) intentionally skipped — need
module-scoped init-signature rework rather than per-site sweep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 03:19:30 +04:00
isaac
7919556375 Postbox -> TelegramEngine wave 20: shortLivedResourceCachePathPrefix consumer sweep
22 call sites across 16 consumer modules migrated to the wave-19 facade:
  context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(resource.id)
  ->
  context.engine.resources.shortLivedResourceCachePathPrefix(id: EngineMediaResource.Id(resource.id))

ItemListStickerPackItem additionally drops the wave-18 `let rawResource` intermediate.

Skipped: MediaEditorComposerEntity.swift:245 (uses local `postbox:` init-param,
not `context.account.postbox`; needs its own wave). No modules become Postbox-free
this wave — each still has other Postbox usage.
2026-04-21 02:27:39 +04:00
isaac
7c53c9babd Postbox -> TelegramEngine wave 19: add shortLivedResourceCachePathPrefix facade
Additive-only. Adds TelegramEngine.Resources.shortLivedResourceCachePathPrefix(id: EngineMediaResource.Id) -> String as a thin forwarder over MediaBox.shortLivedResourceCachePathPrefix.

Unblocks consumer migration across 25+ call sites in ~15 modules; consumers migrate in follow-up waves.
2026-04-20 22:30:33 +02:00
isaac
a86376c25e Postbox -> TelegramEngine wave 18: ItemListStickerPackItem mixed-shape migration
- Add 3 narrow typealiases to TelegramCore (rule 1 — narrow utility aliases):
  EngineItemCollectionId, EngineFetchResourceSourceType, EngineFetchResourceError.
- StickerPackThumbnailItem.animated payload: MediaResource -> EngineMediaResource
  (wave-4 shape). Equatable uses EngineMediaResource.== (identical semantics).
- Replace raw fetchedMediaResource() with context.engine.resources.fetch()
  (wave-3 facade, pre-existing).
- Module becomes fully Postbox-free (source + BUILD).
2026-04-20 22:22:42 +02:00
isaac
9b06909edd Postbox -> TelegramEngine wave 17: ItemListAvatarAndNameInfoItem stateManager: collapse
Applies the wave-11/12/15 collapse pattern to ItemListAvatarAndNameInfoItem.
ItemContext.other payload changes from (accountPeerId:, postbox: Postbox,
network: Network) to (accountPeerId:, stateManager: AccountStateManager).
Internal AvatarNode.setPeer forward rewires through stateManager.postbox /
.network. Module drops import Postbox (source) and //submodules/Postbox:Postbox
(BUILD). Sole external caller — DeviceContactInfoController.swift:413 at the
Share-Extension boundary — migrated atomically.

Handle choice is stateManager: (not engine:) because the sole caller fires
specifically when the context is not a ShareControllerAppAccountContext;
ShareControllerAccountContext protocol exposes stateManager: AccountStateManager
but not engine: TelegramEngine, and no full TelegramEngine is constructible in
the Share Extension (no Account). Per feedback_postbox_refactor_handle.md and
the wave-15 precedent.

Pre-flight public-Postbox-type inventory grep (per CLAUDE.md's Wave-selection
guidance) returned only Postbox itself — no hidden leaks like wave 16's
EngineMessageHistoryThread / PeerStoryStats surprises.

Module fully Postbox-free after this wave. Running tally updated in CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 21:46:02 +02:00
isaac
8215c057cf CLAUDE.md: add public-Postbox-type inventory lesson to wave-selection guidance
Surfaced by wave 16 -- grepping only for Postbox/Network tokens undercounts
the hidden public-surface leaks (e.g., EngineMessageHistoryThread, PeerStoryStats).
Document the allowlist-grep recipe and the three paths for handling hits.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 21:39:15 +02:00
isaac
8e7014a7ed CLAUDE.md: append wave 16a/16b outcome
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 21:31:34 +02:00
isaac
a5432e44a8 Postbox -> TelegramEngine wave 16b: ItemListPeerItem.Context engine: collapse
ItemListPeerItem.Context.Custom's init took (postbox: Postbox, network: Network)
purely to forward them to downstream AvatarNode.setPeer and EmojiStatusComponent.
Collapse to engine: TelegramEngine (wave-11 pattern, engine handle preferred per
the standing guidance since the sole external caller is main-app, not
Share-Extension).

Surface changes:
- Context.Custom: two stored fields (postbox, network) -> one (engine); init
  param pair -> single engine:.
- Context: computed postbox/network -> computed engine.
- Six internal forwards route via item.context.engine.account.postbox/.network.

External caller (sole .custom(Custom(...)) construction site codebase-wide):
- PeerInfoSettingsItems.swift:121 -> pass engine: peerAccountContext.engine
  (the accountsAndPeers tuple already carries AccountContext, which exposes
  .engine: TelegramEngine).

All 37 other ItemListPeerItem(...) sites use the .account(context: AccountContext)
convenience overload unchanged.

Module does NOT become Postbox-free: PeerStoryStats? (public surface on
storyStats) and, via the now-unavoidable Postbox import, a handful of other
transitive Postbox types remain reachable. PeerStoryStats is deeply baked into
Postbox view types (PeerView, PeerStoryStatsView, ChatListEntry, MessageHistoryView,
Postbox.getPeerStoryStats) and moving it would require a cross-module wrapper
rewrite out of scope here. EngineMessageHistoryThread.Info (the other
previously-blocking public-surface type) was moved to TelegramCore in the
preceding wave 16a commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 21:30:19 +02:00
isaac
3bb22d503c Postbox -> TelegramEngine wave 16a: move EngineMessageHistoryThread to TelegramCore
Promote Postbox's internal MutableMessageHistoryThreadIndexView.Item to a
public top-level type MessageHistoryThreadIndexItem; drop Postbox's empty
EngineMessageHistoryThread namespace class and its nested Item.

MessageHistoryThreadIndexView.items is now [MessageHistoryThreadIndexItem]
directly (no wrap/unwrap step in the init). The two consumer iteration
sites (ChatListNodeLocation.swift, ShareControllerNode.swift) don't need
changes -- they iterate without type annotation and only read fields that
exist on both the old nested Item and the new top-level type.

Collapse TelegramCore's public extension EngineMessageHistoryThread into
a proper class definition:
public final class EngineMessageHistoryThread { class Info { ... } }.

After this, EngineMessageHistoryThread is a pure TelegramCore type --
consumers that only use EngineMessageHistoryThread.Info no longer need
import Postbox for the outer name to resolve.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 21:26:32 +02:00
isaac
a053909b87 Fix crash 2026-04-20 21:06:20 +02:00
isaac
46566e7155 Postbox -> TelegramEngine wave 15: SelectablePeerNode stateManager collapse
Applies the wave-11/12 AccountStateManager collapse pattern to
SelectablePeerNode. Module is now fully Postbox-free (source + BUILD).

- SelectablePeerNode.setup(... postbox: Postbox, network: Network, ...)
  -> setup(... stateManager: AccountStateManager, ...). Same for
  setupStoryRepost. AvatarNode.setPeer and EmojiStatusComponent are
  forwarded as stateManager.postbox / .network without naming Postbox.
- Three Namespaces.Peer.SecretChat == checks rewritten to use the
  existing PeerId.isSecretChat extension (as in wave 13).
- ShareControllerPeerGridItem.setup / setupStoryRepost and
  HorizontalPeerItem.setup call sites collapse to stateManager:.
  JoinLinkPreviewPeerContentNode uses the convenience
  setup(context: AccountContext) and is unchanged.
- Drop import Postbox in SelectablePeerNode.swift and the
  //submodules/Postbox:Postbox dep in SelectablePeerNode/BUILD.

The stateManager fallback (over the normally-preferred engine:
TelegramEngine) is used because SelectablePeerNode crosses the Share
Extension boundary: ShareControllerAccountContextExtension has no
Account, so TelegramEngine(account:) is physically unreachable there.
This matches the "rare but genuine fallback" clause of
feedback_postbox_refactor_handle.md.

Build verified green (debug_sim_arm64, 193 actions).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 20:37:41 +02:00
isaac
b20cd3502b Postbox -> TelegramEngine waves 11-14: stateManager collapse + BUILD-dep sweep
Wave 11: ActionSheetPeerItem de-Postboxed. Revisits wave-1 abandonment.
`postbox: Postbox, network: Network` init params collapse to
`stateManager: AccountStateManager`; avatar setPeer call routes via
`item.stateManager.postbox` / `.network`. Module never names Postbox.
Sole caller (ShareController.swift:1146) migrated in place.

Wave 12: HorizontalPeerItem de-Postboxed (same pattern). Ripples the
collapse up into ChatListSearchRecentPeersNode's public init
(`postbox:/network:` -> `stateManager:`). That module still imports
Postbox for PostboxViewKey/UnreadMessageCountsView internals but its
public surface simplifies. 3 external caller sites migrated.

Wave 13: AttachmentTextInputPanelNode minor cleanup. Module was already
Postbox-free at source level (wave 6) but carried a dead BUILD dep and
had 2 raw `peerId?.namespace == Namespaces.Peer.SecretChat` checks.
Both now use existing `PeerId.isSecretChat` extension in TelegramCore.

Wave 14: BUILD-dep sweep mirroring wave 6's source sweep. 98 modules
had `//submodules/Postbox:Postbox` (or `//submodules/Postbox`) BUILD
deps despite no source file importing Postbox since wave 6. Single
iteration, zero restores -- Bazel Swift requires source-level `import`
for symbol resolution, so redundant BUILD deps are pure metadata.

Net: 110 files, +116/-149. Build verified green (debug_sim_arm64).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 20:26:58 +02:00
isaac
3716f59e7d Cleanup 2026-04-20 18:55:27 +02:00
isaac
0fd2765908 DecryptMatch: pure-Python port of fastlane match decrypt.rb
Replace the Ruby decrypt.rb shell-out with a direct Python call to
decrypt_match_data(). The iOS build no longer depends on a Ruby
interpreter. Includes the spec, plan, AES-256 port, tightened error
surfaces for key length and V1 fallback, and the BuildConfiguration
wire-up that drops decrypt.rb.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 18:45:34 +02:00
Isaac
34c2c8c8a4 Postbox -> TelegramEngine wave 10: StorageFileListPanelComponent drop
Closes the last future-wave candidate from wave 8 by eliminating the
Icon.media(Media, ...) enum case in StorageFileListPanelComponent.swift
and dropping import Postbox. StorageUsageScreen (the module as a whole)
is now fully Postbox-free.

Icon enum split:
  case media(Media, TelegramMediaImageRepresentation)  ->
    case mediaFile(TelegramMediaFile, TelegramMediaImageRepresentation)
    case mediaImage(TelegramMediaImage, TelegramMediaImageRepresentation)

Equatable rewritten as switch-over-tuple with id-based equality per
concrete type (lFile.fileId == rFile.fileId / lImage.imageId ==
rImage.imageId), same semantics as the old media.id comparison.

Binding site: `if case let .media(media, representation)` +
`as? TelegramMediaFile` / `as? TelegramMediaImage` downcasts ->
compound case-binding `case let .mediaFile(_, representation), let
.mediaImage(_, representation):` to lift the shared representation
variable, plus an inner switch for the setSignal branch. The compiler-
enforced exhaustiveness of the split improves call-site safety.

Construction sites (2): `.media(file, representation)` -> `.mediaFile(
file, representation)`, `.media(image, representation)` -> `.mediaImage(
image, representation)`.

Placeholder fixup:
  messageId: EngineMessage.Id(peerId: PeerId(namespace: PeerId.Namespace
    ._internalFromInt32Value(0), id: PeerId.Id._internalFromInt64Value(0)
    ), namespace: 0, id: 0)
  ->
  messageId: EngineMessage.Id(peerId: component.context.account.peerId,
    namespace: 0, id: 0)

Inside a measureItem layout-measurement instance. Caught by second-pass
build failure `cannot find 'PeerId' in scope`. PeerId / PeerId.Namespace
/ PeerId.Id are raw Postbox types (not TelegramCore typealiases —
consistent with wave 9's MessageId -> EngineMessage.Id fixup). Using
context.account.peerId is semantically equivalent for the measurement
use case (messageId only feeds image-fetch userLocation and Equatable
comparison, neither exercised for this standalone instance).

Net: 1 file changed, +22 / -29 lines.

Plan: docs/superpowers/plans/2026-04-20-postbox-to-telegramengine-wave-10.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 01:46:18 +02:00
Isaac
1a432362a3 Postbox -> TelegramEngine wave 9: StorageUsageScreen preferences-view rewrite
Closes the first of the two future-wave candidates left open by wave 8 by
rewriting both AccountSpecificCacheStorageSettings preferences-view
observation sites in StorageUsageScreen.swift using engine APIs, and
drops import Postbox from that file.

Site 1 — cacheSettingsExceptionCount (former 1047-1087):
  postbox.combinedView(keys: [.preferences(keys: Set([...]))]) +
  PreferencesView                ->
    context.engine.data.subscribe(TelegramEngine.EngineData.Item
                                    .Configuration.ApplicationSpecific-
                                    Preference(key: ...))
                                   + preferencesEntry?.get(...)

Site 2 — peerExceptions (former 3131-3196):
  - Same preferences-observation replacement as Site 1.
  - postbox.transaction { transaction.getPeer / getPeerCachedData as?
    CachedGroupData / CachedChannelData; FoundPeer(peer:subscribers:) }
    -> context.engine.data.get(EngineDataMap(...TelegramEngine.Engine-
       Data.Item.Peer.Peer.init(id:))) + pattern match on EnginePeer
       .user / .secretChat / .legacyGroup / .channel
  - Signal element: [(peer: FoundPeer, value: Int32)] -> [(peer: Engine-
    Peer, value: Int32)]. FoundPeer wrapper and its `subscribers` field
    dropped — computed but never read downstream (consumers only read
    .isEmpty, .count, and .prefix(3).map { EnginePeer($0.peer.peer) }).

Consumer update:
  peerExceptions.prefix(3).map { EnginePeer($0.peer.peer) } ->
      .prefix(3).map { $0.peer }

Typealias fixup (caught by first-pass build failure):
  var mergedMedia: [MessageId: Int64] -> [EngineMessage.Id: Int64]
  (MessageId is raw Postbox; must use the EngineMessage.Id typealias
   when import Postbox is removed.)

Reusable pattern documented in CLAUDE.md: TelegramEngine.EngineData.Item
.Configuration.ApplicationSpecificPreference(key: ValueBoxKey) is the
general-purpose engine replacement for the postbox.combinedView(keys:
[.preferences(keys: Set([key]))]) + PreferencesView idiom. Works from
any module importing TelegramCore (without import Postbox) because
passing PreferencesKeys.<name> keeps ValueBoxKey as an inferred-only
type that never gets named in the consumer.

Net: 1 file changed, +30 / -54.

StorageUsageScreen.swift is now Postbox-free. The wave 8 outcome's other
future candidate (StorageFileListPanelComponent.swift's Icon.media(Media,
...) enum case) remains — trivial future wave will land the whole-module
drop.

Plan: docs/superpowers/plans/2026-04-20-postbox-to-telegramengine-wave-9.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 01:11:50 +02:00
Isaac
635d392484 Postbox -> TelegramEngine wave 8: StorageUsageScreen domain-type migration
Narrow consumer-module migration of raw Message types to EngineMessage in
the StorageUsageScreen component. Two files touched; the module keeps
import Postbox because of two out-of-scope site clusters (preferences-
view observation + a Media-carrying Icon enum case) — both flagged in
CLAUDE.md and the wave doc as future-wave targets.

StorageUsageScreen.swift:
  SelectionState.togglePeer(availableMessages:)
      [EngineMessage.Id: Message]  -> [EngineMessage.Id: EngineMessage]
  AggregatedData.messages
      [MessageId: Message]         -> [EngineMessage.Id: EngineMessage]
  AggregatedData.clearIncludeMessages / .clearExcludeMessages
      [Message]                     -> [EngineMessage]
  AggregatedData.init messages param — same swap
  RenderResult.messages
      [MessageId: Message]         -> [EngineMessage.Id: EngineMessage]
  openMessage(message: Message)    -> openMessage(message: EngineMessage)
                                      (unwrap to raw at OpenChatMessageParams
                                       / chatMediaListPreviewControllerData
                                       call sites via ._asMessage())

StorageFileListPanelComponent.swift:
  Item.message: Message            -> EngineMessage
                                      (internal .id / .timestamp / .media
                                       usage compiles unchanged against the
                                       EngineMessage class).

Wave-7 facade-boundary bridging dropped:
  - renderStorageUsageStatsMessages call site: the .mapValues(EngineMessage.init)
    on existingMessages and .mapValues { $0._asMessage() } on the result vanish;
    AggregatedData.messages and RenderResult.messages are now engine-typed on
    both sides of the facade.
  - clearStorage call sites (2): the .map(EngineMessage.init) wraps around
    includeMessages / excludeMessages vanish; locals become [EngineMessage].
  - Inside AggregatedData.updateSelected... accumulation loop, four
    item.message._asMessage() calls (where item.message was EngineMessage
    and the target was [Message]) drop back to plain item.message.
  - StorageMediaGridPanelComponent.Item(message: EngineMessage(message), ...)
    at the RenderResult-build loop loses the EngineMessage(...) wrap since
    `message` is already EngineMessage.

Out of scope (module keeps import Postbox):
  - StorageUsageScreen.swift:1047-1062 / 3131-3185 — AccountSpecificCache-
    StorageSettings observation via postbox.combinedView + PreferencesView
    and a postbox.transaction block doing transaction.getPeer / getPeerCached-
    Data as? CachedGroupData/CachedChannelData for peer-category classification.
  - StorageFileListPanelComponent.swift:105 — Icon.media(Media, ...) enum case.
    Constructed only as .media(TelegramMediaFile, ...) or .media(TelegramMedia-
    Image, ...); trivial future wave to split into two cases.

Build verified green: 59s incremental, 27 actions, Telegram.ipa produced.

Plan: docs/superpowers/plans/2026-04-20-postbox-to-telegramengine-wave-8.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 00:39:19 +02:00
Isaac
b2ba4b5878 Postbox -> TelegramEngine wave 7: last TelegramEngine.* facade leaks
Closes the seven remaining raw-Postbox leaks in TelegramEngine public
facades surfaced by a post-wave-6 scouting pass (all non-permanently-
blocked candidates).

Facades migrated in place (6 rewrites + 1 deletion; all _internal_*
implementations unchanged per the "internal Postbox-facing stays raw"
rule):

  Messages:
    downloadMessage                          Signal<Message?>           -> Signal<EngineMessage?>
    topPeerActiveLiveLocationMessages        Signal<(Peer?, [Message])> -> Signal<(EnginePeer?, [EngineMessage])>
    getSynchronizeAutosaveItemOperations     deleted (dead facade; sole caller uses _internal_ directly)

  Peers:
    updatedRemotePeer                        Signal<Peer>  -> Signal<EnginePeer>
                                             (PeerReference param kept; no EnginePeer.Reference alias today)

  Resources:
    renderStorageUsageStatsMessages          [EngineMessage.Id: Message]  -> [EngineMessage.Id: EngineMessage]
    clearStorage(peerId: ...)                [Message]                     -> [EngineMessage]
    clearStorage(peerIds: ...)               [Message]                     -> [EngineMessage]
    clearStorage(messages:)                  [Message]                     -> [EngineMessage]
                                             (no external callers; migrated for overload-set consistency)

Consumer call-site updates (5 files):
  - ChatListSearchListPaneNode       drop redundant .flatMap(EngineMessage.init) wrap
  - LocationViewControllerNode       drop redundant .map(EngineMessage.init) wrap
  - LiveLocationSummaryManager       drop redundant EnginePeer(...) / EngineMessage(...) ctors
  - StorageUsageScreen               bridge [Message] <-> [EngineMessage] at the 4 facade-call points
                                     (internal [MessageId: Message] / [Message] storage kept;
                                      full-consumer-module migration is out of scope)

Discovery: grep of TelegramEngine/*/TelegramEngine*.swift public signatures
for `: Postbox|: Account|: MediaBox|: MediaResource|: Peer\b|: Message\b|
-> Signal<.*(Peer|Message)` turned up these seven candidates and no others.
After this wave, the full TelegramEngine.* facade surface is engine-typed
modulo the four permanently-blocked TelegramMediaResource-conforming
classes recorded in CLAUDE.md (ICloudFileResource, InstantPageExternal-
MediaResource, VideoLibraryMediaResource, YoutubeEmbedStoryboardMedia-
Resource).

No modules became Postbox-free in this wave. Plan: docs/superpowers/
plans/2026-04-20-postbox-to-telegramengine-wave-7.md.

Full project build verified green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 00:25:28 +02:00
Isaac
31012e7cf9 CLAUDE.md: update wave-6 commit SHA references after squash
The wave-6 commits (spec, plan, C1 batch drop, C2 tally) were
squashed into a single commit, shifting the SHA referenced twice in
the wave-6 outcome section. Updates the two "see git show <sha>"
pointers to the new squashed commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:55:25 +02:00
Isaac
8edaa79eda Merge commit '23c4d94748' 2026-04-19 23:54:22 +02:00
Isaac
7b2b74e79b Postbox -> TelegramEngine wave 6: unused import Postbox batch sweep
First build-verified unused-import sweep: speculatively dropped
import Postbox from 782 consumer files (plain ^import Postbox$ lines,
excluding TelegramCore/Postbox/TelegramApi paths), iterated 18 full
project builds with --continueOnError, restored the import on every
file that failed to compile. 183 drops survived; 189 consumer modules
newly Postbox-free.

Bundled: spec + plan + C1 atomic batch drop + C2 CLAUDE.md outcome and
permanent methodology guidance under Wave-selection. The methodology
subsection captures the reusable playbook (--continueOnError is
essential, dependency graphs are deep so expect many iterations,
pattern-based preemptive restores accelerate convergence, and
CLAUDE.md's engine typealias cheat sheet arrows are migration targets
rather than typealiases in TelegramCore).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:46:13 +02:00
Isaac
c99adbbe0b Postbox -> TelegramEngine wave 5: uploadSecureIdFile + SecureId context
Migrates uploadSecureIdFile's public signature from (context:,
postbox: Postbox, network: Network, resource: MediaResource) to
(context:, engine: TelegramEngine, resource: EngineMediaResource).
SecureIdVerificationDocumentsContext refactored to hold
engine: TelegramEngine instead of raw postbox + network, drops
import Postbox (tally +1). The one instantiation site in
SecureIdDocumentFormControllerNode updates to pass
engine: self.context.engine.

Completes the last explicitly-named future-wave candidate from
CLAUDE.md.

Bundled: spec + plan + C1 atomic migration + CLAUDE.md outcome.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:45:59 +02:00
Isaac
b989b160c0 Postbox -> TelegramEngine wave 4: TelegramEngine.Stickers.uploadSticker
Migrates uploadSticker's public surface from (peer: Peer,
resource: MediaResource, thumbnail: MediaResource?, ...) to
(peer: EnginePeer, resource: EngineMediaResource,
thumbnail: EngineMediaResource?, ...), and UploadStickerStatus.complete
payload from CloudDocumentMediaResource to EngineMediaResource. Both
external call sites plus the cascading destructure and .standalone
sites inside MediaEditorScreen migrated atomically.

Bundled: spec + fix + plan + C1 atomic facade migration + CLAUDE.md
outcome + enum-payload inventory lesson added to wave-selection
guidance.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:45:48 +02:00
Isaac
4ae15b42a7 Postbox -> TelegramEngine wave 3: MediaBox fetch/status/data facades + SaveToCameraRoll
Adds three thin forwarding methods on TelegramEngine.Resources
(fetch, status, data) over MediaBox, then migrates SaveToCameraRoll's
three public functions to use them, drops import Postbox from the
module (source + Bazel dep), and updates all 23 call sites across 14
caller files atomically.

Bundled: spec + fix + plan + C1 facades + C2 SaveToCameraRoll rewrite
+ BUILD dep drop + CLAUDE.md outcome.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:45:34 +02:00
Isaac
791bb62148 Display/ListView: snap-scroll to pinned item + synchronous history transactions
Adds an experimentalSnapScrollToPinnedItem path that resnaps scroll to
the first pinToEdgeWithInset item after inset/visible-size updates and
on empty itemNodes. Promotes ListViewItem to AnyObject and adds a
pinToEdgeWithInset protocol requirement with a default of false.

Also runs chat history transactions synchronously when updating scroll
around correlated messages, and tightens beganInteractiveDragging weak-
self handling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:45:18 +02:00
Isaac
684796144c TextProcessing: style create/edit/delete, AI previews, and integration
Wires up TextProcessingScreen to the edit/delete AI text style facades,
renders AI text style webpage previews in chat bubbles, and exposes a
shared makeEmojiStatusSelectionController on SharedAccountContext so
the screen can present the emoji picker when assigning a style emoji.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:45:18 +02:00
Isaac
d01bbc6529 TelegramCore: edit/delete AI text styles + AI webpage attribute
Adds TelegramEngine.Messages.editAITextStyle and deleteAITextStyle
facades and decodes webPageAttributeAiComposeTone into a new
TelegramMediaWebpageAITextStyleAttribute. Makes CloudStyle.prompt
optional and requires emojiFileId on create.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:45:18 +02:00
Isaac
b8e985b939 TelegramApi: regenerate schema for AI-compose tone + webpage attribute
Adds aicompose.createTone/updateTone/deleteTone functions,
InputAiComposeTone constructor, and webPageAttributeAiComposeTone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:45:18 +02:00
Isaac
4bd54b9771 Display/ListView: pin first pinToEdgeWithInset item to bottom edge
Introduces a pin-to-edge mode for list items: items whose
pinToEdgeWithInset flag is true are pinned to the bottom edge of the
visible area, with the list geometry (pin inset, scrollToItem,
inset-transition offsetFix, visible-size updates) adjusted to handle
this new mode consistently.

Collected from spec, plan, and 12 iterative fixes during
implementation that refined pin-inset helpers, scroll landings, and
transition math. Pin-inset computation uses frame.size.height;
scrollToItem lands on the item's pinned position via apparentBounds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 23:45:13 +02:00
Ilya Laktyushin
23c4d94748 Various fixes 2026-04-19 21:50:24 +02:00
Ilya Laktyushin
1670677a92 Various fixes 2026-04-19 21:48:47 +02:00
Ilya Laktyushin
b138b9f549 Stickers & emoji search pagination 2026-04-19 18:32:40 +02:00
Ilya Laktyushin
c9b76c9294 Various fixes 2026-04-19 14:17:48 +02:00
Ilya Laktyushin
d88a29b378 Various improvements 2026-04-18 08:41:08 +02:00
Ilya Laktyushin
1fa0c7991c Various fixes 2026-04-17 11:06:56 +02:00
Isaac
bedbc8de6d CLAUDE.md: record wave-2 outcome and update wave-selection guidance
Reflects the current state of the Postbox → TelegramEngine refactor:

- Header now lists waves 1 and 2 with their plans.
- New "Wave 2 outcome (2026-04-17)" section enumerates the five
  migrated TelegramEngine facades, the one fully de-Postboxed
  consumer submodule (MapResourceToAvatarSizes), the AuthorizationUI
  signal type swap, and the abandoned Task 8 (SaveToCameraRoll).
- Wave-selection guidance extended with two lessons learned:
  (a) planning-time inventories should grep the full Postbox token
  set, not just the tokens specific to the wave's goal, to avoid
  execution-time abandonments like wave 2's SaveToCameraRoll; and
  (b) facade-API migrations (wave 2's shape) work better than
  per-module Postbox drops (wave 1's shape) when the target is a
  shared API surface.
- New "Modules currently free of import Postbox" tally lists the
  8 consumer modules now clean across all waves and the standalone
  PromptUI / PresentationDataUtils / StickerPeekUI cleanups.
- New "Known future-wave candidates" section records the three
  leaks surfaced by the wave-2 final review and the four permanently
  blocked TelegramMediaResource-conforming classes.

Docs-only change. No behavior change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:43:48 +02:00
Isaac
bbfd1ddca0 Merge commit '532a3ae3e1' 2026-04-17 09:09:55 +02:00
Isaac
f84e94f507 MediaResource → EngineMediaResource refactor: wave 2
Drive raw `MediaResource` out of the `TelegramEngine` public facade for
photo-upload APIs, and complete a first batch of consumer-side
migrations. Behavior-preserving. The `_internal_*` Postbox-facing
functions are untouched — only the facade signatures change, bridging
inside via `_asResource()` / `EngineMediaResource(_:)`.

TelegramEngine facades migrated (signatures now take EngineMediaResource):
- TelegramEngine.Peers.uploadedPeerPhoto / uploadedPeerVideo
- TelegramEngine.Peers.updatePeerPhoto (closure param too)
- TelegramEngine.AccountData.updateAccountPhoto / updateFallbackPhoto
- TelegramEngine.Contacts.updateContactPhoto
- TelegramEngine.Auth.uploadedPeerVideo

Consumer-side changes:
- MapResourceToAvatarSizes utility: signature is now
  (engine: TelegramEngine, resource: EngineMediaResource, ...). Uses
  engine.resources.data(id:) internally. The submodule drops
  `import Postbox` and the Bazel dep.
- AuthorizationUI: avatar-video signal retyped from
  Signal<TelegramMediaResource?> to Signal<EngineMediaResource?>.
- 27 `mapResourceToAvatarSizes(postbox:...)` call sites across 5
  TelegramUI/TelegramCallsUI files migrated to the new form.

Deferred:
- SaveToCameraRoll (planned Task 8) abandoned — module has three
  public functions taking `postbox: Postbox` (umbrella-type leak,
  banned by rule 2) and requires a full module-migration wave, not a
  type swap. Reason recorded in the wave-2 plan doc.
- Other TelegramEngine facades still leaking MediaResource
  (TelegramEngineStickers.uploadSticker; UploadSecureIdFile.* —
  additionally leaks Postbox) flagged for a future wave.

Docs:
- CLAUDE.md: new rule 7 (TelegramCore never imports UIKit/Display,
  shared with Telegram-Mac), and a new "MediaResource →
  EngineMediaResource consumer migration" section describing the
  wrap/unwrap helpers and the modify-in-place facade-bridging
  pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:07:54 +02:00
Isaac
adc275af27 Fix base64 2026-04-17 09:06:14 +02:00
Isaac
75ec477248 PresentationDataUtils: drop direct Postbox dependency
The only Postbox usage in Sources/ was a `PeerId?` parameter in the
public signature of openUserGeneratedUrl. Switch to the
EnginePeer.Id typealias (same type as PeerId, so no call sites
break) and remove the Postbox import. Add TelegramCore to BUILD
deps since EnginePeer lives there; Postbox was not in BUILD (was
transitively supplied). Behavior-preserving.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 23:55:52 +02:00
Isaac
ef0974de6d PromptUI: drop unused Postbox dependency
The `import Postbox` line and `//submodules/Postbox` BUILD dep were
unused — no Postbox types or APIs are referenced in the module.
Removing both. Behavior-preserving.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 23:55:48 +02:00
Isaac
10e40b974c StickerPeekUI: drop unused Postbox dependency
The `import Postbox` line and `//submodules/Postbox` BUILD dep were
unused — no Postbox types or APIs are referenced in the module.
Removing both. Behavior-preserving.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 23:37:44 +02:00
Isaac
ad85ef6517 Postbox → TelegramEngine refactor: wave 1
Drop direct `import Postbox` from four leaf consumer submodules, routing
data access through TelegramEngine/TelegramCore. Behavior-preserving.

Consumers migrated:
- ChatInterfaceState
- ChatSendMessageActionUI
- ContactListUI
- DrawingUI

TelegramCore additions (typealiases + one EngineData item):
- EngineMemoryBuffer, EnginePostboxDecoder, EnginePostboxEncoder,
  EngineAdaptedPostboxDecoder (narrow utility aliases for coding support)
- EngineData.Item.Configuration.ContactsSettings

Six planned modules were abandoned in wave 1 with reasons recorded in
the plan: ActionSheetPeerItem, ChatListSearchRecentPeersNode,
DirectMediaImageCache, FetchManagerImpl, GalleryData, ICloudResources.
Each either has a public API that leaks `Postbox`/`Account`/`MediaBox`
(banned umbrella-type aliases) or cascades into out-of-wave modules.

CLAUDE.md now records the wave rules, typealias cheat sheet, and the
wave-selection guidance learned from this pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 23:16:45 +02:00
Ilya Laktyushin
532a3ae3e1 Various fixes 2026-04-16 21:45:26 +02:00
Isaac
40112d3cff Add implementation plan: Postbox → TelegramEngine wave 1
10 tasks, one per chosen leaf module, each with inventory-map-edit-
build-commit steps. Common build command, commit template, and
failure-handling rules centralized in a Background section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:32:51 +02:00
Isaac
ec24ec7dbb Tighten wave-1 spec: clarify engine typealias rules
TelegramCore does not re-export Postbox, so dropping the Postbox
import forces every Postbox-type reference to switch to an engine
typealias. Spell this out, and clarify that new typealiases are in
scope while new engine wrapper structs are not.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:24:13 +02:00
Isaac
5d40b8ca33 Add design: Postbox → TelegramEngine refactor, wave 1
Covers the first 10 single-import leaf submodules, in bottom-up
dependency order, with full-build verification per module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 18:22:52 +02:00
Isaac
bf21bca206 Merge commit '31e3a7dc79'
# Conflicts:
#	submodules/TelegramCore/Sources/PendingMessages/PendingMessageUploadedContent.swift
#	submodules/TelegramCore/Sources/TelegramEngine/Messages/Polls.swift
#	submodules/TelegramCore/Sources/TelegramEngine/Messages/Translate.swift
2026-04-16 17:52:38 +02:00
Ilya Laktyushin
31e3a7dc79 Fix build 2026-04-16 02:36:03 +02:00
Ilya Laktyushin
8aa421e08b Fix build 2026-04-16 02:00:16 +02:00
Ilya Laktyushin
8b7e294fc6 Fix build 2026-04-16 01:41:31 +02:00
Ilya Laktyushin
0df319742a Update API 2026-04-16 01:18:22 +02:00
Ilya Laktyushin
efb1110987 Fix build 2026-04-16 00:20:06 +02:00
Ilya Laktyushin
352d9f24e8 Fix build 2026-04-16 00:03:09 +02:00
Ilya Laktyushin
701d27c0a9 Fix build 2026-04-15 23:50:11 +02:00
Ilya Laktyushin
8f1e024aef Various fixes 2026-04-15 23:12:53 +02:00
Isaac
0095bfad39 Temp 2026-04-15 13:18:46 +02:00
Isaac
a4e9b0468e Merge commit '314f02d36d' 2026-04-14 15:34:04 +02:00
Isaac
2de1052c3d Cleanup 2026-04-14 15:33:58 +02:00
Isaac
976c2de599 Temp 2026-04-14 15:33:19 +02:00
Isaac
430ea53ed8 Add per-character glyph rects to InteractiveTextNodeLine and implement reveal animation
- Replace characterToGlyphMapping with characterRects ([CGRect]?) on InteractiveTextNodeLine
- Add computeCharacterRects flag to InteractiveTextNodeLayoutArguments
- Compute actual glyph bounding boxes via CTFontGetBoundingRectsForGlyphs during layout
- Implement computeRevealedLines, layoutForCharacterCount, sizeForCharacterCount
- Implement updateRevealCharacterCount to distribute character budget across content item layers
- Update snippet layers to animate per-character rects with SnippetLayer tracking character index
- Mask limit driven by lowest animating snippet index for correct reveal ordering
- Fix listViewAnimationCurveEaseIn to match iOS default ease-in curve (0.42, 0.0, 1.0, 1.0)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:31:49 +02:00
Isaac
9fb219645b Add design spec for character rects in InteractiveTextNodeLine
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 11:24:54 +02:00
Ilya Laktyushin
314f02d36d Various fixes 2026-04-14 04:53:01 +02:00
Ilya Laktyushin
64aa306cf9 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-14 03:34:28 +02:00
Ilya Laktyushin
22df2dbdb9 Various fixes 2026-04-14 03:33:34 +02:00
Isaac
41d6f727e0 Various improvements 2026-04-10 17:21:36 +02:00
Isaac
d6d0ab1a7f Merge branch 'temp-513'
# Conflicts:
#	versions.json
2026-04-10 14:30:58 +02:00
Isaac
d575824ab4 Various improvements 2026-04-10 14:30:23 +02:00
Isaac
d2293b8e09 Xcode 26.4 build crashes on iOS 15/16 2026-04-09 15:02:17 +02:00
Isaac
fc57219d1c Unbump xcode 2026-04-09 14:38:07 +02:00
Isaac
4504afcde3 Add design spec for tgcalls CLI UDP reflector mode
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 12:32:20 +02:00
Isaac
be6c32ef9c Trigger build 2026-04-07 21:44:48 +02:00
Isaac
0cbbf10eea Update entitlements 2026-04-07 21:13:31 +02:00
Isaac
45984d2a12 Update deploy 2026-04-07 20:48:44 +02:00
Isaac
41c6274252 Merge branch 'master' into beta
# Conflicts:
#	submodules/TelegramUI/Components/Chat/ChatMessagePollBubbleContentNode/Sources/ChatMessagePollBubbleContentNode.swift
#	versions.json
2026-04-07 20:45:57 +02:00
Isaac
80d7198230 Merge commit '9d2094fe23' 2026-04-07 20:32:42 +02:00
Isaac
f89246fd4b Bump version 2026-04-07 20:32:32 +02:00
Ilya Laktyushin
9d2094fe23 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-07 19:21:40 +02:00
Ilya Laktyushin
5c814c503e Live photo saving 2026-04-07 19:16:22 +02:00
Isaac
203047a464 Update deploy 2026-04-07 18:50:47 +02:00
Isaac
bef7b70e55 Merge commit '05d64c58b2' 2026-04-07 16:48:17 +02:00
Isaac
d89a4a79cf Various improvements 2026-04-07 16:48:11 +02:00
Isaac
278f3ca420 Various improvements 2026-04-07 16:47:08 +02:00
Isaac
64c23acd43 Fix url handling 2026-04-07 16:46:54 +02:00
Isaac
3d6fabea33 Update safari 2026-04-07 16:37:17 +02:00
Isaac
9338361543 fix: correct Swift-ObjC bridging in subcodec animation modules
Fix compilation errors in SubcodecAnimationCacheImpl and
SubcodecMultiAnimationRendererImpl: NSData->Data sink closure types,
withSink->sink argument labels for advanceFrame/emitFrameIfNeeded,
unused variable warning, and redundant Void return assignment.
Add both modules as deps to ChatEntityKeyboardInputNode to verify
they compile in the full build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:35:54 +02:00
Isaac
d6d633e296 feat: add SubcodecMultiAnimationRendererImpl public class with MultiAnimationRenderer conformance
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:20:32 +02:00
Isaac
dc20b265d1 feat: add SubcodecMultiAnimationRendererImpl internal types - SurfaceGroup, SpriteContext, frame extraction
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:18:41 +02:00
Isaac
7052e7e3ea feat: add SubcodecAnimationCacheImpl public class with protocol conformance and subcodec API
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:16:37 +02:00
Isaac
095c2940a8 feat: add SubcodecAnimationCacheImpl writer and ARGB-to-YUV conversion
Implements utility helpers, BT.709 ARGB→YUV 4:2:0 conversion with alpha
un-premultiplication, and AnimationCacheItemWriterImpl that feeds frames
to SCSprite and writes metadata alongside the .mbs output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 12:13:23 +02:00
Isaac
e8dc34c11b feat: add BUILD files for SubcodecAnimationCacheImpl and SubcodecMultiAnimationRendererImpl 2026-04-07 12:11:27 +02:00
Isaac
d147c63b68 Refactoring 2026-04-07 11:31:22 +02:00
Isaac
95a03d9931 subcodec 2026-04-07 10:44:45 +02:00
Ilya Laktyushin
05d64c58b2 Fix 2026-04-07 10:10:17 +02:00
Isaac
1b3a547401 subcodec 2026-04-07 09:58:54 +02:00
Isaac
28608194a9 fix: copy bSubcodecMode in ParamTranscode so encoder context sees the flag
Without this, SWelsSvcCodingParam::ParamTranscode was not copying
bSubcodecMode from SEncParamExt, so the encoder's internal pSvcParam
always had bSubcodecMode=false regardless of what the caller set.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 08:49:45 +02:00
Isaac
d239564d84 feat: gate Log2MaxFrameNum on bSubcodecMode via WelsInitSps parameter
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 08:42:28 +02:00
Isaac
e647f733c9 feat: gate padding recon override on bSubcodecMode with hardcoded 1-MB border 2026-04-07 08:41:06 +02:00
Isaac
9871479b27 feat: gate VaaOnScreen sub-partition suppression on bSubcodecMode 2026-04-07 08:40:23 +02:00
Isaac
1c05425261 feat: gate intra/I_4x4/sub-partition suppression on bSubcodecMode
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 08:39:09 +02:00
Isaac
d224a25d07 feat: gate MV range cap on bSubcodecMode 2026-04-07 08:36:38 +02:00
Isaac
96daaaa794 feat: replace iPaddingMbs with bSubcodecMode in SEncParamExt 2026-04-07 08:36:09 +02:00
Isaac
f3e1795b68 Temp 2026-04-07 08:11:27 +02:00
Ilya Laktyushin
ae6d05c49d Various fixes 2026-04-07 06:36:13 +02:00
Ilya Laktyushin
86e521c3cb Various fixes 2026-04-07 01:44:04 +04:00
Ilya Laktyushin
498897c227 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-04-04 10:11:50 +02:00
Ilya Laktyushin
65872a4a59 Poll improvements 2026-04-04 10:11:30 +02:00
Isaac
4235d7e9c8 Clean 2026-04-03 22:40:26 +08:00
Isaac
823244e49d Remove firebase 2026-04-03 22:23:39 +08:00
Isaac
648430e37d Various improvements 2026-04-03 22:15:42 +08:00
Isaac
16c630b946 Refactoring 2026-04-03 15:50:39 +08:00
Isaac
a4d630bf24 Merge commit '2bad906e88' 2026-04-03 13:15:09 +08:00
Isaac
1a728382c4 Disable AI button in secret chats 2026-04-03 13:15:06 +08:00
Ilya Laktyushin
2bad906e88 Fix stickers memory leak 2026-04-02 20:37:35 +02:00
Ilya Laktyushin
c81015c003 Various fixes 2026-04-02 19:20:15 +02:00
Ilya Laktyushin
098efc7f20 Bump version 2026-04-01 01:00:09 +02:00
Ilya Laktyushin
d0d3b064ed Cherry-pick fixes 2026-04-01 00:59:30 +02:00
Ilya Laktyushin
43c263cb6f Various fixes 2026-04-01 00:58:16 +02:00
Ilya Laktyushin
629f2b1e5d Various fixes 2026-04-01 00:33:44 +02:00
Ilya Laktyushin
e7722d7b29 Various fixes 2026-04-01 00:10:39 +02:00
Ilya Laktyushin
ff95bd97c9 Various fixes 2026-03-31 23:06:05 +02:00
Isaac
43e41b20d9 Update webrtc 2026-03-31 23:51:10 +08:00
Isaac
e181533029 Bump versions 2026-03-31 23:41:45 +08:00
Isaac
e8510c1a8a Fix search filter display 2026-03-31 23:05:28 +08:00
Isaac
5cb164d42e Merge commit '0fecd9a535' 2026-03-31 22:42:06 +08:00
Isaac
796826b0ad Various improvements 2026-03-31 22:42:02 +08:00
Ilya Laktyushin
0fecd9a535 Fix 2026-03-31 15:38:13 +02:00
Isaac
3e0c38c3ce Merge commit '36440d6566' 2026-03-31 20:24:35 +08:00
Isaac
34477605b1 Various improvements 2026-03-31 20:24:24 +08:00
Ilya Laktyushin
36440d6566 Album art view 2026-03-31 13:51:10 +02:00
Ilya Laktyushin
c1d8b98fda Update localization 2026-03-31 11:59:27 +02:00
Ilya Laktyushin
7ea47b8105 Various fixes 2026-03-30 17:23:39 +02:00
Isaac
18abe71dca Support Xcode 26.4 2026-03-30 20:44:10 +08:00
Isaac
001a5ed5b1 Merge commit 'b3d4c97da4' 2026-03-30 19:59:16 +08:00
Isaac
c73bceb797 Cleanup 2026-03-30 19:59:03 +08:00
Ilya Laktyushin
b3d4c97da4 Various improvements 2026-03-30 05:09:10 +02:00
Ilya Laktyushin
ca3eacda45 Various improvements 2026-03-30 04:37:05 +02:00
Ilya Laktyushin
8f8dca5795 Allow attach menu apps in paid message chats 2026-03-30 03:01:36 +02:00
Ilya Laktyushin
21adc7d061 Various improvements 2026-03-30 02:55:35 +02:00
Ilya Laktyushin
f3c18e1436 Various improvements 2026-03-29 22:18:19 +02:00
Ilya Laktyushin
8d7b84caac Various fixes 2026-03-29 18:49:14 +02:00
Ilya Laktyushin
acc053a628 Various fixes 2026-03-29 18:36:33 +02:00
Ilya Laktyushin
7ac52c685d Various fixes 2026-03-29 17:42:24 +02:00
Ilya Laktyushin
f160fb99d9 Various improvements 2026-03-29 16:23:09 +02:00
Ilya Laktyushin
ceceec2e94 Various fixes 2026-03-28 23:42:30 +01:00
Ilya Laktyushin
6df559ff97 Various fixes 2026-03-28 20:47:35 +01:00
Ilya Laktyushin
53d5425341 Various fixes 2026-03-28 18:27:01 +01:00
Ilya Laktyushin
5532067aa1 Various fixes 2026-03-28 16:10:52 +01:00
Ilya Laktyushin
0fc60571fe Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-28 15:55:56 +01:00
Ilya Laktyushin
265b502f76 Various fixes 2026-03-28 15:55:50 +01:00
Isaac
337ffb691e Improvements 2026-03-28 21:31:09 +08:00
Isaac
14ae9a0bf5 Merge commit '784b43934a' 2026-03-28 21:13:42 +08:00
Isaac
6257031092 Temp 2026-03-28 21:13:25 +08:00
Ilya Laktyushin
784b43934a Update text styles data 2026-03-27 22:59:36 +01:00
Ilya Laktyushin
d0fce97c93 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-27 18:45:59 +01:00
Ilya Laktyushin
e0ec4d9c31 Various fixes 2026-03-27 18:45:53 +01:00
Isaac
5cc27e5d04 Fix overlay chat layout 2026-03-28 01:22:15 +08:00
Isaac
0b878e4d24 Various improvements 2026-03-28 00:52:16 +08:00
Isaac
9142299387 Merge commit 'a320fbf36e'
# Conflicts:
#	submodules/TelegramUI/Components/CreateBotScreen/Sources/CreateBotScreen.swift
2026-03-28 00:12:38 +08:00
Isaac
f34db983e0 Various improvements 2026-03-28 00:11:41 +08:00
Ilya Laktyushin
a320fbf36e Fix build 2026-03-27 16:53:01 +01:00
Ilya Laktyushin
d90092d9f1 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-27 16:48:30 +01:00
Ilya Laktyushin
c1020d12c5 Various fixes 2026-03-27 16:48:23 +01:00
Mikhail Filimonov
3c4af77ad2 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-27 16:18:49 +01:00
Mikhail Filimonov
b5973fed13 canManageBots flag 2026-03-27 16:18:42 +01:00
Isaac
c9add89043 More ai button fixes 2026-03-27 22:33:54 +08:00
Isaac
51d1b693d1 Updates 2026-03-27 20:16:52 +08:00
Isaac
8dd7b4c8e7 Temp 2026-03-27 19:30:03 +08:00
Isaac
d11a967936 Merge commit 'fd68aed766' 2026-03-27 19:24:49 +08:00
Isaac
911ebd07ab Update 2026-03-27 19:23:09 +08:00
Isaac
22e58eb5e4 Add SwiftTL 2026-03-27 19:22:57 +08:00
Isaac
2907ddbe46 Unseen polls 2026-03-27 18:30:01 +08:00
Ilya Laktyushin
fd68aed766 Auth improvements 2026-03-27 11:24:08 +01:00
Ilya Laktyushin
bc3612587b Various fixes 2026-03-27 11:13:25 +01:00
Ilya Laktyushin
8a523bc1cd Update localization 2026-03-27 02:32:43 +01:00
Ilya Laktyushin
a1c4e02a06 Various fixes 2026-03-27 01:46:27 +01:00
Ilya Laktyushin
ed55943a44 Various improvements 2026-03-27 01:13:38 +01:00
Ilya Laktyushin
043cdc33d5 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-26 18:43:33 +01:00
Ilya Laktyushin
9dde762a1c Various improvements 2026-03-26 18:43:26 +01:00
Isaac
e6ce004498 Merge commit '77cc01f0d9' 2026-03-27 00:47:05 +08:00
Isaac
fe791128d6 Various improvements 2026-03-27 00:46:53 +08:00
Ilya Laktyushin
77cc01f0d9 Various fixes 2026-03-26 13:58:50 +01:00
Ilya Laktyushin
e3eac999c4 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-26 09:26:21 +01:00
Ilya Laktyushin
6b6ba070c7 Update API 2026-03-26 09:26:15 +01:00
Isaac
c3181ed97e Adjust spacing 2026-03-26 00:41:21 +08:00
Isaac
e9f62db2c3 Fix selection 2026-03-25 01:13:19 +08:00
Isaac
50c46d13f3 Merge commit '583e794a53' 2026-03-25 00:40:12 +08:00
Isaac
90844063f7 Update 2026-03-25 00:40:04 +08:00
Ilya Laktyushin
583e794a53 Merge branches 'master' and 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-24 17:21:52 +01:00
Ilya Laktyushin
25762d1133 Various fixes 2026-03-24 17:21:46 +01:00
Isaac
f48617fbec Update 2026-03-25 00:18:11 +08:00
Isaac
93bf472472 Text selection 2026-03-24 22:51:44 +08:00
Isaac
3920eb1507 Merge commit '010945d371' 2026-03-24 16:48:05 +08:00
Isaac
a0a2f9f6bf Various improvements 2026-03-24 16:47:36 +08:00
Mikhail Filimonov
010945d371 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-24 09:26:24 +01:00
Mikhail Filimonov
84bc40e1f8 polls 2026-03-24 09:26:16 +01:00
Ilya Laktyushin
d4402d371a Fix audio file ref 2026-03-24 08:56:17 +01:00
Ilya Laktyushin
ed6511a79e Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-24 07:13:53 +01:00
Ilya Laktyushin
d63f704472 Move list checkbox to the right 2026-03-24 07:13:46 +01:00
Ilya Laktyushin
67f45ba06d Various improvements 2026-03-24 06:54:30 +01:00
Isaac
9c0e6f6151 Merge commit 'e11c9899e6' 2026-03-24 01:39:57 +08:00
Isaac
f437e0bd04 Text editor 2026-03-24 01:39:53 +08:00
Isaac
c9e07daeda Temp 2026-03-24 00:26:50 +08:00
Isaac
1a17e97a7c Temp 2026-03-23 23:37:31 +08:00
Ilya Laktyushin
e11c9899e6 Various fixes 2026-03-23 15:03:50 +01:00
Isaac
19da3fa55a Merge commit '87409ead6c' 2026-03-23 21:33:37 +08:00
Isaac
0aac8d47ac Temp 2026-03-23 21:33:34 +08:00
Ilya Laktyushin
87409ead6c Various fixes 2026-03-23 12:41:42 +01:00
Ilya Laktyushin
9a9665ce54 Various improvements 2026-03-23 12:04:16 +01:00
Mikhail Filimonov
7354bea3e6 pass iscreator 2026-03-23 10:45:34 +01:00
Ilya Laktyushin
5ed2f0ad1e Various fixes 2026-03-23 00:17:18 +01:00
Ilya Laktyushin
c165cbe434 Update API 2026-03-22 18:41:53 +01:00
Ilya Laktyushin
d0e26af8b1 Various fixes 2026-03-22 18:05:56 +01:00
Ilya Laktyushin
61e174fd9e Various improvements 2026-03-22 16:59:07 +01:00
Ilya Laktyushin
6fd65e6d26 Various improvements 2026-03-22 16:53:55 +01:00
Ilya Laktyushin
8098f24f4e Various improvements 2026-03-22 16:41:22 +01:00
Ilya Laktyushin
6aa99e3553 Various improvements 2026-03-22 14:04:33 +01:00
Ilya Laktyushin
91548c5b05 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-22 13:44:10 +01:00
Ilya Laktyushin
66d08c0e1b Various improvements 2026-03-22 13:44:04 +01:00
Isaac
675696da2b Update animation 2026-03-22 05:20:26 +03:00
Isaac
b2ca658489 Translation improvements 2026-03-22 05:17:29 +03:00
Isaac
9110dda4b4 Fix color 2026-03-22 01:55:00 +03:00
Isaac
e554fa9c6a Merge commit '30ad6807d4' 2026-03-22 01:42:38 +03:00
Isaac
28323206b3 Temp 2026-03-22 01:41:58 +03:00
Ilya Laktyushin
30ad6807d4 Various improvements 2026-03-21 10:04:44 +01:00
Ilya Laktyushin
87ca0f78d6 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-21 09:47:24 +01:00
Ilya Laktyushin
ea4bcd9a46 Various improvements 2026-03-21 09:47:17 +01:00
Isaac
40e1e6a116 Improvements 2026-03-20 19:17:11 +01:00
Isaac
af6e5f258e Merge commit '90f110a311'
# Conflicts:
#	Telegram/Telegram-iOS/en.lproj/Localizable.strings
#	submodules/ChatPresentationInterfaceState/Sources/ChatPresentationInterfaceState.swift
2026-03-20 18:55:29 +01:00
Isaac
bc7858ad2b AI editing 2026-03-20 18:23:45 +01:00
Mikhail Filimonov
90f110a311 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-20 15:55:18 +01:00
Mikhail Filimonov
2b5f390262 remove debug 2026-03-20 15:55:08 +01:00
Ilya Laktyushin
8ac0f3d9e3 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-20 15:47:02 +01:00
Ilya Laktyushin
2a55559f82 Various fixes 2026-03-20 15:46:56 +01:00
Mikhail Filimonov
7811bfa350 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-20 15:35:58 +01:00
Mikhail Filimonov
694c443009 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Messages/Polls.swift
#	submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift
2026-03-20 15:35:49 +01:00
Ilya Laktyushin
f12fb93a3e [WIP] Polls 2026-03-20 14:52:19 +01:00
Ilya Laktyushin
676f46d44d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-20 12:48:12 +01:00
Ilya Laktyushin
34f5b9d4c2 Update API 2026-03-20 12:48:05 +01:00
Ilya Laktyushin
e7a334364c [WIP] Polls 2026-03-20 12:15:27 +01:00
Ilya Laktyushin
433237d1e9 [WIP] Polls 2026-03-20 10:15:00 +01:00
Isaac
8919596469 Temp 2026-03-19 22:27:08 +01:00
Mikhail Filimonov
bdacdee42f Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-19 14:30:46 +01:00
Mikhail Filimonov
d04f1d069f add poll answer 2026-03-19 14:30:40 +01:00
Ilya Laktyushin
5dce76415a Fix 2026-03-18 19:59:49 +01:00
Isaac
8d4926bca2 Fix 2026-03-18 01:03:20 +01:00
Isaac
2c10093c5e Merge commit '1a08c3f0d0'
# Conflicts:
#	submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift
2026-03-18 00:27:47 +01:00
Isaac
a2d5c530a5 Various improvements 2026-03-18 00:27:13 +01:00
Ilya Laktyushin
c32f645f5e [WIP] Polls 2026-03-17 16:32:49 +01:00
Ilya Laktyushin
6519b5c84d [WIP] Polls 2026-03-17 11:12:58 +01:00
Mikhail Filimonov
1a08c3f0d0 update api 2026-03-17 10:29:43 +01:00
Mikhail Filimonov
35346920b9 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-17 08:25:24 +01:00
Mikhail Filimonov
25d601920e composeMessageWithAI 2026-03-17 08:25:16 +01:00
Ilya Laktyushin
92ec3558e3 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-17 00:04:56 +01:00
Ilya Laktyushin
2b9d97b944 Update API 2026-03-17 00:04:50 +01:00
Isaac
67d43248da Temp 2026-03-16 20:52:05 +01:00
Isaac
c2cd6478a8 Revert "Temp"
This reverts commit 099267a84a.
2026-03-16 20:49:54 +01:00
Isaac
099267a84a Temp 2026-03-16 20:45:43 +01:00
Ilya Laktyushin
b1a190f87a [WIP] Polls 2026-03-16 18:07:12 +01:00
Ilya Laktyushin
b64d4a23fe Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-16 13:42:14 +01:00
Ilya Laktyushin
3a311f75bd Update API 2026-03-16 13:37:36 +01:00
Ilya Laktyushin
6980ca9397 Merge commit 'a824d97804' 2026-03-14 00:08:02 +01:00
Ilya Laktyushin
a171e30532 [WIP] Polls 2026-03-14 00:07:57 +01:00
Isaac
f38fa578c6 Fixes 2026-03-13 16:02:19 +01:00
Isaac
72fbe5d7a7 Various improvements 2026-03-13 14:54:44 +01:00
Ilya Laktyushin
950d99eea7 [WIP] Polls 2026-03-13 14:11:19 +01:00
Ilya Laktyushin
cbc5a49507 [WIP] Polls 2026-03-13 11:04:33 +01:00
Mikhail Filimonov
a824d97804 api update 2026-03-13 10:40:03 +01:00
Isaac
bebbd02f30 Merge commit '246b97ce8e' 2026-03-13 09:00:59 +01:00
Isaac
3d3232eedc Temp 2026-03-13 09:00:55 +01:00
Ilya Laktyushin
ce1685be40 Merge commit '5b04ae1131' 2026-03-13 00:30:49 +01:00
Mikhail Filimonov
5b04ae1131 update api 2026-03-12 19:29:26 +01:00
Ilya Laktyushin
246b97ce8e Various fixes 2026-03-12 15:53:10 +01:00
Mikhail Filimonov
dce5832d4d location 2026-03-12 14:25:05 +00:00
Ilya Laktyushin
dca6b5f145 Various improvements 2026-03-12 13:51:27 +01:00
Ilya Laktyushin
bf3ddc99f8 Update scheme 2026-03-12 11:43:27 +01:00
Ilya Laktyushin
968c577488 Reapply "Fix build"
This reverts commit b7312f6933.
2026-03-11 18:51:50 +01:00
Ilya Laktyushin
94923cc353 Reapply "Update API"
This reverts commit 0411cfc18c.
2026-03-11 18:51:44 +01:00
Mikhail Filimonov
a02f811c2a polls 2026-03-11 17:41:41 +00:00
Ilya Laktyushin
0411cfc18c Revert "Update API"
This reverts commit 6c1376169c.
2026-03-11 18:04:50 +01:00
Ilya Laktyushin
b7312f6933 Revert "Fix build"
This reverts commit 2d73c0796d.
2026-03-11 18:04:45 +01:00
Ilya Laktyushin
2d73c0796d Fix build 2026-03-11 14:48:15 +01:00
Mikhail Filimonov
0c2bb780d5 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-11 13:41:07 +00:00
Ilya Laktyushin
6c1376169c Update API 2026-03-11 14:37:23 +01:00
Mikhail Filimonov
88c60997ca Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-11 13:24:44 +00:00
Mikhail Filimonov
e88eb17f1e update translate 2026-03-11 13:24:38 +00:00
Isaac
33d598cbe7 Optimize 2026-03-10 19:33:45 +01:00
Isaac
e4e5142a96 Various improvements 2026-03-10 17:50:37 +01:00
Isaac
efb828e61b Metrics 2026-03-10 11:54:23 +01:00
Isaac
8605549176 Update submodule 2026-03-10 08:54:54 +01:00
Isaac
18201ca830 Refactor 2026-03-10 08:54:43 +01:00
Isaac
9a4327116d Refactor 2026-03-10 00:38:36 +01:00
Isaac
83af56d379 Update API [skip ci] 2026-03-09 21:14:50 +01:00
Isaac
68e26d20aa Merge commit '249e58fca0' 2026-03-09 20:23:48 +01:00
Isaac
8adc7ec9a5 Temp 2026-03-09 20:23:44 +01:00
Ilya Laktyushin
249e58fca0 Fix build 2026-03-09 17:44:31 +01:00
Ilya Laktyushin
ae0d5d4a79 Update localization 2026-03-09 17:13:37 +01:00
Ilya Laktyushin
713f557e64 Update API 2026-03-09 14:32:10 +01:00
Ilya Laktyushin
675b88b316 Fix message privacy value display 2026-03-08 22:41:35 +01:00
Ilya Laktyushin
4842beb80d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-03-08 08:49:33 +01:00
Ilya Laktyushin
c68337ef70 Update API 2026-03-08 08:49:21 +01:00
Isaac
ab72475106 Fix 2026-03-07 15:33:36 +01:00
Isaac
c84563bd86 Bump version 2026-03-07 02:43:53 +01:00
Isaac
7ac23627f8 Merge commit '1e8abfc3c0' 2026-03-07 02:43:30 +01:00
Ilya Laktyushin
1e8abfc3c0 Merge commit 'ed6643e82c' into beta 2026-03-07 01:18:15 +01:00
Ilya Laktyushin
ed6643e82c Fix recording cancel button hit testing 2026-03-07 01:06:00 +01:00
Ilya Laktyushin
e02f0fcc9c Fix story collage picker 2026-03-07 00:56:43 +01:00
Ilya Laktyushin
c06e1b2eb4 Bump version 2026-03-06 22:59:40 +01:00
Isaac
4fa6aaaf9d Merge commit 'e279f224a1' 2026-03-06 18:13:53 +01:00
Isaac
bb23c6f653 Various improvements 2026-03-06 18:13:48 +01:00
Ilya Laktyushin
e279f224a1 Various improvements 2026-03-06 13:20:49 +01:00
Ilya Laktyushin
d5ccfe2812 Various fixes 2026-03-06 10:48:10 +04:00
Ilya Laktyushin
b2d33d6a57 Various fixes 2026-03-03 23:18:54 +04:00
Ilya Laktyushin
551a74fd61 Bump version 2026-03-03 20:42:05 +04:00
Ilya Laktyushin
0fdb24253f Various fixes 2026-03-03 20:41:19 +04:00
Ilya Laktyushin
b1aa62e9cc Various fixes 2026-03-03 20:26:45 +04:00
Isaac
3ca012d610 Adjust 2026-03-03 16:30:31 +01:00
Ilya Laktyushin
ddd336bc8f Various fixes 2026-03-03 19:26:10 +04:00
Isaac
dc6827def2 Fix 2026-03-03 15:44:33 +01:00
Isaac
354a4ee92e Temp 2026-03-03 15:25:19 +01:00
Isaac
951bc1cec3 Temp 2026-03-03 11:40:08 +01:00
Ilya Laktyushin
ad0f639fb5 Various fixes 2026-03-02 18:26:12 +04:00
Ilya Laktyushin
45a9f55b0b Various fixes 2026-03-01 18:49:55 +04:00
Ilya Laktyushin
42085036a2 Various fixes 2026-03-01 17:55:12 +04:00
Ilya Laktyushin
2fb17b827b Various fixes 2026-02-28 13:55:20 +04:00
Ilya Laktyushin
b87a202329 Various fixes 2026-02-28 00:35:08 +04:00
Ilya Laktyushin
5efa8f63c0 Various fixes 2026-02-27 21:41:43 +04:00
Ilya Laktyushin
ad3b5bb0d8 Various fixes 2026-02-27 20:42:49 +04:00
Ilya Laktyushin
ad73bdf08c Various fixes 2026-02-27 19:44:46 +04:00
Ilya Laktyushin
8005514986 Various fixes 2026-02-27 18:52:13 +04:00
Ilya Laktyushin
7504a0f926 Trigger build 2026-02-27 17:17:10 +04:00
Ilya Laktyushin
501416e17a Various fixes 2026-02-27 16:49:29 +04:00
Ilya Laktyushin
e6320bcd91 Various fixes 2026-02-27 16:47:54 +04:00
Ilya Laktyushin
6b2bb6bfe6 Various fixes 2026-02-27 16:31:25 +04:00
Ilya Laktyushin
ba07479aa0 Various fixes 2026-02-27 16:09:25 +04:00
Ilya Laktyushin
b9ba7336bb Various fixes 2026-02-27 15:24:38 +04:00
Ilya Laktyushin
e3c84fce71 Various fixes 2026-02-27 14:34:18 +04:00
Ilya Laktyushin
ddd724a5af Various fixes 2026-02-27 01:29:16 +04:00
Ilya Laktyushin
e12e096919 Various fixes 2026-02-27 00:53:51 +04:00
Isaac
8a60ae2e7f Merge commit '7facb8b563' 2026-02-26 19:09:33 +01:00
Isaac
22254ad084 Merge remote-tracking branch 'refs/remotes/origin/master' 2026-02-26 19:09:26 +01:00
Isaac
eac4e0321d Unbump version 2026-02-26 19:09:03 +01:00
Ilya Laktyushin
7facb8b563 Trigger build 2026-02-25 19:56:50 +04:00
Ilya Laktyushin
9d5e4f395d Trigger build 2026-02-25 19:43:24 +04:00
Ilya Laktyushin
687cefb291 Various fixes 2026-02-25 18:09:57 +04:00
Ilya Laktyushin
02f2607dd9 Various fixes 2026-02-25 16:01:04 +04:00
Ilya Laktyushin
dbb8dee236 Various fixes 2026-02-25 14:23:01 +04:00
Ilya Laktyushin
1ab69f4527 Various fixes 2026-02-25 14:03:10 +04:00
Isaac
99b46bd53a Merge commit 'c05a1dd17c' 2026-02-25 10:47:22 +01:00
Isaac
043e9380d5 Bump version 2026-02-25 10:46:04 +01:00
Ilya Laktyushin
c05a1dd17c Various improvements 2026-02-25 13:00:12 +04:00
Ilya Laktyushin
7d65064f9b Various improvements 2026-02-25 04:38:32 +04:00
Ilya Laktyushin
d93a33cabb Update localization 2026-02-25 03:43:48 +04:00
Ilya Laktyushin
9fe004a7ec Various improvements 2026-02-25 02:08:33 +04:00
Ilya Laktyushin
32660b3806 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-02-24 21:44:38 +04:00
Ilya Laktyushin
654ff9e7e0 Various improvements 2026-02-24 21:44:29 +04:00
Isaac
73dfa5f60d Fix build 2026-02-24 18:00:55 +01:00
Isaac
4f513faa82 Merge commit '69c8e2634b' 2026-02-24 17:20:01 +01:00
Isaac
622ea906ef Merge commit 'e24d411efa' 2026-02-24 17:19:36 +01:00
Isaac
71b2ff998f Fix 2026-02-24 17:19:30 +01:00
Ilya Laktyushin
69c8e2634b Update localization 2026-02-24 19:33:42 +04:00
Ilya Laktyushin
aec6a54b5d Update localization 2026-02-24 19:12:54 +04:00
Isaac
ad30eb2bc5 Update 2026-02-24 14:00:41 +01:00
Ilya Laktyushin
e24d411efa Various fixes 2026-02-24 16:34:29 +04:00
Isaac
3ad16682c4 Update 2026-02-24 12:35:02 +01:00
Ilya Laktyushin
bae4591799 Web auth improvements 2026-02-24 15:10:22 +04:00
Isaac
e36e44ed72 Temp 2026-02-24 11:11:50 +01:00
Isaac
d52e4d9b62 Temp 2026-02-24 10:57:32 +01:00
Isaac
4f517ed01f Temp 2026-02-24 10:56:22 +01:00
Ilya Laktyushin
f852dca2c8 Manual date formatting 2026-02-24 13:07:08 +04:00
Ilya Laktyushin
c93c70ff84 Various fixes 2026-02-24 03:09:26 +04:00
Ilya Laktyushin
b07a2fbb77 Various improvements 2026-02-24 03:03:45 +04:00
Ilya Laktyushin
e3cbd92a40 Various improvements 2026-02-23 23:15:45 +04:00
Ilya Laktyushin
5d50aa34af Various improvements 2026-02-23 21:25:25 +04:00
Ilya Laktyushin
4203d70414 Various improvements 2026-02-23 18:45:47 +04:00
Isaac
4d4fcdd17f Cleanup 2026-02-23 11:19:09 +01:00
Isaac
45e8661802 Update submodules 2026-02-23 11:17:26 +01:00
Ilya Laktyushin
1d80861e09 Various improvements 2026-02-23 13:51:13 +04:00
Ilya Laktyushin
5018fd7c65 Added dates in poll results 2026-02-22 01:37:19 +04:00
Ilya Laktyushin
83669124c9 Skip past dates 2026-02-21 19:01:13 +04:00
Ilya Laktyushin
8def1683b9 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-02-21 13:45:36 +04:00
Ilya Laktyushin
2c4c9a9d9b [WIP] Live photos 2026-02-20 13:28:58 +04:00
Isaac
0999c097b4 Merge commit '670c547aad' 2026-02-20 09:57:54 +01:00
Isaac
02aab7476e Update 2026-02-20 09:57:49 +01:00
Mikhail Filimonov
670c547aad copy protection improvements 2026-02-20 10:58:14 +04:00
Isaac
0aae6101a3 Merge commit '589e46f52d'
# Conflicts:
#	submodules/TelegramApi/Sources/Api15.swift
#	submodules/TelegramApi/Sources/Api28.swift
#	submodules/TelegramApi/Sources/Api4.swift
2026-02-19 21:20:55 +01:00
Isaac
3b5707fe0f Update 2026-02-19 21:20:27 +01:00
Ilya Laktyushin
d9d1210c1d Various improvements 2026-02-19 21:53:26 +04:00
Mikhail Filimonov
a2413e4aa8 Merge commit '589e46f52d' into formatted-date-api 2026-02-19 14:57:59 +04:00
Mikhail Filimonov
2e2b278e85 match code 2026-02-19 14:57:47 +04:00
Ilya Laktyushin
589e46f52d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-02-17 10:42:35 +04:00
Ilya Laktyushin
9c16af25c0 Update API 2026-02-17 10:25:42 +04:00
Isaac
26cc304ca0 Fix bg 2026-02-17 10:19:02 +04:00
Isaac
7171441b96 Update 2026-02-16 21:54:04 +04:00
Isaac
4f6ba2c2d0 Update docs 2026-02-15 22:53:21 +04:00
Isaac
dec912f2db Update 2026-02-15 22:50:18 +04:00
Isaac
038a6e928c Update 2026-02-14 23:20:28 +04:00
Isaac
9988158f83 WIP ui-tests 2026-02-14 20:01:15 +04:00
Isaac
4864bb1ae4 Bump version 2026-02-14 16:46:38 +04:00
Isaac
c79716dfbe Merge branch 'beta' 2026-02-14 16:46:10 +04:00
Isaac
f4064a5dd9 Temp
(cherry picked from commit 44fab3078a)
2026-02-13 19:56:39 +04:00
Isaac
631d5e1b2f Additional topic fixes 2026-02-13 19:19:48 +04:00
Isaac
6c37615dbd Continue Last Thread fix 2026-02-13 19:19:20 +04:00
Isaac
a8a308d7a6 forMainFrameOnly 2026-02-13 18:15:03 +04:00
Isaac
9d33962c01 constTimeIsEqual 2026-02-13 18:13:26 +04:00
Isaac
466de70edd constTimeIsEqual 2026-02-13 18:10:16 +04:00
Isaac
09d3f7386b Don't crash on invalid input 2026-02-13 18:10:06 +04:00
Isaac
fe8d847408 Gallery fixes 2026-02-13 18:09:56 +04:00
Isaac
ddf5ac7275 Update tgcalls 2026-02-13 18:09:41 +04:00
Isaac
8b56eb602e Merge commit '9616ea2ad9' 2026-02-13 17:08:52 +04:00
Isaac
157a7a978d Glass 2026-02-13 17:08:48 +04:00
Mikhail Filimonov
04f6c60c0c Merge commit '9616ea2ad9' into formatted-date-api 2026-02-13 15:36:11 +04:00
Ilya Laktyushin
9616ea2ad9 Update API 2026-02-13 14:09:36 +04:00
Isaac
2a317d87d2 Upgrade SpaceWarpNode 2026-02-13 12:23:53 +04:00
Isaac
955d69472c Merge commit 'c0f7cda4eb' 2026-02-12 17:58:56 +04:00
Isaac
41566cede0 Adjust animation 2026-02-12 17:58:53 +04:00
Isaac
761701caa1 Improve ripple effect 2026-02-12 17:48:03 +04:00
Mikhail Filimonov
82f930a993 Merge commit 'c0f7cda4eb' into formatted-date-api 2026-02-12 16:20:46 +04:00
Ilya Laktyushin
c0f7cda4eb Update API 2026-02-12 15:37:57 +04:00
Ilya Laktyushin
6240a14697 Crafting improvements 2026-02-12 14:04:46 +04:00
Isaac
37a744a26c Merge branch 'temp-10'
# Conflicts:
#	submodules/DebugSettingsUI/Sources/DebugController.swift
2026-02-11 22:07:23 +04:00
Isaac
45b3705f1f Re-enable incremental build 2026-02-11 22:05:23 +04:00
Isaac
bb30f5c1ea Disable ASDK accessibility 2026-02-11 22:05:08 +04:00
Isaac
dde740bfe8 Various improvements 2026-02-11 22:04:54 +04:00
Mikhail Filimonov
72b0007ac0 Merge commit '72ed83c99a' into formatted-date-api 2026-02-10 14:01:11 +04:00
Ilya Laktyushin
72ed83c99a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-02-10 12:59:12 +04:00
Ilya Laktyushin
189d25c32e Update API 2026-02-10 12:58:04 +04:00
Mikhail Filimonov
e294569f5d Merge commit 'a329f55dce' into formatted-date-api
# Conflicts:
#	submodules/TelegramCore/Sources/State/Serialization.swift
2026-02-10 11:48:39 +04:00
Isaac
692fbd9742 Fix chat title update 2026-02-10 10:52:53 +04:00
Isaac
73d7587a06 Bump version
(cherry picked from commit 2057b724cd)
2026-02-09 23:56:44 +04:00
Isaac
102afdeaf6 Fix pinned background 2026-02-09 23:39:59 +04:00
Isaac
cd6092d15a Fix build 2026-02-09 23:28:15 +04:00
Isaac
45952b7c18 Fix forum forwarding 2026-02-09 23:28:06 +04:00
Isaac
6ed54e991b Cherry-pick fixes 2026-02-09 23:03:51 +04:00
Isaac
a329f55dce Merge commit '4b9b95cbc5' 2026-02-09 22:58:01 +04:00
Isaac
0afb17091b Various improvements 2026-02-09 22:55:28 +04:00
Ilya Laktyushin
4b9b95cbc5 Fix 2026-02-08 23:27:38 +04:00
Ilya Laktyushin
8babb95d7e Fix 2026-02-08 16:10:33 +04:00
Ilya Laktyushin
b47660b22c Various fixes 2026-02-06 19:35:09 +04:00
Isaac
7606a5a0fe Update 2026-02-06 18:03:26 +04:00
Isaac
a1c3b7a588 Fix send button blur 2026-02-06 17:49:43 +04:00
Isaac
c313a43456 Fix forum forwarding 2026-02-06 17:40:36 +04:00
Isaac
2057b724cd Bump version 2026-02-06 17:17:24 +04:00
Isaac
002df956d2 Bug fixes 2026-02-06 17:14:35 +04:00
Isaac
a3b4b085ae Merge commit 'aa21a14c7d'
# Conflicts:
#	submodules/TelegramUI/Components/ContextControllerImpl/Sources/ContextActionsContainerNode.swift
2026-02-06 15:19:11 +04:00
Isaac
45b1306274 Various improvements 2026-02-06 15:18:17 +04:00
Mikhail Filimonov
c9ea813970 Merge branch 'beta' into formatted-date-api 2026-02-06 14:39:16 +04:00
Mikhail Filimonov
d4a3523fb1 refactor 2026-02-06 14:38:53 +04:00
Ilya Laktyushin
25952cfef6 Merge commit 'e81e7c6897' 2026-02-06 14:25:13 +04:00
Ilya Laktyushin
96bb624b2d Merge branch 'formatted-date-api' 2026-02-06 14:25:09 +04:00
Ilya Laktyushin
e81e7c6897 Formatted date support 2026-02-06 14:24:03 +04:00
Ilya Laktyushin
aa21a14c7d Update API [skip ci] 2026-02-06 13:35:20 +04:00
Isaac
44fab3078a Temp 2026-02-06 11:39:09 +04:00
Ilya Laktyushin
e17c7d9859 Update API 2026-02-05 17:27:47 +04:00
Isaac
5aeb390d8c Merge commit '63a37c5bec' 2026-02-05 14:58:47 +08:00
Isaac
8005726b3d Experiment 2026-02-05 14:58:39 +08:00
Ilya Laktyushin
63a37c5bec Merge commit '5ebc55af73' into beta 2026-02-04 17:46:28 +04:00
Ilya Laktyushin
5ebc55af73 Fix location view 2026-02-04 17:34:19 +04:00
Ilya Laktyushin
c0f8f7deec Merge commit 'e6b0d669e3' into beta 2026-02-04 17:11:59 +04:00
Ilya Laktyushin
e6b0d669e3 Bump version 2026-02-04 17:08:46 +04:00
Ilya Laktyushin
29678db680 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-02-04 16:36:18 +04:00
Ilya Laktyushin
c5a0ad267c Various improvements 2026-02-04 16:36:09 +04:00
Isaac
8e9cd79855 Fix buffer 2026-02-04 19:41:25 +08:00
Isaac
2bed5fab18 Re-commit 2026-02-04 18:01:47 +08:00
Isaac
cb802c524e Revert "Experiment"
This reverts commit 8c54db62f3.
2026-02-04 18:01:32 +08:00
Isaac
d40e803719 Merge commit 'b3aef93435' 2026-02-04 03:22:41 +08:00
Isaac
8c54db62f3 Experiment 2026-02-04 03:22:37 +08:00
Ilya Laktyushin
b3aef93435 Various improvements 2026-02-03 21:58:41 +04:00
Ilya Laktyushin
ef5a5d22ab Various improvements 2026-02-03 19:23:16 +04:00
Ilya Laktyushin
ceca805df7 Various improvements 2026-02-03 19:07:30 +04:00
Ilya Laktyushin
07bddcd6f4 Various fixes 2026-02-03 17:53:48 +04:00
Ilya Laktyushin
510dadd5a5 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-02-03 17:33:40 +04:00
Ilya Laktyushin
14be0239af Various improvements 2026-02-03 17:33:31 +04:00
Isaac
facd51e0f5 Fix buttons 2026-02-03 21:05:05 +08:00
Isaac
5a92faa94b Trigger build 2026-02-03 20:35:52 +08:00
Isaac
370bcdfe04 Merge commit '0e58f827b6' 2026-02-03 20:24:24 +08:00
Isaac
0b112aea95 Fix animation 2026-02-03 20:24:21 +08:00
Isaac
1bb139ff32 Various improvements 2026-02-03 20:17:44 +08:00
Ilya Laktyushin
0e58f827b6 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-02-03 15:33:33 +04:00
Ilya Laktyushin
2ba1f6183e Various fixes 2026-02-03 15:27:06 +04:00
Isaac
93b10b7e11 Fix emoji pack tap 2026-02-03 01:41:59 +08:00
Isaac
bc9d6d8368 Merge commit 'bbad57434f' 2026-02-03 01:00:45 +08:00
Isaac
83c1563c44 Fix text recognition overlay 2026-02-03 01:00:41 +08:00
Ilya Laktyushin
bbad57434f Various fixes 2026-02-02 15:54:43 +04:00
Isaac
a49fea01ac Merge commit '226200c8c9' 2026-02-02 17:38:35 +08:00
Isaac
bc3523d4e0 Various improvements 2026-02-02 17:38:32 +08:00
Ilya Laktyushin
226200c8c9 Various improvements 2026-02-02 04:11:51 +04:00
Isaac
6ed562a052 Update colors 2026-02-01 01:51:31 +08:00
Ilya Laktyushin
3ea99e6eee Various fixes 2026-01-31 19:58:54 +04:00
Ilya Laktyushin
b7f206c486 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-31 07:08:15 +04:00
Ilya Laktyushin
cbe98a3fc6 Various improvements 2026-01-31 07:08:06 +04:00
Isaac
c9074f65ba Merge commit 'c509a6e1a2' 2026-01-31 01:30:06 +08:00
Isaac
2c601506ae Reset some theme keys 2026-01-31 01:30:03 +08:00
Ilya Laktyushin
c509a6e1a2 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-30 20:46:11 +04:00
Ilya Laktyushin
f58bf2e724 Various improvements 2026-01-30 20:46:03 +04:00
Mikhail Filimonov
4da24b44dc Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-30 17:41:04 +01:00
Mikhail Filimonov
dca57f143d gift unavailable 2026-01-30 17:40:50 +01:00
Isaac
ff7f75c946 Merge commit 'eb20fdbc60' 2026-01-31 00:37:38 +08:00
Isaac
ad731bf237 Various improvements 2026-01-31 00:37:35 +08:00
Ilya Laktyushin
eb20fdbc60 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-30 20:21:41 +04:00
Ilya Laktyushin
b91e78fbea Various improvements 2026-01-30 20:21:24 +04:00
Isaac
37ffcf76e9 Merge commit '0448473ab6' 2026-01-30 23:53:59 +08:00
Isaac
5b27ca9d4c Various improvements 2026-01-30 23:53:55 +08:00
Ilya Laktyushin
0448473ab6 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-30 19:47:31 +04:00
Ilya Laktyushin
7f75219a03 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-30 19:45:23 +04:00
Isaac
8af5f74cf7 Fix build 2026-01-30 22:57:12 +08:00
Ilya Laktyushin
75627b036a Various improvements 2026-01-30 18:55:05 +04:00
Isaac
47cef684ba Merge commit '15d0267e72'
# Conflicts:
#	submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramMediaAction.swift
2026-01-30 22:40:53 +08:00
Isaac
58aab15546 Various improvements 2026-01-30 22:39:20 +08:00
Isaac
962a9ae83a Various improvements 2026-01-30 22:20:50 +08:00
Mikhail Filimonov
15d0267e72 burned flag 2026-01-30 12:09:19 +01:00
Isaac
87e914d1d2 Merge commit '90a4dbe855' 2026-01-30 18:50:28 +08:00
Isaac
9c4e390f0d Various improvements 2026-01-30 18:50:18 +08:00
Mikhail Filimonov
609c22582a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-30 08:22:01 +01:00
Mikhail Filimonov
4d99e3ad01 badge 2026-01-30 08:21:55 +01:00
Ilya Laktyushin
90a4dbe855 Fix stake dice result message 2026-01-30 03:21:18 +04:00
Ilya Laktyushin
f0c0f806e6 Various improvements 2026-01-30 01:45:59 +04:00
Ilya Laktyushin
d07d38df25 Various improvements 2026-01-30 00:11:52 +04:00
Ilya Laktyushin
422e3e4e24 Various improvements 2026-01-29 21:37:06 +04:00
Mikhail Filimonov
5389f949d9 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-29 14:07:16 +01:00
Ilya Laktyushin
4e43b0cbb2 Various improvements 2026-01-29 17:02:59 +04:00
Ilya Laktyushin
b459de93b6 Various fixes 2026-01-29 13:27:18 +04:00
Ilya Laktyushin
4d64ba28a5 Various improvements 2026-01-29 02:48:56 +04:00
Ilya Laktyushin
1d59f24bd8 Update API 2026-01-28 23:50:31 +04:00
Ilya Laktyushin
809958df3b Update localization 2026-01-28 22:11:45 +04:00
Ilya Laktyushin
a1aa4d9094 Various fixes 2026-01-28 19:05:47 +04:00
Ilya Laktyushin
52a22d8cef Fix faq 2026-01-28 00:23:23 +04:00
Ilya Laktyushin
15ca7254fb Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-27 22:24:42 +04:00
Ilya Laktyushin
142d59cf8f Various improvements 2026-01-27 22:24:31 +04:00
Isaac
efe000e9e3 Fix crashes 2026-01-28 01:06:37 +08:00
Isaac
42bf37bbc8 Feature flag 2026-01-27 22:58:16 +08:00
Isaac
ba1068a5ea Fix delete context item 2026-01-27 21:50:59 +08:00
Isaac
0f025f0c55 Fix 2026-01-27 21:20:00 +08:00
Isaac
80c7b7c3f3 Fix 2026-01-27 21:18:48 +08:00
Isaac
13e9940230 Fix build 2026-01-27 21:14:08 +08:00
Isaac
9af8018ac6 Merge commit '8be8491b84'
# Conflicts:
#	submodules/TelegramUI/Components/GlassControls/Sources/GlassControlGroup.swift
2026-01-27 21:05:39 +08:00
Isaac
8422b48216 Glass gallery 2026-01-27 21:04:08 +08:00
Mikhail Filimonov
6f3f664f82 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-27 10:12:40 +01:00
Mikhail Filimonov
c1659b34e8 macos related 2026-01-27 10:12:34 +01:00
Ilya Laktyushin
8be8491b84 Various improvements 2026-01-26 02:16:22 +04:00
Ilya Laktyushin
0d12dd29ad Various improvements 2026-01-25 22:17:49 +04:00
Isaac
7f59789ffc Fix more elements 2026-01-25 00:55:04 +08:00
Isaac
ea82a68859 Adjust effect 2026-01-25 00:38:55 +08:00
Isaac
ca6fdc1629 Glass 2026-01-25 00:31:18 +08:00
Isaac
0431273d7f Merge commit '206bb40479' 2026-01-24 00:35:51 +08:00
Isaac
6ad2622b30 Various updates 2026-01-24 00:35:42 +08:00
Mikhail Filimonov
4832fe8234 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-22 18:53:41 +01:00
Ilya Laktyushin
206bb40479 Update API 2026-01-22 21:21:24 +04:00
Mikhail Filimonov
20b00b51b2 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-22 17:37:26 +01:00
Isaac
5ac365a601 Connection impl 2026-01-20 23:43:39 +08:00
Isaac
bc6b472960 Temp glass UI 2026-01-20 22:30:38 +08:00
Isaac
0638c08b75 Merge commit '823cd9993f' 2026-01-20 21:35:12 +08:00
Isaac
4f04dc0bb7 Glass 2026-01-20 21:35:04 +08:00
Mikhail Filimonov
589168318a update api (rarities, crafted) 2026-01-20 13:24:54 +01:00
Ilya Laktyushin
823cd9993f Update API [skip ci] 2026-01-20 15:34:55 +04:00
Ilya Laktyushin
7f2eb05339 Update API [skip ci] 2026-01-20 15:21:58 +04:00
Ilya Laktyushin
ea9d8db1d3 Update API [skip ci] 2026-01-20 14:54:15 +04:00
Isaac
f444587197 Generate real API 2026-01-19 14:37:53 +08:00
Isaac
50c5cc9616 Refactor constructor use sites for types 560-579 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 00:40:53 +08:00
Isaac
bb7e1ae300 Refactor constructor use sites for types 540-559 to struct pattern
Migrated Api.phone.*, Api.photos.*, Api.stats.*, Api.premium.* constructors
to use struct-wrapped enum pattern with --struct-count=560.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 00:28:21 +08:00
Isaac
64d8fe6ba0 Refactor constructor use sites for types 520-539 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 00:14:18 +08:00
Isaac
6746305b4b Refactor constructor use sites for types 500-519 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 00:06:07 +08:00
Isaac
b1f723fbe8 Refactor constructor use sites for types 480-499 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 23:47:18 +08:00
Isaac
5e4cbec07a Refactor constructor use sites for types 460-479 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 23:36:22 +08:00
Isaac
1f4b520b1b Refactor constructor use sites for types 440-459 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 23:29:12 +08:00
Isaac
81e17da3fb Refactor constructor use sites for types 420-439 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 23:22:34 +08:00
Isaac
b5dc0b2fd9 Refactor constructor use sites for types 400-419 to struct pattern
Refactored Api constructors in authorization and channel-related code:
- authorization, authorizationSignUpRequired, sentCode, sentCodeSuccess,
  sentCodePaymentRequired, sentCodeTypeFirebaseSms, and related types
- channelParticipant, channelParticipants, sendAsPeers, adminLogResults
- chatlistInvite, chatlistInviteAlready, chatlistUpdates, exportedChatlistInvite
- popularAppBots, sponsoredMessageReportResultChooseOption, and others

Fixed variable shadowing issues where 'user' was extracted and then
immediately shadowed by TelegramUser initialization.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 23:15:21 +08:00
Isaac
5e27a39d80 Refactor constructor use sites for types 380-399 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 22:58:30 +08:00
Isaac
55c53717af Refactor constructor use sites for types 360-379 to struct pattern
Migrated 20 types including userProfilePhoto, userStatus*, username, videoSize*,
wallPaper*, webDocument*, webPage*, webViewResultUrl, authorizations,
authorizationForm, autoDownloadSettings, businessChatLinks, chatThemes,
connectedBots, and contentSettings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 22:45:35 +08:00
Isaac
9b71eb0f8f Refactor constructor use sites for types 340-359 to struct pattern
Updates TelegramCore to work with --struct-count=360. This batch includes
story types, update types, user types, theme types, and various other
constructors in the 340-359 type range.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 22:21:57 +08:00
Isaac
8a99f76f93 Refactor constructor use sites for types 320-339 to struct pattern
Migrated constructors: starsSubscription, starsSubscriptionPricing,
starsTopupOption, starsTransaction, starsTransactionPeer,
statsAbsValueAndPrev, statsDateRangeDays, statsGraph, statsGraphAsync,
statsGraphError, statsGroupTopAdmin, statsGroupTopInviter,
statsGroupTopPoster, statsPercentValue, stickerKeyword, stickerPack,
stickerSet, stickerSetCovered, stickerSetFullCovered,
stickerSetMultiCovered, stickerSetNoCovered, storiesStealthMode,
storyAlbum, storyFwdHeader

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 15:06:15 +08:00
Isaac
859f5acea5 Refactor constructor use sites for types 300-319 to struct pattern
Migrated star gift and stars-related constructors including:
- starGift, starGiftUnique (pattern matches)
- starGiftAttribute*, starGiftAuction* constructors
- starsAmount, starsTonAmount, starsGiftOption
- starsGiveawayOption, starsGiveawayWinnersOption
- starsRevenueStatus, starRefProgram, starsRating
- starGiftCollection, starGiftUpgradePrice, starGiftBackground

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 14:54:12 +08:00
Isaac
5712f3061f Refactor constructor use sites for types 280-299 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 14:42:21 +08:00
Isaac
42b89bbb90 Refactor constructor use sites for types 260-279 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 14:34:07 +08:00
Isaac
07313cbb84 Refactor constructor use sites for types 250-259 to struct pattern
Migrates the following constructors to use struct-wrapped associated values:
- postInteractionCountersMessage, postInteractionCountersStory
- premiumGiftCodeOption, premiumSubscriptionOption
- prepaidGiveaway, prepaidStarsGiveaway
- privacyValueAllowChatParticipants, privacyValueAllowUsers
- privacyValueDisallowChatParticipants, privacyValueDisallowUsers
- publicForwardMessage, publicForwardStory
- quickReply
- reactionCustomEmoji, reactionEmoji

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 14:24:53 +08:00
Isaac
90737abf6d Refactor constructor use sites for types 240-249 to struct pattern
Types refactored: phoneCallProtocol, phoneConnection, phoneConnectionWebrtc,
photo, photoEmpty, photoCachedSize, photoPathSize, photoSize, photoSizeEmpty,
photoSizeProgressive, photoStrippedSize, poll, pollAnswer, pollAnswerVoters,
pollResults, popularContact, postAddress

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 02:25:52 +08:00
Isaac
c6b0ef5da3 Refactor constructor use sites for types 220-239 to struct pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 02:08:10 +08:00
Isaac
a3d66c99f0 Refactor constructor use sites for types 220-229 to struct pattern
Constructors refactored:
- passkey, passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow
- pageRelatedArticle, pageTableCell, pageTableRow
- paymentCharge
- paidReactionPrivacyPeer
- paymentFormMethod, paymentRequestedInfo, paymentSavedCredentialsCard

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 01:44:12 +08:00
Isaac
3e5775b48e Refactor constructor use sites for types 210-220 to struct pattern
Types refactored:
- myBoost, nearestDc, notificationSound*, notifyForumTopic, notifyPeer
- outboxReadDate, page, pageBlock*, pageCaption, pageListItem*

Files modified (8):
- ApiUtils/InstantPage.swift (33 constructors)
- ApiUtils/TelegramPeerNotificationSettings.swift (2 constructors)
- ForumChannels.swift (1 constructor)
- State/AccountStateManagementUtils.swift (2 constructors)
- State/ChannelBoost.swift (1 constructor)
- State/UpdatesApiUtils.swift (1 constructor)
- TelegramEngine/Messages/MessageReadStats.swift (1 constructor)
- TelegramEngine/Peers/NotificationExceptionsList.swift (1 constructor)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 01:15:19 +08:00
Isaac
94b53b190a Refactor constructor use sites for types 200-209 to struct pattern
Refactored constructors: messageReactions, messageReactor, messageReplies,
messageReplyHeader, messageReplyStoryHeader, messageViews,
inputMessagesFilterPhoneCalls, messagePeerVote, messagePeerVoteInputOption,
messagePeerVoteMultiple, messageReportOption, missingInvitee

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 01:01:19 +08:00
Isaac
61983a113a Refactor constructor use sites for types 190-199 to struct pattern
Refactored constructors include:
- maskCoords, mediaArea*, message, messageEmpty, messageService
- messageAction* (50+ action types)
- messageEntity* (20+ entity types)
- messageMedia* (20+ media types)
- messageFwdHeader, messagePeerReaction, messageExtendedMedia*

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 00:45:23 +08:00
Isaac
d2cf720e0a Refactor constructor use sites for types 180-189 to struct pattern
Refactored constructors:
- JSON types: jsonObjectValue, jsonArray, jsonBool, jsonNumber, jsonObject, jsonString
- Invoice types: invoice, labeledPrice
- Keyboard button types: keyboardButton, keyboardButtonCallback, keyboardButtonUrl, etc.
- Lang pack types: langPackDifference, langPackString, langPackStringPluralized, langPackStringDeleted, langPackLanguage
- Input web file types: inputWebFileLocation, inputWebFileAudioAlbumThumbLocation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 22:27:04 +08:00
Isaac
7013cd9fee Merge branch 'master' into api-refactoring
# Conflicts:
#	submodules/TelegramApi/Sources/Api0.swift
#	submodules/TelegramApi/Sources/Api25.swift
#	submodules/TelegramApi/Sources/Api26.swift
#	submodules/TelegramApi/Sources/Api27.swift
#	submodules/TelegramApi/Sources/Api28.swift
#	submodules/TelegramApi/Sources/Api29.swift
#	submodules/TelegramApi/Sources/Api30.swift
#	submodules/TelegramApi/Sources/Api31.swift
#	submodules/TelegramApi/Sources/Api32.swift
#	submodules/TelegramApi/Sources/Api33.swift
#	submodules/TelegramApi/Sources/Api34.swift
#	submodules/TelegramApi/Sources/Api35.swift
#	submodules/TelegramApi/Sources/Api36.swift
#	submodules/TelegramApi/Sources/Api37.swift
#	submodules/TelegramApi/Sources/Api38.swift
#	submodules/TelegramApi/Sources/Api39.swift
2026-01-17 04:12:49 +08:00
Isaac
59ace446a5 Fix 2026-01-17 02:36:00 +08:00
Isaac
dc29571075 Disable artifacts 2026-01-17 02:34:58 +08:00
Isaac
e0367409f2 Fix context menus 2026-01-17 01:03:38 +08:00
Isaac
1b52877d0b Fix build 2026-01-16 21:48:09 +08:00
Isaac
2fdec84b46 Merge commit 'db93244583' 2026-01-16 21:23:35 +08:00
Isaac
6558d2e265 Various improvements 2026-01-16 21:23:32 +08:00
Mikhail Filimonov
db93244583 update api (rarities, crafted) 2026-01-16 16:20:08 +04:00
Ilya Laktyushin
a1f6f80888 Update API [skip ci] 2026-01-16 15:43:35 +04:00
Isaac
8696bb0c2a Fix constructors 2026-01-16 15:40:50 +08:00
Isaac
e68bdc05ca Refactor Api types 150-179 to use struct-wrapped constructors
- Update pattern matches to use struct-based extraction for inputPeer*,
  inputMedia*, inputReplyTo*, inputSticker*, inputPhoto, inputUser, etc.
- Wrap constructor calls with .init() for struct-wrapped enum cases
- 47 TelegramCore source files modified
- 5 TelegramApi files regenerated with --struct-count=180

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 15:18:11 +08:00
Isaac
33a0d9e62c Refactor Api types 120-149 to use struct-wrapped constructors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 03:00:59 +08:00
Isaac
6b2c0f9c53 Refactor constructor use sites for types 100-119 to struct pattern
Migrated 22 constructors: fileHash, folder, folderPeer, forumTopic,
forumTopicDeleted, foundStory, game, geoPoint, geoPointAddress,
globalPrivacySettings, groupCall, groupCallDiscarded, groupCallDonor,
groupCallMessage, groupCallParticipant, groupCallParticipantVideo,
groupCallParticipantVideoSourceGroup, groupCallStreamChannel,
highScore, importedContact, inlineBotSwitchPM, inlineBotWebView

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 02:41:47 +08:00
Isaac
ac019b15c5 Refactor Api types 90-99 to use struct-wrapped constructors
Types refactored (file-grouped parallel approach):
- encrypted* (Chat, ChatDiscarded, ChatEmpty, ChatRequested, ChatWaiting,
  File, Message, MessageService)
- chatInviteExported
- exported* (ChatlistInvite, ContactToken, MessageLink, StoryLink)
- factCheck

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 02:19:54 +08:00
Isaac
a78b2c0db2 Refactor Api types 70-89 to use struct-wrapped constructors
Types refactored:
- 70-79: contactStatus, dataJSON, dcOption, defaultHistoryTTL, dialog,
  dialogFolder, dialogFilter, dialogFilterChatlist, dialogFilterSuggested,
  dialogPeer, dialogPeerFolder, disallowedGiftsSettings, document, documentEmpty
- 80-89: documentAttribute* (Audio, CustomEmoji, Filename, ImageSize, Sticker, Video),
  draftMessage, draftMessageEmpty, emailVerification* (Apple, Code, Google),
  emailVerifyPurposeLoginSetup, emoji* (Group, GroupGreeting, GroupPremium,
  Keyword, KeywordDeleted, KeywordsDifference, Language, List, Status,
  StatusCollectible), inputEmojiStatusCollectible

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 02:12:20 +08:00
Isaac
02167b9b86 Refactor Api types 65-69 to use struct-wrapped constructors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 01:38:37 +08:00
Isaac
df3b1cddcf Refactor Api types 60-64 to use struct-wrapped constructors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 01:29:09 +08:00
Isaac
dc3d2dc789 Refactor Api types 53-59 to use struct-wrapped constructors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 01:14:05 +08:00
Isaac
68d60d34dc Refactor Api types 43-52 to use struct-wrapped constructors
Also adds -warnings-as-errors to TelegramCore Package.swift

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 00:33:37 +08:00
Isaac
9f757cbf74 Refactor Api types 33-42 to use struct-wrapped constructors
Types refactored:
- BusinessBotRecipients, BusinessBotRights, BusinessChatLink
- BusinessGreetingMessage, BusinessIntro, BusinessLocation
- BusinessRecipients, BusinessWeeklyOpen, BusinessWorkHours, CdnConfig

Updated pattern matching and construction sites in TelegramCore.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 19:41:25 +08:00
Isaac
375c1bc3e0 Refactor Api types 23-32 to use struct-wrapped constructors
Types refactored:
- BotCommandScope*, BotInfo, BotInlineMessage*, BotInlineResult
- BotMenuButton, BotPreviewMedia, BotVerification, BotVerifierSettings
- BusinessAwayMessage, BusinessAwayMessageScheduleCustom

Updated pattern matching and construction sites in TelegramCore.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 19:31:50 +08:00
Isaac
a526aee73e Refactor Api types 13-22 to use struct-wrapped constructors
Types refactored:
- AvailableReaction, BankCardOpenUrl, Birthday, Boost
- BotApp, BotAppSettings, BotBusinessConnection, BotCommand

Updated pattern matching and construction sites in TelegramCore.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 19:19:24 +08:00
Isaac
94cb9d3228 Refactor Api types 3-12 to use struct-wrapped constructors
Types refactored:
- AttachMenuBotIconColor, AttachMenuBots, AttachMenuBotsBot
- AuctionBidLevel, Authorization, AutoDownloadSettings
- AutoSaveException, AutoSaveSettings, AvailableEffect

Updated pattern matching and construction sites in TelegramCore.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 19:11:04 +08:00
Isaac
138cc9f51e Refactor Api types 0-2 to use struct-wrapped constructors
- AccountDaysTTL, AttachMenuBot, AttachMenuBotIcon now use Cons_* classes
- Updated use sites in TelegramCore to destructure from wrapper
- Generated Api files with stub functions for faster compilation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 18:59:46 +08:00
Isaac
a14a8ecf00 Add temp gitignore 2026-01-15 16:55:41 +08:00
Isaac
e02a39331c Trigger build 2026-01-14 23:36:45 +04:00
Isaac
9b68f361e4 Revert "Upgrade recaptcha"
This reverts commit b0f2d0220e.
2026-01-14 22:58:46 +04:00
Isaac
6c0f54a688 Fix url parsing 2026-01-14 22:58:31 +04:00
Isaac
2db08cde89 Glass 2026-01-13 19:21:49 +04:00
Isaac
3773777141 Bump version 2026-01-11 21:35:04 +04:00
Isaac
76c3cb47c3 Merge branch 'temp-12' 2026-01-11 21:02:28 +04:00
Isaac
0f5a019f04 Glass updates 2026-01-11 21:01:45 +04:00
Ilya Laktyushin
4e2c4631dd Fix 2026-01-09 17:27:33 +04:00
Ilya Laktyushin
e68756a7d5 Fix 2026-01-09 17:23:45 +04:00
Ilya Laktyushin
e89a069016 Fix build 2026-01-08 20:15:21 +04:00
Ilya Laktyushin
584af12c27 Bump version 2026-01-08 19:23:17 +04:00
Ilya Laktyushin
4463c7f26c Various fixes 2026-01-08 19:22:48 +04:00
Ilya Laktyushin
d70b31f8bc Fix build 2026-01-08 19:21:29 +04:00
Ilya Laktyushin
dfbab14a67 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-08 18:46:45 +04:00
Ilya Laktyushin
dbd5dd9912 Fix auction gift resale 2026-01-08 18:46:37 +04:00
Mikhail Filimonov
f3090d3b91 failed craft 2026-01-08 15:38:27 +04:00
Mikhail Filimonov
fc78790b24 Merge branch 'craft' 2026-01-08 15:27:58 +04:00
Mikhail Filimonov
b2972e3f59 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-08 15:27:53 +04:00
Mikhail Filimonov
35cfd6d0d2 craft 2026-01-08 15:27:38 +04:00
Ilya Laktyushin
93bb85b3b6 Various fixes 2026-01-08 00:47:32 +04:00
Ilya Laktyushin
21995065d6 Various fixes 2026-01-08 00:20:56 +04:00
Mikhail Filimonov
6b82d49945 - macos related 2026-01-07 21:35:27 +04:00
Ilya Laktyushin
f89ad5cd72 Fix emoji packs display on error 2026-01-07 15:10:05 +04:00
Ilya Laktyushin
937eae7081 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-06 23:13:11 +04:00
Ilya Laktyushin
ec53c5d115 Clean up 2026-01-06 23:12:38 +04:00
Isaac
1425fd8973 Fix tinted dark panel control color 2026-01-07 02:56:15 +08:00
Isaac
3e5547ef28 Fix background mask 2026-01-07 02:01:47 +08:00
Isaac
a200a427e6 Fix build 2026-01-06 23:25:17 +08:00
Isaac
abc135f257 Fix botforum topic removal 2026-01-06 23:22:18 +08:00
Isaac
9cfcc5d8ba UI improvements 2026-01-06 22:54:01 +08:00
Isaac
62a431b12c Merge commit '2a5b83429a' 2026-01-06 21:20:19 +08:00
Isaac
3a1d85784e Various improvements 2026-01-06 21:20:16 +08:00
Ilya Laktyushin
2a5b83429a Various fixes 2026-01-06 14:20:06 +04:00
Ilya Laktyushin
bceed091d8 Fix 2026-01-05 15:49:24 +04:00
Ilya Laktyushin
179be956d0 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2026-01-05 15:23:22 +04:00
Ilya Laktyushin
c654227b83 Various fixes 2026-01-05 15:14:19 +04:00
Isaac
a9cf09a673 Fix gift pane 2026-01-04 10:40:01 +08:00
Isaac
cb7d6f8593 Fix gift pane 2026-01-03 01:05:13 +08:00
Isaac
26d845520b Update rules_apple 2026-01-02 23:15:24 +08:00
Isaac
9300ec2db0 Merge commit 'c93e02a58e' 2026-01-02 23:11:57 +08:00
Isaac
87187bd414 Fixes 2026-01-02 23:11:51 +08:00
Ilya Laktyushin
c93e02a58e Various fixes 2026-01-02 17:48:36 +04:00
Ilya Laktyushin
b80fb9acc9 Various fixes 2026-01-02 16:57:34 +04:00
Ilya Laktyushin
da23f7798d Various fixes 2026-01-02 16:51:41 +04:00
Ilya Laktyushin
abb6abdf94 Fix wearable gifts list 2026-01-01 17:21:10 +04:00
Ilya Laktyushin
80f4410f42 Various fixes 2026-01-01 05:22:16 +04:00
Ilya Laktyushin
b04fd532da Various fixes 2025-12-31 16:51:40 +04:00
Ilya Laktyushin
3defa0121e Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-30 23:41:43 +04:00
Ilya Laktyushin
7cd159bda4 Various fixes 2025-12-30 23:41:35 +04:00
Isaac
5e0f332efb Update 2025-12-30 22:55:11 +08:00
Isaac
0b2f7bbe61 Fix pattern wallpaper isDark detection 2025-12-30 22:25:20 +08:00
Isaac
e4bb16bd53 Fix peer selection controller 2025-12-30 21:46:18 +08:00
Isaac
79142834fb Updates 2025-12-30 21:18:43 +08:00
Isaac
38053570c9 Wallpaper background color calculation 2025-12-30 18:02:58 +08:00
Isaac
4e45d5f27c Built time 2025-12-30 15:16:10 +08:00
Isaac
1c91b37b6f Merge commit 'eba3c17f69' 2025-12-30 14:04:36 +08:00
Isaac
8a406c86a5 Update color 2025-12-30 13:58:23 +08:00
Ilya Laktyushin
eba3c17f69 Trigger build 2025-12-30 01:44:09 +04:00
Ilya Laktyushin
839efdd5cf Various fixes 2025-12-30 00:50:56 +04:00
Ilya Laktyushin
fd27c39a9a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-29 22:43:07 +04:00
Ilya Laktyushin
fdc66446ce Various improvements 2025-12-29 22:42:58 +04:00
Isaac
45e10e98a3 Merge commit 'e7a4815ec3'
# Conflicts:
#	submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftOfferAlertController.swift
#	submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift
#	versions.json
2025-12-30 02:07:00 +08:00
Isaac
b6fcc88f67 Fixes 2025-12-30 02:05:00 +08:00
Isaac
bae3a1234b Update 2025-12-30 00:38:32 +08:00
Isaac
c9863f26f1 Fix attachment icon 2025-12-30 00:31:11 +08:00
Isaac
844da497fb Various fixes 2025-12-30 00:18:36 +08:00
Isaac
a906dc0bb4 Merge commit 'efda15d41b' 2025-12-29 23:03:24 +08:00
Isaac
af7f91163b Fix background 2025-12-29 23:03:10 +08:00
Ilya Laktyushin
efda15d41b Various fixes 2025-12-29 17:04:55 +04:00
Ilya Laktyushin
49398ef9e0 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-29 15:46:23 +04:00
Ilya Laktyushin
0d82876099 Various fixes 2025-12-29 15:46:09 +04:00
Isaac
61108c162b Saved messages search 2025-12-29 19:05:22 +08:00
Ilya Laktyushin
150dfa934d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-29 10:05:59 +04:00
Ilya Laktyushin
966182bd2f Various improvements 2025-12-29 10:05:51 +04:00
Isaac
f2cbf6b609 Update 2025-12-29 03:23:06 +08:00
Isaac
c75df9501e Fix profile insets 2025-12-29 02:26:40 +08:00
Isaac
c3c82f4e9b Fixes 2025-12-29 02:20:50 +08:00
Isaac
d2456c2a6b Merge commit '2e95fa0a08' 2025-12-28 22:39:38 +08:00
Isaac
05b667797d Glass 2025-12-28 22:39:34 +08:00
Ilya Laktyushin
2e95fa0a08 Fix build 2025-12-27 22:22:49 +04:00
Ilya Laktyushin
54ec998186 Various fixes 2025-12-27 21:50:29 +04:00
Isaac
9d6518a738 Temp fixes 2025-12-27 16:34:51 +08:00
Isaac
3f87ee8321 Fix buttons 2025-12-26 23:15:01 +08:00
Isaac
f4f3ed1d54 Adjust colors 2025-12-26 22:27:03 +08:00
Isaac
602708649d Fix search members style 2025-12-26 21:47:25 +08:00
Isaac
d12103c553 Fix touches 2025-12-26 21:44:17 +08:00
Isaac
816632ae38 Update 2025-12-26 21:42:12 +08:00
Isaac
216a49c71e Fix build 2025-12-26 20:56:45 +08:00
Isaac
9dbfa24ad5 Fix build 2025-12-26 20:50:11 +08:00
Isaac
586f5039f1 Merge commit '974a2f6caa'
# Conflicts:
#	submodules/TelegramUI/Components/GlobalControlPanelsContext/Sources/GlobalControlPanelsContext.swift
#	submodules/TelegramUI/Components/LiquidLens/Sources/LiquidLensView.swift
#	submodules/TelegramUI/Components/TranslateHeaderPanelComponent/Sources/ChatTranslationPanelNode.swift
#	submodules/TelegramUI/Sources/ChatControllerNode.swift
2025-12-26 20:34:31 +08:00
Isaac
40361ce6a6 Glass 2025-12-26 20:32:20 +08:00
Isaac
4a13c3830a Glass 2025-12-26 20:29:30 +08:00
Isaac
7ed08c0141 Build system 2025-12-26 19:42:31 +08:00
Ilya Laktyushin
974a2f6caa Various improvements 2025-12-26 13:34:23 +04:00
Ilya Laktyushin
0f53130216 Various improvements 2025-12-25 01:00:37 +04:00
Ilya Laktyushin
57cdc60862 Cocoon info 2025-12-23 23:54:51 +04:00
Ilya Laktyushin
f7f3b92fa7 Various improvements 2025-12-23 22:25:44 +04:00
Ilya Laktyushin
2bba31bcdf Alerts 2025-12-22 23:28:04 +04:00
Ilya Laktyushin
59f2f7389a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-22 00:48:28 +04:00
Ilya Laktyushin
2edce5ebf2 Alerts 2025-12-22 00:19:11 +04:00
Isaac
25d13682ba Update API 2025-12-21 00:28:54 +08:00
Isaac
3bce334dc1 Update API 2025-12-21 00:02:44 +08:00
Isaac
77ad4b15a5 Fix API 2025-12-20 04:00:18 +08:00
Isaac
b40513ac37 Glass 2025-12-20 03:24:48 +08:00
Isaac
4c6b273fe1 Merge commit 'ef5b8537e0'
# Conflicts:
#	submodules/TelegramUI/Components/LiquidLens/Sources/LiquidLensView.swift
#	submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift
2025-12-20 03:05:26 +08:00
Isaac
3486393f99 Glass 2025-12-20 03:02:08 +08:00
Ilya Laktyushin
ef5b8537e0 Various fixes 2025-12-17 15:54:44 +04:00
Ilya Laktyushin
c367c8eb8a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-17 14:32:03 +04:00
Ilya Laktyushin
1a1f08de64 Various improvements 2025-12-17 14:31:54 +04:00
Peter Iakovlev
28abb4cd3d Force build 2025-12-16 18:21:59 +00:00
Ilya Laktyushin
28d4e1e171 Various improvements 2025-12-16 20:05:44 +04:00
Isaac
0ccec4b6b6 WIP 2025-12-16 20:55:47 +08:00
Ilya Laktyushin
f781dbd25f Update API 2025-12-15 15:45:34 +04:00
Isaac
fbebd03f88 Update 2025-12-15 03:58:05 +08:00
Isaac
6b63a53322 Update CI 2025-12-15 03:49:42 +08:00
Isaac
c49fe34c43 Fix color 2025-12-15 03:49:32 +08:00
Isaac
b2af252d11 Legacy glass 2025-12-15 02:41:00 +08:00
Isaac
b90e17064e Update build system 2025-12-15 02:37:57 +08:00
Isaac
903ecdc8f6 Glass 2025-12-13 03:08:56 +08:00
Isaac
5561667d04 Glass 2025-12-13 02:45:39 +08:00
Isaac
6d42458fe7 Merge commit 'fdf8fef76c' 2025-12-13 00:04:46 +08:00
Isaac
b0f2d0220e Upgrade recaptcha 2025-12-13 00:04:41 +08:00
Isaac
a63c90aa00 Glass 2025-12-12 23:58:00 +08:00
Mikhail Filimonov
fdf8fef76c isRefunded for savedGift 2025-12-12 15:47:04 +04:00
Ilya Laktyushin
e7a4815ec3 Use system photos picker when no photos access is available 2025-12-12 02:22:52 +04:00
Ilya Laktyushin
8a8b04978d Use system photos picker when no photos access is available 2025-12-12 02:18:52 +04:00
Ilya Laktyushin
d476b2ecf8 Various fixes 2025-12-11 23:23:42 +04:00
Ilya Laktyushin
9793dc8718 Various fixes 2025-12-11 23:14:24 +04:00
Ilya Laktyushin
2ce14895bf Bump version 2025-12-11 21:36:54 +04:00
Ilya Laktyushin
aeb2e35d42 Various fixes 2025-12-11 21:36:25 +04:00
Ilya Laktyushin
245dacbaa6 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-11 21:34:30 +04:00
Ilya Laktyushin
6a6714baef Various fixes 2025-12-11 21:32:44 +04:00
Isaac
3982aa3f9e Merge commit '10a429b944' into experimental-3 2025-12-10 00:17:02 +08:00
Isaac
a62aec40fe Bump version 2025-12-10 00:16:56 +08:00
Isaac
0c3530d8a8 Glass 2025-12-10 00:16:36 +08:00
Ilya Laktyushin
10a429b944 Update device list 2025-12-09 01:28:37 +04:00
Ilya Laktyushin
95b074de14 Various fixes 2025-12-08 19:08:32 +04:00
Ilya Laktyushin
03afc1343c Various fixes 2025-12-08 16:23:31 +04:00
Ilya Laktyushin
f7dc38b52e Various fixes 2025-12-08 00:07:54 +04:00
Ilya Laktyushin
ce5e83b53b Fix 2025-12-06 02:31:11 +04:00
Ilya Laktyushin
68a75ff7fc Merge commit '7621e2f8de' into beta 2025-12-06 02:17:48 +04:00
Ilya Laktyushin
7621e2f8de Various fixes 2025-12-06 02:17:23 +04:00
Ilya Laktyushin
13a2fdf5c8 Various fixes 2025-12-06 01:43:15 +04:00
Ilya Laktyushin
a3b1dd5c9b Merge commit '3b1b668fe4' into beta 2025-12-06 00:10:55 +04:00
Ilya Laktyushin
3b1b668fe4 Fix 2025-12-06 00:04:28 +04:00
Ilya Laktyushin
595eeb73cf Bump version 2025-12-05 23:52:22 +04:00
Ilya Laktyushin
4c085af0bc Merge commit '7facd8aaf0' into beta 2025-12-05 23:51:39 +04:00
Ilya Laktyushin
7facd8aaf0 Fix 2025-12-05 23:50:21 +04:00
Ilya Laktyushin
e84fc33aa9 Fix 2025-12-05 23:46:46 +04:00
Isaac
dca1f06e91 Update 2025-12-06 01:42:16 +08:00
Isaac
1ee7268488 Glass 2025-12-06 01:28:06 +08:00
Ilya Laktyushin
06cb1ece50 Various improvements 2025-12-05 18:41:50 +04:00
Isaac
1969b1b280 Merge commit '6db5077642' into experimental-3 2025-12-05 14:35:56 +08:00
Ilya Laktyushin
6db5077642 Various fixes 2025-12-05 02:26:17 +04:00
Ilya Laktyushin
f97eca0172 Merge commit '2cb0c7f147' into beta 2025-12-04 08:01:56 +04:00
Ilya Laktyushin
2cb0c7f147 Various improvements 2025-12-04 07:56:44 +04:00
Ilya Laktyushin
4660f67271 Update localization 2025-12-03 22:25:26 +04:00
Ilya Laktyushin
52e7a175c4 Show generic gift title and number if available 2025-12-03 18:15:27 +04:00
Ilya Laktyushin
f21f9b0421 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-03 17:59:32 +04:00
Ilya Laktyushin
6a09d2e4e6 Various improvements 2025-12-03 17:59:09 +04:00
Mikhail Filimonov
6a0763f8fc Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-03 11:22:28 +04:00
Isaac
55a5745149 Bump version 2025-12-03 04:36:32 +08:00
Isaac
a90b1e865f Update CI 2025-12-03 04:27:14 +08:00
Isaac
f6ba92766b Glass 2025-12-03 04:21:09 +08:00
Ilya Laktyushin
0044bde566 Various improvements 2025-12-02 23:02:12 +04:00
Ilya Laktyushin
5d9d21e0dc Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-02 19:23:25 +04:00
Ilya Laktyushin
ecb12a784e Various improvements 2025-12-02 19:22:06 +04:00
Isaac
3b02aeae9d Update localization 2025-12-02 22:15:52 +08:00
Isaac
bd2819e749 Merge branch 'master' into glass-26
# Conflicts:
#	submodules/TelegramUI/BUILD
2025-12-02 20:52:27 +08:00
Isaac
62d29ee551 Passkeys 2025-12-02 19:59:39 +08:00
Isaac
2e279e8fd3 Temp 2025-12-02 19:30:48 +08:00
Isaac
b1a1d932a8 Update 2025-12-02 19:17:15 +08:00
Mikhail Filimonov
e2b49cc712 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-02 14:29:35 +04:00
Mikhail Filimonov
52adb303f1 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-02 14:29:02 +04:00
Ilya Laktyushin
0ac2602f7f Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-02 14:28:56 +04:00
Ilya Laktyushin
653ee1b299 Update API 2025-12-02 14:28:47 +04:00
Isaac
42f10b4fed Merge branch 'master' into glass-26 2025-12-02 17:30:38 +08:00
Isaac
8047d0fa2a Revert "Revert "[WIP] Tab bar and search""
This reverts commit 89f96e28b3.
2025-12-02 17:30:30 +08:00
Isaac
6dba110767 Merge commit 'b308f42396' 2025-12-02 17:26:57 +08:00
Isaac
cf5584e02f Collapse sibling options 2025-12-02 17:20:43 +08:00
Mikhail Filimonov
231b2d320b Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-02 13:10:09 +04:00
Ilya Laktyushin
b308f42396 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-02 13:02:44 +04:00
Ilya Laktyushin
50fe471cb6 Show extended auction round info 2025-12-02 13:02:06 +04:00
Isaac
765aa49f41 Passkeys 2025-12-02 17:01:07 +08:00
Ilya Laktyushin
4a571de626 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-02 12:36:13 +04:00
Ilya Laktyushin
5046aab8ff Update API 2025-12-02 12:36:05 +04:00
Mikhail Filimonov
ac2ba992ff Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-02 09:31:15 +04:00
Isaac
2967648b2b Update icons 2025-12-02 01:51:40 +08:00
Isaac
8f1c9019be Passkeys 2025-12-02 01:43:04 +08:00
Ilya Laktyushin
95526c1c4d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-12-01 19:55:44 +04:00
Ilya Laktyushin
6bc1fe1939 Various improvements 2025-12-01 19:54:58 +04:00
Isaac
d8b0878046 Update 2025-12-01 22:29:44 +08:00
Isaac
89f96e28b3 Revert "[WIP] Tab bar and search"
This reverts commit 5e26b246bd.
2025-12-01 22:18:17 +08:00
Isaac
cd436e8210 Glass 2025-12-01 22:13:33 +08:00
Isaac
557af859bb build-system 2025-12-01 22:13:16 +08:00
Mikhail Filimonov
31d1b0ac63 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-28 09:31:35 +04:00
Ilya Laktyushin
b04eee8289 Update API [skip ci] 2025-11-27 19:55:24 +04:00
Mikhail Filimonov
2caa983785 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-27 15:41:40 +04:00
Mikhail Filimonov
a9511e7c57 improvements 2025-11-26 22:49:31 +04:00
Isaac
0055396d4d Update 2025-11-26 23:05:30 +08:00
Isaac
ddcea95734 Update API [skip ci] 2025-11-25 23:05:01 +08:00
Isaac
6e6b5b571e Merge remote-tracking branch 'refs/remotes/origin/master' 2025-11-24 00:25:27 +08:00
Isaac
9c609350aa Update settings 2025-11-24 00:25:24 +08:00
Ilya Laktyushin
5761556de6 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-23 11:04:22 +01:00
Ilya Laktyushin
1496c81082 Various improvements 2025-11-23 11:04:16 +01:00
Isaac
cfd7a5242a Merge commit '0f994c4f62' 2025-11-22 03:33:43 +08:00
Isaac
d86362c6e7 Merge commit 'b83250ac63' 2025-11-22 03:17:30 +08:00
Isaac
5e26b246bd [WIP] Tab bar and search 2025-11-22 03:17:19 +08:00
Isaac
dd8040f00c Update build system 2025-11-22 03:17:01 +08:00
Mikhail Filimonov
0f994c4f62 Merge branch 'macos-12.2-release' 2025-11-20 16:52:58 +04:00
Ilya Laktyushin
d5a952172a Various improvements 2025-11-20 12:08:19 +01:00
Mikhail Filimonov
b53b2545fa fix: deleteAllMessages in monoforum 2025-11-19 12:48:36 +04:00
Ilya Laktyushin
9f5efde107 Fix 2025-11-18 22:08:47 +04:00
Ilya Laktyushin
b83250ac63 Fix 2025-11-18 22:08:06 +04:00
Ilya Laktyushin
8dafa7003f Various fixes 2025-11-18 21:35:40 +04:00
Ilya Laktyushin
af04c63038 Various fixes 2025-11-18 21:35:09 +04:00
Ilya Laktyushin
887d1063e1 Various fixes 2025-11-18 20:48:38 +04:00
Ilya Laktyushin
f0de386e91 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-18 20:44:33 +04:00
Ilya Laktyushin
7463fb9eda Various fixes 2025-11-18 20:44:26 +04:00
Isaac
326fe35598 Bump version 2025-11-19 00:08:28 +08:00
Isaac
c67ed1a009 Merge commit '183bc34f79' 2025-11-19 00:08:05 +08:00
Isaac
95ecb88025 Passkeys 2025-11-19 00:07:50 +08:00
Isaac
0371407380 Custom tab bar 2025-11-19 00:04:06 +08:00
Isaac
abc6997985 Build system updates 2025-11-19 00:03:25 +08:00
Ilya Laktyushin
8dc582ac0f Merge commit '183bc34f79' into beta 2025-11-18 18:24:56 +04:00
Ilya Laktyushin
183bc34f79 Various fixes 2025-11-18 17:13:27 +04:00
Ilya Laktyushin
d6cb84e878 Merge commit '8a46bdffce' into beta 2025-11-17 21:49:59 +04:00
Ilya Laktyushin
8a46bdffce Various improvements 2025-11-17 21:49:36 +04:00
Isaac
5a2d74d53d Merge commit '8f33585114' 2025-11-17 23:16:47 +08:00
Isaac
49ae84062b Update build system 2025-11-17 23:16:39 +08:00
Ilya Laktyushin
8f33585114 Various improvements 2025-11-17 03:15:36 +04:00
Ilya Laktyushin
c813a76e9a Fix 2025-11-16 14:46:01 +04:00
Isaac
a2f71562f6 Merge branch 'beta' 2025-11-16 13:53:38 +08:00
Isaac
00858ee5f4 Merge commit 'd8efc7c865' into beta 2025-11-16 13:53:24 +08:00
Isaac
0859e8594c Merge commit '74b761c53f' into beta 2025-11-16 13:53:18 +08:00
Ilya Laktyushin
74b761c53f Various improvements 2025-11-16 01:22:06 +04:00
Ilya Laktyushin
eb7f575bda Fix build 2025-11-15 22:34:08 +04:00
Ilya Laktyushin
3a4031b5c5 Various fixes 2025-11-15 22:31:03 +04:00
Ilya Laktyushin
d8efc7c865 Merge commit 'e52134993a' into beta 2025-11-15 20:48:20 +04:00
Ilya Laktyushin
e52134993a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-15 20:47:46 +04:00
Ilya Laktyushin
c7556cedf9 Remove story live mode in groups 2025-11-15 20:47:37 +04:00
Isaac
da08c69da2 Fix typo
(cherry picked from commit 53966b99a8)
2025-11-16 00:26:20 +08:00
Isaac
53966b99a8 Fix typo 2025-11-16 00:24:00 +08:00
Isaac
49a060585f Merge commit '0a5c043896' 2025-11-15 18:31:35 +08:00
Isaac
1f841d4c43 Fix main thread UI 2025-11-15 18:31:32 +08:00
Mikhail Filimonov
0a5c043896 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-15 10:58:58 +04:00
Ilya Laktyushin
5390369691 Bump version 2025-11-15 03:21:40 +04:00
Ilya Laktyushin
29fb65d33d Various improvements 2025-11-15 02:33:37 +04:00
Ilya Laktyushin
a443df81dd Various improvements 2025-11-15 02:12:21 +04:00
Ilya Laktyushin
82addaa434 Various improvements 2025-11-15 01:14:50 +04:00
Isaac
d33fd57200 Merge commit '1c3b749ede' 2025-11-15 02:55:45 +08:00
Isaac
c57aa07d7d Fit more text 2025-11-15 02:55:41 +08:00
Ilya Laktyushin
1c3b749ede Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-14 18:31:54 +04:00
Ilya Laktyushin
48e873c840 Various fixes 2025-11-14 18:31:45 +04:00
Isaac
a39987a8cd Unbump version 2025-11-14 22:04:39 +08:00
Isaac
e3bf4697b7 Stories 2025-11-14 21:46:43 +08:00
Isaac
888b12405b Filter consecutive newlines 2025-11-14 21:19:08 +08:00
Isaac
09ca26be9b Merge commit 'a8c6314d48' 2025-11-14 21:00:41 +08:00
Isaac
35235b8e3a Add story pip button 2025-11-14 21:00:27 +08:00
Ilya Laktyushin
a8c6314d48 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-14 16:52:31 +04:00
Isaac
ac65d7f443 Stories 2025-11-14 20:50:02 +08:00
Ilya Laktyushin
72eaf9f83b Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-14 16:45:57 +04:00
Ilya Laktyushin
6a030345d0 Save privacy on live stream start 2025-11-14 16:45:48 +04:00
Isaac
63055d7ba8 Merge branch 'beta' 2025-11-14 20:30:49 +08:00
Isaac
a8f09233ba Updates 2025-11-14 20:30:25 +08:00
Ilya Laktyushin
38eaa9085a Fix 2025-11-14 16:09:30 +04:00
Ilya Laktyushin
807fa893c5 Various fixes 2025-11-14 15:02:49 +04:00
Ilya Laktyushin
493e91f60d Fix 2025-11-14 14:39:39 +04:00
Ilya Laktyushin
90b6f2427f Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-14 14:35:52 +04:00
Ilya Laktyushin
09bbf8df9c Various fixes 2025-11-14 14:35:42 +04:00
Isaac
95b0889361 Bump version 2025-11-14 18:27:09 +08:00
Isaac
4de499b88a Update 2025-11-14 17:45:49 +08:00
Isaac
5f1eafa0ce Merge commit 'c0ae0f8a42' 2025-11-14 17:27:40 +08:00
Isaac
4d184eb9fa Fix stars settings 2025-11-14 17:27:08 +08:00
Ilya Laktyushin
c0ae0f8a42 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-14 13:19:42 +04:00
Ilya Laktyushin
7e2d79adfc Fix 2025-11-14 13:19:34 +04:00
Isaac
cbab90d49c Allow send messages when admin 2025-11-14 17:07:28 +08:00
Isaac
989e1b4368 Fix live stream settings 2025-11-14 17:06:12 +08:00
Isaac
a05e19e745 Merge commit '0e1b60be24' 2025-11-14 16:50:04 +08:00
Isaac
e56c3451c0 Fix 2025-11-14 16:49:51 +08:00
Ilya Laktyushin
0e1b60be24 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-14 12:48:06 +04:00
Ilya Laktyushin
f91fbff773 Various fixes 2025-11-14 12:47:55 +04:00
Isaac
441b4ccc9f Fix reaction stream layout 2025-11-14 16:37:40 +08:00
Isaac
507ff0555b Merge commit '9d34773d1c' 2025-11-14 16:05:38 +08:00
Isaac
c2f2744401 Don't display send as when there is only one peer 2025-11-14 16:05:27 +08:00
Mikhail Filimonov
2a35678e2b Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-14 11:01:26 +04:00
Mikhail Filimonov
a8d4de1224 - auctions, small fix 2025-11-14 11:01:16 +04:00
Ilya Laktyushin
9d34773d1c Merge commit 'cbf23d0df5' into beta 2025-11-14 02:11:38 +04:00
Ilya Laktyushin
cbf23d0df5 Various fixes 2025-11-14 02:08:00 +04:00
Ilya Laktyushin
1d351a0547 Fix localization 2025-11-14 01:38:28 +04:00
Ilya Laktyushin
301f04fd27 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-14 01:36:32 +04:00
Ilya Laktyushin
4c89870f2d Various fixes 2025-11-14 01:30:23 +04:00
Isaac
1ef464086b Merge commit '87035b30ea' 2025-11-14 05:25:21 +08:00
Isaac
70a0f01951 Fix view once 2025-11-14 05:25:18 +08:00
Ilya Laktyushin
87035b30ea Various fixes 2025-11-14 01:07:43 +04:00
Ilya Laktyushin
7f696814ff Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-14 00:20:09 +04:00
Ilya Laktyushin
e5a004f67a Various fixes 2025-11-14 00:19:58 +04:00
Isaac
08ac8fa27f Fix story streaming 2025-11-14 04:07:17 +08:00
Isaac
cce8161001 Merge remote-tracking branch 'refs/remotes/origin/master' 2025-11-14 03:45:06 +08:00
Isaac
22e764278a Stories 2025-11-14 03:44:55 +08:00
Ilya Laktyushin
14c56127fa Various fixes 2025-11-13 23:39:59 +04:00
Ilya Laktyushin
008a1a09a7 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-13 22:40:22 +04:00
Ilya Laktyushin
ee50fdcd14 Various fixes 2025-11-13 22:40:12 +04:00
Isaac
a16f71d336 Merge commit '09c12f964b' 2025-11-14 02:11:44 +08:00
Isaac
c37c6fd005 Fix story cube animation 2025-11-14 02:11:41 +08:00
Ilya Laktyushin
09c12f964b Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-13 22:07:08 +04:00
Ilya Laktyushin
5e17b321f8 Various improvements 2025-11-13 22:06:24 +04:00
Isaac
cebadbbf3d Stories 2025-11-14 01:34:10 +08:00
Isaac
74e1d22de4 Merge commit 'd574fb7a11' 2025-11-13 23:44:26 +08:00
Isaac
0995e5ebcb Stories 2025-11-13 23:44:23 +08:00
Ilya Laktyushin
d574fb7a11 Various fixes 2025-11-13 16:10:30 +04:00
Ilya Laktyushin
62157e92ae Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-13 15:20:24 +04:00
Ilya Laktyushin
e9a3e599a1 Various improvements 2025-11-13 15:16:41 +04:00
Isaac
22ba19029e Merge commit '87baa1b655' 2025-11-13 18:56:57 +08:00
Isaac
ab3d486026 Stories 2025-11-13 18:56:38 +08:00
Mikhail Filimonov
87baa1b655 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-13 11:25:50 +04:00
Mikhail Filimonov
2f66d9931c auction is active 2025-11-13 11:25:42 +04:00
Ilya Laktyushin
3886b847ae Various improvements 2025-11-13 08:27:11 +04:00
Ilya Laktyushin
9527b2d8be Various improvements 2025-11-13 07:18:15 +04:00
Ilya Laktyushin
29b24d9d57 Various improvements 2025-11-13 01:29:20 +04:00
Ilya Laktyushin
c6acd92aed Fix iPad camera 2025-11-12 23:04:30 +04:00
Ilya Laktyushin
1712a00910 Fix 2025-11-12 22:09:57 +04:00
Ilya Laktyushin
cd3942882d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-12 22:06:47 +04:00
Ilya Laktyushin
e680691988 Update API 2025-11-12 22:06:23 +04:00
Isaac
e8fe2b0042 Merge commit '1be0aaef7c' 2025-11-13 00:28:23 +08:00
Isaac
789f9e29c9 Stories 2025-11-13 00:25:29 +08:00
Ilya Laktyushin
1be0aaef7c Various improvements 2025-11-12 19:43:42 +04:00
Ilya Laktyushin
b0f4ca9ad9 Various improvements 2025-11-12 18:41:57 +04:00
Ilya Laktyushin
bdcc80e649 Various improvements 2025-11-12 18:20:38 +04:00
Ilya Laktyushin
ac28ed9d74 Various improvements 2025-11-12 17:47:34 +04:00
Ilya Laktyushin
99840de8d7 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-12 04:47:28 +04:00
Ilya Laktyushin
412e02ef00 Gift auctions 2025-11-12 04:46:02 +04:00
Isaac
f2f1f0db35 Fix glass 2025-11-12 01:43:59 +08:00
Isaac
9fce079880 Fix 2025-11-12 01:23:36 +08:00
Isaac
dff6e560d2 Updates 2025-11-11 23:53:59 +08:00
Isaac
858e00c991 Various improvements 2025-11-11 21:58:05 +08:00
Isaac
7acf2b0b41 Forum improvements 2025-11-11 20:05:29 +08:00
Isaac
89ce010de2 Fix panel while live chat is loading 2025-11-11 18:36:04 +08:00
Isaac
9eddffb694 Various improvements 2025-11-11 18:29:30 +08:00
Isaac
9f9a6365f1 Remove unnecessary option 2025-11-11 18:22:43 +08:00
Isaac
bd8d1d055f Fix build 2025-11-11 18:19:02 +08:00
Isaac
5c572fd8fe Merge commit '938669e1fa' 2025-11-11 18:07:46 +08:00
Isaac
3d51d83e89 Stories 2025-11-11 18:07:34 +08:00
Mikhail Filimonov
938669e1fa Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-11 14:25:14 +07:00
Mikhail Filimonov
430994d341 - added missing API 2025-11-11 14:24:55 +07:00
Isaac
99cb9d4832 Merge commit 'aba2704dcb' 2025-11-11 13:56:49 +08:00
Isaac
3097309db5 No preload 2025-11-11 13:56:46 +08:00
Ilya Laktyushin
aba2704dcb Update API 2025-11-10 20:26:02 +04:00
Ilya Laktyushin
ea8dc07b23 Update API 2025-11-10 18:58:38 +04:00
Isaac
d05425794c Enforce balance limit 2025-11-10 03:33:58 +08:00
Isaac
9ad4321d00 Update tgcalls 2025-11-10 03:31:36 +08:00
Isaac
4b13bd5c04 Merge commit 'fbf7473892' 2025-11-10 03:25:39 +08:00
Isaac
cd6a593be7 Fix active glass container touch 2025-11-10 03:25:35 +08:00
Isaac
dab0ea96d4 Stories 2025-11-10 02:12:01 +08:00
Ilya Laktyushin
fbf7473892 Various improvements 2025-11-09 20:16:32 +04:00
Ilya Laktyushin
b76c6c9b3c Update API 2025-11-08 23:17:00 +04:00
Isaac
64ab80da02 Merge commit '7b5f9a89b2' 2025-11-07 22:55:15 +08:00
Isaac
4853623813 Stories 2025-11-07 22:54:56 +08:00
Ilya Laktyushin
7b5f9a89b2 Various improvements 2025-11-07 17:46:11 +04:00
Isaac
62e92134e0 Update 2025-11-07 20:39:37 +08:00
Isaac
6ea1d44e94 Stories 2025-11-07 18:59:29 +08:00
Isaac
c3fdcbde88 Merge commit '42e4d4add6' 2025-11-07 18:28:13 +08:00
Isaac
a3b7e1acab Fix custom emoji 2025-11-07 18:28:01 +08:00
Ilya Laktyushin
42e4d4add6 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-07 14:13:46 +04:00
Ilya Laktyushin
22945ebb31 Various improvements 2025-11-07 14:13:09 +04:00
Isaac
4616f0833c Stories 2025-11-07 18:08:34 +08:00
Isaac
a05ef5e022 Merge commit '51ad5a5efa' 2025-11-06 23:17:00 +04:00
Isaac
99430812c1 Stories 2025-11-06 23:16:55 +04:00
Ilya Laktyushin
51ad5a5efa Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-06 13:56:23 +04:00
Ilya Laktyushin
b559663d6a Various improvements 2025-11-06 13:55:58 +04:00
Isaac
6b330351e1 Stories 2025-11-06 12:53:18 +04:00
Isaac
481419ced0 Debug 2025-11-06 00:34:55 +04:00
Isaac
feba38c28b Debug 2025-11-06 00:27:05 +04:00
Isaac
5783d24652 Debug 2025-11-06 00:22:48 +04:00
Isaac
9580e43846 Fix 2025-11-06 00:17:49 +04:00
Isaac
4e9f09e2a1 Debug 2025-11-06 00:06:45 +04:00
Isaac
8ff8bd766b Debug 2025-11-06 00:05:31 +04:00
Isaac
fad96534ce Debug 2025-11-06 00:02:06 +04:00
Isaac
5d46a9c219 Debug ip 2025-11-05 23:57:04 +04:00
Isaac
4ebbbfe71b Merge commit 'bda836f032' 2025-11-05 22:37:57 +04:00
Isaac
a165eab477 Update tgcalls 2025-11-05 22:37:42 +04:00
Isaac
11ed074079 Stories 2025-11-05 22:36:17 +04:00
Ilya Laktyushin
bda836f032 Various improvements 2025-11-05 20:25:07 +04:00
Isaac
16cd9b3c29 Stories 2025-11-04 18:49:43 +04:00
Isaac
23a0b30de0 Merge commit '354bde5af1' 2025-11-04 18:27:22 +04:00
Isaac
07a3a5a2aa Update 2025-11-04 18:27:13 +04:00
Ilya Laktyushin
354bde5af1 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-04 17:40:44 +04:00
Ilya Laktyushin
e7bd31137a Update API 2025-11-04 17:40:19 +04:00
Isaac
b427a8d4ca Stories 2025-11-04 17:26:02 +04:00
Ilya Laktyushin
be8227eba5 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-04 17:11:58 +04:00
Ilya Laktyushin
2b2937a2eb Update API 2025-11-04 17:11:50 +04:00
Isaac
d11fe92d67 Merge commit '0284687897' 2025-11-04 15:32:28 +04:00
Isaac
029654c14a Stories 2025-11-04 15:32:19 +04:00
Ilya Laktyushin
0284687897 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-04 14:48:05 +04:00
Ilya Laktyushin
6f5cd84019 Various improvements 2025-11-04 14:43:17 +04:00
Isaac
ff32f34405 Various improvements 2025-11-04 14:22:43 +04:00
Isaac
3ab4850306 Updates [skip ci] 2025-11-04 11:35:11 +04:00
Ilya Laktyushin
7cf87859a8 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-11-04 01:05:05 +04:00
Ilya Laktyushin
8897deff91 Various improvements 2025-11-04 01:04:57 +04:00
Isaac
e09b241a9b Updates 2025-11-04 00:56:08 +04:00
Isaac
bc5a577994 Merge commit '2f3cf25666' 2025-11-03 14:15:52 +04:00
Isaac
5bc61d614c Update animation 2025-11-03 14:15:49 +04:00
Ilya Laktyushin
2f3cf25666 Various improvements 2025-11-03 03:12:54 +04:00
Isaac
a1c33e1884 Merge commit '0dfcdbeb9c' 2025-10-31 18:23:22 +04:00
Isaac
9397ece5a8 Update 2025-10-31 18:23:12 +04:00
Ilya Laktyushin
0dfcdbeb9c Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-10-31 18:14:22 +04:00
Ilya Laktyushin
4432581c77 Various improvements 2025-10-31 18:13:30 +04:00
Isaac
5145b9e605 Stories 2025-10-31 17:51:37 +04:00
Isaac
0e5337636d Merge commit 'e839427846' 2025-10-31 12:00:39 +04:00
Isaac
7be3a0ce81 Update 2025-10-31 12:00:34 +04:00
Ilya Laktyushin
e839427846 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-10-31 00:07:36 +04:00
Ilya Laktyushin
76757b5f3d Login email setup 2025-10-31 00:07:28 +04:00
Isaac
25b82cf7f4 Trigger build 2025-10-30 22:21:59 +04:00
Isaac
21446a5ba0 Fix build 2025-10-30 22:08:36 +04:00
Isaac
547b2c285f Merge commit '1d139d11bf' 2025-10-30 21:23:36 +04:00
Isaac
8bcbfd7166 Update 2025-10-30 21:23:33 +04:00
Ilya Laktyushin
1d139d11bf Update API 2025-10-30 15:04:58 +04:00
Isaac
7a0c3503a9 Trigger build 2025-10-30 00:11:58 +04:00
Ilya Laktyushin
5ac77b9f31 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-10-29 17:21:34 +04:00
Ilya Laktyushin
5877f2c20d Various improvements 2025-10-29 17:20:36 +04:00
Isaac
1bb50a3b36 Trigger build 2025-10-29 16:46:49 +04:00
Isaac
8dc3fcb2ec Update animation 2025-10-28 18:26:25 +04:00
Isaac
d4d032a47d Fix incoming stars 2025-10-28 17:48:36 +04:00
Isaac
70702914b4 Stories 2025-10-28 16:56:08 +04:00
Isaac
aa59524a09 Stories 2025-10-28 15:44:44 +04:00
Isaac
aa637d96d7 Stories 2025-10-28 12:41:50 +04:00
Isaac
284d963b07 Stories 2025-10-27 01:01:04 +04:00
Isaac
348a176393 Stories 2025-10-27 00:37:42 +04:00
Isaac
84171b89f4 Update 2025-10-27 00:22:14 +04:00
Isaac
d3d1b0ee39 Adjust ci 2025-10-26 22:37:34 +04:00
Isaac
fedc43fec8 Fix live story stats 2025-10-26 22:24:55 +04:00
Isaac
24260d3652 Merge commit 'bc1598bb92' 2025-10-26 22:06:03 +04:00
Isaac
c880397eca Stories 2025-10-26 22:05:58 +04:00
Ilya Laktyushin
bc1598bb92 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-10-24 23:06:35 +04:00
Ilya Laktyushin
3e50a2dd56 Various improvements 2025-10-24 23:06:10 +04:00
Isaac
fcdfd8e00f Updates 2025-10-24 20:09:32 +04:00
Isaac
5633833085 Update 2025-10-24 16:03:43 +04:00
Isaac
1967e1e273 Update 2025-10-24 13:34:55 +04:00
Isaac
eebfe1acae Merge commit '35a285752f' 2025-10-24 11:11:48 +04:00
Isaac
7e473a3872 Update 2025-10-24 11:11:45 +04:00
Ilya Laktyushin
35a285752f Fix corners 2025-10-23 16:42:53 +04:00
Ilya Laktyushin
471822007c Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-10-22 21:12:46 +04:00
Ilya Laktyushin
c014d0b333 Various improvements 2025-10-22 21:12:38 +04:00
Isaac
39db75b4ea Fix tab bar hit box 2025-10-21 21:06:20 +04:00
Isaac
fad4203892 Update 2025-10-21 20:57:40 +04:00
Isaac
118d475e16 Merge commit 'ee059515d0' 2025-10-21 18:28:48 +04:00
Isaac
e44bd4d858 Story updates 2025-10-21 18:28:45 +04:00
Ilya Laktyushin
ee059515d0 Fix build 2025-10-20 23:15:12 +04:00
Ilya Laktyushin
78c9cc422e Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-10-20 22:57:38 +04:00
Ilya Laktyushin
2cb5122bb3 Various improvements 2025-10-20 22:57:29 +04:00
Mikhail Filimonov
ffa620b62b - add contact improments. 2025-10-20 21:04:05 +03:00
Mikhail Filimonov
2751cf54d8 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-10-20 18:43:38 +03:00
Ilya Laktyushin
35c9a5d279 Various improvements 2025-10-20 00:46:26 +04:00
Isaac
bcc1213db2 Update 2025-10-18 02:55:47 +08:00
Isaac
1e87e776ed Bump version 2025-10-18 02:36:06 +08:00
Isaac
abe3a01668 Update 2025-10-18 02:35:58 +08:00
Isaac
0619f73819 Updates 2025-10-18 02:00:35 +08:00
Mikhail Filimonov
280e0b09c8 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-10-17 19:53:33 +04:00
Isaac
216d03f95d Merge commit '85092482f3' 2025-10-17 23:52:31 +08:00
Isaac
7e3abe798f Update 2025-10-17 23:51:58 +08:00
Mikhail Filimonov
3b4297ad7d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-10-17 18:28:25 +04:00
Mikhail Filimonov
d676001557 message time fix 2025-10-17 17:42:46 +04:00
Ilya Laktyushin
85092482f3 Various improvements 2025-10-17 17:01:25 +04:00
Ilya Laktyushin
d58757ca3c Various improvements 2025-10-16 19:19:50 +04:00
Ilya Laktyushin
473b00c2e7 Various improvements 2025-10-16 08:09:30 +04:00
Ilya Laktyushin
0915a42e64 Various improvements 2025-10-16 05:30:06 +04:00
Isaac
babf5cc9d7 Merge commit '73d5152aec' 2025-10-15 17:06:43 +08:00
Isaac
f468cea13c Update API 2025-10-15 17:06:40 +08:00
Ilya Laktyushin
5c68a90cb0 Bump 2025-10-10 23:42:17 +04:00
Ilya Laktyushin
6af750e586 Various fixes 2025-10-10 23:21:46 +04:00
Ilya Laktyushin
73d5152aec Fix 2025-10-10 22:03:17 +04:00
Isaac
751f4801d6 Add mic button bounce 2025-10-11 01:27:14 +08:00
Isaac
6758fa57cc Adjust avatar inset 2025-10-11 01:07:26 +08:00
Isaac
9353cc0ff1 Merge commit '62d881d25b' 2025-10-11 00:56:24 +08:00
Isaac
b9b38e5fbf Various improvements 2025-10-11 00:56:21 +08:00
Ilya Laktyushin
62d881d25b Fix 2025-10-10 02:44:26 +04:00
Isaac
e3ee0126b2 Fix input 2025-10-09 00:06:37 +08:00
Isaac
ddf68a0729 Bump version 2025-10-07 21:56:13 +08:00
Isaac
90c88e4122 Merge commit '5d143f5e75' 2025-10-07 21:55:47 +08:00
Isaac
3fd1ef362c Input updates 2025-10-07 21:55:39 +08:00
Ilya Laktyushin
5d143f5e75 Merge commit '72848d83da' into beta 2025-10-04 21:08:30 +04:00
Ilya Laktyushin
72848d83da Fix 2025-10-04 21:07:56 +04:00
Ilya Laktyushin
04bf598060 Merge commit 'bff39b3f39' into beta 2025-10-04 20:39:53 +04:00
Ilya Laktyushin
bff39b3f39 Fix 2025-10-04 20:16:17 +04:00
Ilya Laktyushin
74d46c2bcb Merge commit '7a2df7750c' into beta 2025-10-04 01:14:19 +04:00
Ilya Laktyushin
7a2df7750c Various fixes 2025-10-04 00:52:36 +04:00
Isaac
c281db9100 Trigger build 2025-10-04 02:34:05 +08:00
Isaac
6ecec86ef8 Update 2025-10-04 02:15:51 +08:00
Isaac
07ab14f625 Updates 2025-10-04 01:52:24 +08:00
Isaac
4b04a6c69e Bounce experiment 2025-10-04 00:44:30 +08:00
Isaac
1ff56084fe Decrease input width a bit 2025-10-03 22:17:55 +08:00
Isaac
a2797c4b49 Fix 2025-10-03 22:05:29 +08:00
Isaac
35d6c16fc5 Update offset 2025-10-03 21:59:12 +08:00
Isaac
891a5c1186 Adjust font 2025-10-03 21:55:24 +08:00
Isaac
9c0f5c0921 Buttons update 2025-10-03 21:54:50 +08:00
Isaac
8e93744c73 Input field improvements 2025-10-03 21:21:19 +08:00
Isaac
67ada2a1bd Partial fix for inline context panel animations 2025-10-03 19:53:05 +08:00
Isaac
3ed35f973b Update text field 2025-10-03 19:35:03 +08:00
Isaac
5ec68c7a5b Fix empty forward 2025-10-03 18:59:41 +08:00
Isaac
6816609a99 Merge commit '2725154111' 2025-10-03 18:47:57 +08:00
Isaac
06936fa06c Text input updates 2025-10-03 18:47:47 +08:00
Ilya Laktyushin
2725154111 Fix typo 2025-10-02 22:51:40 +04:00
Isaac
c962e6f56a Send button update 2025-10-03 02:22:18 +08:00
Isaac
70be4f840f Update localization 2025-10-02 00:48:42 +08:00
Isaac
c02ef75c55 Merge commit '29b266d5ad'
# Conflicts:
#	Telegram/Telegram-iOS/en.lproj/Localizable.strings
#	submodules/AuthorizationUI/BUILD
#	submodules/AuthorizationUI/Sources/AuthorizationSequencePaymentScreen.swift
2025-10-02 00:18:39 +08:00
Isaac
27159968f4 Merge commit 'ba58f0c694' 2025-10-02 00:15:18 +08:00
Isaac
08fae7b3c3 Update 2025-10-02 00:14:52 +08:00
Ilya Laktyushin
ba58f0c694 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-10-01 17:53:15 +04:00
Ilya Laktyushin
6de357d643 Fix rtl in group call messages 2025-10-01 17:52:34 +04:00
Isaac
948a99a143 Input field 2025-10-01 21:07:04 +08:00
Isaac
5efc685585 Merge commit '282b9ccd7e' 2025-10-01 00:10:19 +08:00
Isaac
c2c99edf89 Emoji bottom panel 2025-10-01 00:10:10 +08:00
Ilya Laktyushin
282b9ccd7e Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-30 19:25:46 +04:00
Ilya Laktyushin
09b104fe11 Various fixes 2025-09-30 19:25:15 +04:00
Isaac
5b65b52c61 Update 2025-09-30 22:01:43 +08:00
Isaac
54d2b58eb3 Updates 2025-09-30 21:52:21 +08:00
Isaac
bdca60c3d0 Update 2025-09-30 20:54:54 +08:00
Isaac
4746b8d486 Stickers 2025-09-30 19:09:58 +08:00
Isaac
3bca9ed158 Fix input tint on iOS 18 2025-09-30 17:51:47 +08:00
Isaac
a7385ad068 Update 2025-09-30 17:41:32 +08:00
Isaac
b5e8c8960d Update 2025-09-30 16:13:37 +08:00
Isaac
7364be9057 Merge commit '02181ead9e' 2025-09-30 15:27:11 +08:00
Isaac
0570dbb774 Update 2025-09-30 15:26:59 +08:00
Ilya Laktyushin
02181ead9e Fix frontal camera photo orientation on iPad 2025-09-30 01:15:19 +04:00
Ilya Laktyushin
6e48514c3b Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-29 23:27:21 +04:00
Ilya Laktyushin
ecd495e1d4 Various fixes 2025-09-29 23:27:10 +04:00
Isaac
8c3bfe9890 Fix 2025-09-30 02:09:57 +08:00
Isaac
4f2bfb5d0d Merge commit 'b0b4381f01' 2025-09-30 01:53:17 +08:00
Isaac
5bbc75fc7c Glass debug 2025-09-30 01:53:14 +08:00
Isaac
724b4ccbdf Various improvements 2025-09-30 01:41:27 +08:00
Ilya Laktyushin
b0b4381f01 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-29 21:01:52 +04:00
Ilya Laktyushin
850bd3b84b Various improvements 2025-09-29 21:01:44 +04:00
Isaac
29edd18309 Merge commit '56ea340e8a' 2025-09-30 00:34:29 +08:00
Isaac
a3200c23a5 Adjust colors 2025-09-30 00:34:09 +08:00
Ilya Laktyushin
56ea340e8a Various improvements 2025-09-29 20:07:44 +04:00
Ilya Laktyushin
aa15e6c5fe Various improvements 2025-09-29 10:55:21 +04:00
Ilya Laktyushin
d126717ec1 Various improvements 2025-09-29 06:42:09 +04:00
Ilya Laktyushin
88068f3ccc Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-28 21:34:59 +04:00
Ilya Laktyushin
6af4878504 Various improvements 2025-09-28 21:31:54 +04:00
Isaac
81a02e46af Fix build 2025-09-29 01:25:01 +08:00
Isaac
3fe6791076 Merge commit 'c39b34d430' 2025-09-29 00:52:52 +08:00
Isaac
cfbd75f03d Fix entity inputs 2025-09-29 00:51:42 +08:00
Ilya Laktyushin
c39b34d430 Fix build 2025-09-28 20:15:15 +04:00
Ilya Laktyushin
c7f607865a Various improvements 2025-09-28 20:04:45 +04:00
Isaac
a7ef03e321 Fix build 2025-09-28 19:35:37 +08:00
Isaac
786c0b03ae Merge commit '107436d78c' 2025-09-28 15:01:56 +08:00
Isaac
5728de8df8 Glass 2025-09-28 15:01:52 +08:00
Ilya Laktyushin
107436d78c Fix build 2025-09-28 04:12:25 +04:00
Ilya Laktyushin
9cd5b06592 Various fixes 2025-09-28 03:34:50 +04:00
Ilya Laktyushin
6d59a6394a Various fixes 2025-09-28 03:01:43 +04:00
Ilya Laktyushin
2aa0a8b4a9 Update API 2025-09-27 02:03:07 +04:00
Ilya Laktyushin
92a7157a70 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-27 01:28:34 +04:00
Ilya Laktyushin
4657ac752d Various improvements 2025-09-27 01:27:56 +04:00
Isaac
f5ca87fb23 Fix legacy tab bar position 2025-09-27 01:09:26 +08:00
Isaac
ecfe436a24 Various improvements 2025-09-27 01:01:29 +08:00
Isaac
75722ecbde Fix set default icon 2025-09-27 00:09:05 +08:00
Isaac
c49713e4d1 Fix slowmode indication 2025-09-27 00:00:27 +08:00
Isaac
d2f471bd35 Fix continue recording 2025-09-26 23:55:04 +08:00
Isaac
aa890a14f5 Various improvements 2025-09-26 23:09:24 +08:00
Isaac
282a538372 Adjust tab bar 2025-09-26 21:33:41 +08:00
Isaac
d140a5098b Update colors 2025-09-26 21:06:52 +08:00
Isaac
e3f7405fae Update API 2025-09-26 21:06:43 +08:00
Isaac
8c89dccf39 Update API 2025-09-26 20:05:27 +08:00
Isaac
0f9e64818a Merge commit 'b8bf673c5f' 2025-09-26 19:44:43 +08:00
Isaac
d5d4bad649 Various improvements 2025-09-26 19:44:40 +08:00
Ilya Laktyushin
b8bf673c5f Fix build 2025-09-26 03:31:13 +04:00
Ilya Laktyushin
deb549bd95 Hosted gifts 2025-09-26 03:16:01 +04:00
Ilya Laktyushin
7dfd3b1d87 Various improvements 2025-09-26 01:30:15 +04:00
Ilya Laktyushin
85f8bde398 Various fixes 2025-09-25 23:19:21 +04:00
Ilya Laktyushin
596e04468e Fix build 2025-09-25 22:25:38 +04:00
Ilya Laktyushin
ecfaa33807 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-25 22:19:17 +04:00
Ilya Laktyushin
737f84bb13 Various fixes 2025-09-25 21:47:46 +04:00
Isaac
73b67e9a4e Merge commit 'a91658373b' 2025-09-26 00:14:28 +08:00
Isaac
87630b6e74 Various improvements 2025-09-26 00:14:23 +08:00
Ilya Laktyushin
98fb98a86e Various improvements 2025-09-25 20:09:35 +04:00
Ilya Laktyushin
a91658373b Various improvements 2025-09-25 18:41:11 +04:00
Ilya Laktyushin
6976839bfc Various fixes 2025-09-25 17:06:35 +04:00
Ilya Laktyushin
934ed73331 Fix build 2025-09-25 15:37:49 +04:00
Ilya Laktyushin
700c915495 Update API 2025-09-25 15:00:14 +04:00
Mikhail Filimonov
678e059b22 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-25 14:37:24 +04:00
Isaac
9dd6d95be6 Fix input field animation 2025-09-25 15:21:06 +08:00
Isaac
c99a642669 Merge commit '61ac2e9c21' 2025-09-25 13:38:04 +08:00
Isaac
59d351da90 Fix animation 2025-09-25 13:38:01 +08:00
Ilya Laktyushin
61ac2e9c21 Support new iPhone models 2025-09-24 21:54:47 +04:00
Ilya Laktyushin
672aff4eb5 Fix build 2025-09-24 00:03:53 +04:00
Ilya Laktyushin
9e7b0efc8b Update 2025-09-23 23:45:49 +04:00
Isaac
c32d05fdb2 Update 2025-09-24 02:35:23 +08:00
Isaac
7ed1261193 Various improvements 2025-09-23 21:59:54 +08:00
Isaac
b62fd285d6 Fix build 2025-09-23 21:04:01 +08:00
Isaac
0ebc5dac3a Merge commit '5d43f14ccb'
# Conflicts:
#	Telegram/Telegram-iOS/en.lproj/Localizable.strings
#	submodules/TelegramCallsUI/Sources/VideoChatScreen.swift
#	submodules/TelegramUI/Components/GlassBackgroundComponent/Sources/GlassBackgroundComponent.swift
#	submodules/TelegramUI/Components/VideoMessageCameraScreen/Sources/VideoMessageCameraScreen.swift
2025-09-23 20:51:11 +08:00
Isaac
3684c6ca15 Various improvements 2025-09-23 20:49:12 +08:00
Ilya Laktyushin
5d43f14ccb Various improvements 2025-09-23 16:04:39 +04:00
Mikhail Filimonov
a29a30530d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-23 13:31:56 +04:00
Ilya Laktyushin
e61870dd0d Various improvements 2025-09-23 01:28:32 +04:00
Ilya Laktyushin
400a67e240 Various improvements 2025-09-22 18:56:39 +04:00
Mikhail Filimonov
8921375934 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-22 16:47:59 +04:00
Ilya Laktyushin
d63b0ce392 Various improvements 2025-09-22 15:56:03 +04:00
Ilya Laktyushin
fb7b93fbdc Various improvements 2025-09-22 07:45:25 +04:00
Ilya Laktyushin
a80a706379 Various improvements 2025-09-22 06:42:19 +04:00
Ilya Laktyushin
efe304afe6 Add channel discussion option 2025-09-20 13:36:05 +04:00
Ilya Laktyushin
173cba16bd Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-19 22:49:08 +04:00
Ilya Laktyushin
b65a684431 Various improvements 2025-09-19 22:48:59 +04:00
Isaac
bf3ec930bc Fix tab bar switching 2025-09-19 19:35:51 +04:00
Isaac
80a7f9fcd2 Input field fixes 2025-09-19 19:08:46 +04:00
Isaac
16b981651a Various improvements 2025-09-19 17:51:11 +04:00
Isaac
14782c1d33 Merge commit 'a0e96582dd' 2025-09-19 15:36:39 +04:00
Isaac
d4a4305f5b Various improvements 2025-09-19 15:36:36 +04:00
Isaac
1d5de1be39 Update submodules 2025-09-19 15:36:24 +04:00
Mikhail Filimonov
526ad333f0 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-19 12:26:46 +04:00
Ilya Laktyushin
a0e96582dd Update API [skip ci] 2025-09-19 12:20:21 +04:00
Mikhail Filimonov
98d28d32f3 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-19 12:14:04 +04:00
Isaac
905de7ee78 Update apple_support 2025-09-18 14:25:43 +04:00
Isaac
b8400f435f Merge commit '4b8d87b05f' 2025-09-18 14:16:05 +04:00
Isaac
4f0b8a8bb4 Fix swift compiler crash 2025-09-18 14:16:02 +04:00
Isaac
d3a3ea008d Glass 2025-09-18 14:15:51 +04:00
Mikhail Filimonov
eab382611c Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-18 14:00:51 +04:00
Mikhail Filimonov
be92ffd8ea Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-18 12:03:30 +04:00
Mikhail Filimonov
96f2740607 small fix 2025-09-18 12:02:43 +04:00
Ilya Laktyushin
4b8d87b05f Merge commit '202274073f' into call-messages 2025-09-17 22:05:40 +04:00
Ilya Laktyushin
b6507b6cfb Various improvements 2025-09-17 21:27:37 +04:00
Ilya Laktyushin
cb523192d5 Various improvements 2025-09-17 20:58:42 +04:00
Isaac
202274073f Bump version 2025-09-17 11:19:13 +04:00
Isaac
04765e0c36 Update 2025-09-17 11:18:26 +04:00
Isaac
0678d0ded0 Merge branch 'master' into glass
# Conflicts:
#	Telegram/Telegram-iOS/en.lproj/Localizable.strings
#	submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift
#	submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift
#	submodules/TelegramCore/Sources/TelegramEngine/Calls/GroupCalls.swift
#	submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
2025-09-16 10:14:07 +04:00
Isaac
5a8bd1d98d Temp 2025-09-16 10:11:54 +04:00
Ilya Laktyushin
0f648157fa Merge commit '3e6c432511' into call-messages 2025-09-12 13:18:30 +04:00
Isaac
3e6c432511 Cherry-pick group call messages 2025-09-12 11:06:40 +02:00
Isaac
e0d511165c Fix call messages 2025-09-12 11:02:05 +02:00
Isaac
a257009780 Update api and call messages 2025-09-12 10:56:05 +02:00
Isaac
18e40eafe3 Fix simultaneous list view scroll + insets update animation 2025-09-12 10:55:44 +02:00
Isaac
842711de04 Auth debug email 2025-09-12 10:55:11 +02:00
Isaac
ebcd0557e5 Temp 2025-09-12 10:54:22 +02:00
Ilya Laktyushin
6b0b4975b9 Merge branch 'master' into call-messages 2025-09-12 03:43:42 +04:00
Ilya Laktyushin
3e71e2428b Fix profile buttons display with reduced transparency on 2025-09-12 02:17:36 +04:00
Ilya Laktyushin
f7901af416 Fix ton balance update on gift purchase 2025-09-11 02:29:29 +04:00
Ilya Laktyushin
2c3a49780f Fix story verification icon 2025-09-10 15:58:38 +04:00
Ilya Laktyushin
9d97a62195 Update localization 2025-09-09 22:12:19 +04:00
Ilya Laktyushin
94ee23649d Various improvements 2025-09-09 20:39:17 +04:00
Ilya Laktyushin
3e483aad40 Gift upgrade improvements 2025-09-09 04:28:27 +04:00
Ilya Laktyushin
4fc3ba70fc Various fixes 2025-09-07 14:57:43 +05:00
Ilya Laktyushin
141e7c1f49 Gift original details removal 2025-09-07 06:49:28 +05:00
Ilya Laktyushin
5c0796b536 Fix build 2025-09-06 15:21:16 +05:00
Ilya Laktyushin
c28ca9ec16 Fix build 2025-09-06 15:16:47 +05:00
Ilya Laktyushin
f2c2b9ae8c Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-09-06 14:59:59 +05:00
Ilya Laktyushin
33fe6eb476 iPad wallpaper improvements 2025-09-06 14:59:50 +05:00
Ilya Laktyushin
76e8d79f9f Update API 2025-09-06 13:35:19 +05:00
Isaac
6ee1edc8b0 Merge branch 'master' into glass
# Conflicts:
#	submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift
2025-09-05 15:48:48 +02:00
Isaac
4f4fc92345 Bot forum updates 2025-09-05 15:43:19 +02:00
Isaac
dbcc62ee40 Merge commit 'b9e5a3f3de'
# Conflicts:
#	submodules/TelegramCore/Sources/State/Serialization.swift
#	submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
#	submodules/TelegramCore/Sources/TelegramEngine/Themes/ChatThemes.swift
2025-09-05 15:26:45 +02:00
Isaac
1d06c3f058 Bot forums v2 2025-09-05 15:25:50 +02:00
Isaac
63e2a1c417 Use playerv2 for av1 content 2025-09-05 15:25:33 +02:00
Ilya Laktyushin
b9e5a3f3de Various improvements 2025-09-05 17:39:32 +05:00
Ilya Laktyushin
ef3512668c Various improvements 2025-09-05 16:11:56 +05:00
Ilya Laktyushin
59239ca2df Update API 2025-09-05 15:10:45 +05:00
Isaac
762f99c0df Update 2025-09-05 07:45:36 +02:00
Ilya Laktyushin
29b266d5ad Merge commit '3c61b4a1e4' into beta 2025-09-03 21:53:32 +05:00
Ilya Laktyushin
3c61b4a1e4 Various fixes 2025-09-03 21:44:56 +05:00
Ilya Laktyushin
3f9820f2ef Various fixes 2025-09-03 21:37:47 +05:00
Isaac
5de7e74180 Merge branch 'master' into glass
# Conflicts:
#	submodules/AttachmentUI/Sources/AttachmentPanel.swift
#	submodules/ChatPresentationInterfaceState/Sources/ChatPanelInterfaceInteraction.swift
#	submodules/TelegramUI/BUILD
#	submodules/TelegramUI/Components/Chat/ChatRecentActionsController/Sources/ChatRecentActionsController.swift
#	submodules/TelegramUI/Components/Chat/ChatTextInputActionButtonsNode/Sources/ChatTextInputActionButtonsNode.swift
#	submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift
#	submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift
#	submodules/TelegramUI/Components/PeerSelectionController/Sources/PeerSelectionControllerNode.swift
#	submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift
#	submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift
2025-09-02 19:55:51 +02:00
Ilya Laktyushin
e60cd2d4d4 Update .gitlab-ci.yml file 2025-09-02 13:57:13 +00:00
Ilya Laktyushin
5497a40f0e Deploy build 2025-09-02 17:33:12 +04:00
Isaac
871072ba95 Refactor text input 2025-09-01 21:45:31 +02:00
Isaac
e2cd4a5f8f Auth payment help
(cherry picked from commit e69f383a40)
2025-09-01 20:04:53 +02:00
Isaac
ad25a91a2f Update 2025-09-01 20:04:27 +02:00
Isaac
e69f383a40 Auth payment help 2025-09-01 20:04:09 +02:00
Isaac
629f8703ec Merge branch 'master' into glass
# Conflicts:
#	submodules/TelegramUI/Sources/ChatControllerNode.swift
2025-09-01 18:59:10 +02:00
Isaac
980ced37a8 Merge remote-tracking branch 'refs/remotes/origin/master' 2025-09-01 18:44:15 +02:00
Isaac
4337026fba Glass 2025-09-01 18:44:03 +02:00
Isaac
8e7e5fefb1 Various improvements 2025-09-01 18:43:34 +02:00
Ilya Laktyushin
fde974e51d Merge commit '12d72565ae' into beta 2025-09-01 19:21:52 +04:00
Ilya Laktyushin
12d72565ae Various fixes 2025-09-01 19:06:11 +04:00
Ilya Laktyushin
5fe77d8fd6 Merge commit 'b1bcf52a09' into beta 2025-09-01 13:24:16 +04:00
Ilya Laktyushin
b1bcf52a09 Various fixes 2025-09-01 13:14:37 +04:00
Ilya Laktyushin
27ec161e39 Merge commit '7b3cf92720' into beta 2025-09-01 03:33:13 +04:00
Ilya Laktyushin
7b3cf92720 Various fixes 2025-09-01 03:30:20 +04:00
Ilya Laktyushin
70aa29c46b Merge commit 'b41ec12024' into beta 2025-09-01 02:28:28 +04:00
Ilya Laktyushin
b41ec12024 Various fixes 2025-09-01 02:28:03 +04:00
Ilya Laktyushin
46d71cdeb9 Merge commit 'd156e55233' into beta 2025-09-01 01:48:25 +04:00
Ilya Laktyushin
d156e55233 Various fixes 2025-09-01 01:28:22 +04:00
Ilya Laktyushin
3532aad036 Various fixes 2025-09-01 01:04:55 +04:00
Ilya Laktyushin
4dc1134688 Merge commit '975430aa85' into beta 2025-09-01 00:16:09 +04:00
Ilya Laktyushin
975430aa85 Various fixes 2025-09-01 00:15:29 +04:00
Ilya Laktyushin
388868a3ce Fix build 2025-08-31 23:10:14 +04:00
Ilya Laktyushin
4dfbf55937 Merge commit '9e099d6612' into beta 2025-08-31 22:38:35 +04:00
Ilya Laktyushin
9e099d6612 Various fixes 2025-08-31 22:36:46 +04:00
Ilya Laktyushin
be54adbfa7 Various fixes 2025-08-29 23:55:43 +04:00
Ilya Laktyushin
c54e9fbedf Various fixes 2025-08-29 23:34:46 +04:00
Ilya Laktyushin
da7fae6566 Various fixes 2025-08-28 22:23:10 +04:00
Ilya Laktyushin
eac655f572 Various improvements 2025-08-28 05:22:22 +04:00
Ilya Laktyushin
a4ed31da74 Various improvements 2025-08-28 05:14:18 +04:00
Ilya Laktyushin
1e800125d5 Various improvements 2025-08-28 04:16:09 +04:00
Ilya Laktyushin
34ff4d1f16 Various improvements 2025-08-28 02:55:00 +04:00
Ilya Laktyushin
1802a28686 Various improvements 2025-08-28 02:40:18 +04:00
Ilya Laktyushin
20630b499e Various improvements 2025-08-28 02:30:08 +04:00
Ilya Laktyushin
a7924e7b6f Various improvements 2025-08-28 02:14:32 +04:00
Ilya Laktyushin
2713bcee1d Various improvements 2025-08-28 01:05:59 +04:00
Ilya Laktyushin
6405f365a9 Various improvements 2025-08-28 00:23:12 +04:00
Ilya Laktyushin
effaa875a6 Various improvements 2025-08-27 23:47:26 +04:00
Ilya Laktyushin
eb8464f687 Various improvements 2025-08-27 22:30:35 +04:00
Ilya Laktyushin
276743d0f9 Various improvements 2025-08-27 22:22:39 +04:00
Ilya Laktyushin
24e01cc8d4 Various improvements 2025-08-27 21:51:58 +04:00
Ilya Laktyushin
bd915704fa Fix build 2025-08-27 18:52:13 +04:00
Ilya Laktyushin
f17f7041cf Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-27 17:32:56 +04:00
Ilya Laktyushin
4a5e7ebed4 Various improvements 2025-08-27 17:32:48 +04:00
Mikhail Filimonov
6ec1569536 fix nextoffset 2025-08-27 12:10:41 +01:00
Mikhail Filimonov
23dd2695b8 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-27 11:17:34 +01:00
Mikhail Filimonov
11a5e97304 better isEqual for ChatTheme 2025-08-27 11:17:28 +01:00
Ilya Laktyushin
bbef11084a Update API 2025-08-26 23:58:41 +04:00
Ilya Laktyushin
144516eae5 Various improvements 2025-08-26 21:14:46 +04:00
Ilya Laktyushin
03fce1ed09 Various improvements 2025-08-26 20:08:50 +04:00
Ilya Laktyushin
4e1b9943a4 Various improvements 2025-08-26 15:44:41 +04:00
Mikhail Filimonov
f56f138aec better isEqual for ChatTheme 2025-08-26 10:18:03 +01:00
Ilya Laktyushin
800cfaf6c5 Update API 2025-08-26 12:25:23 +04:00
Isaac
f77609e6fa Various improvements 2025-08-25 22:57:08 +02:00
Isaac
73ffed012f Merge commit 'bdc6b8f628' 2025-08-25 20:10:01 +02:00
Ilya Laktyushin
bdc6b8f628 Various fixes 2025-08-25 19:52:40 +04:00
Ilya Laktyushin
618859a050 Update API 2025-08-25 18:37:14 +04:00
Ilya Laktyushin
f6e28fc44e Various fixes 2025-08-25 17:56:19 +04:00
Ilya Laktyushin
cb1f5058a7 Update API 2025-08-25 17:23:25 +04:00
Ilya Laktyushin
1d20927877 Various improvements 2025-08-25 07:16:46 +04:00
Ilya Laktyushin
ea2c1e24af Various fixes 2025-08-25 03:43:22 +04:00
Ilya Laktyushin
498ce24a09 Various fixes 2025-08-25 02:16:37 +04:00
Ilya Laktyushin
5749548ac8 Various fixes 2025-08-24 17:39:47 +04:00
Ilya Laktyushin
83ef360953 Various fixes 2025-08-24 03:32:27 +04:00
Ilya Laktyushin
780909673a Fix build 2025-08-23 22:04:16 +04:00
Ilya Laktyushin
e7c698d5f1 Various fixes 2025-08-23 21:40:21 +04:00
Ilya Laktyushin
6e3c3940c2 Various fixes 2025-08-23 11:41:30 +04:00
Ilya Laktyushin
c8230eb2e0 Various fixes 2025-08-23 03:32:53 +04:00
Ilya Laktyushin
b1ebdab0dc Various fixes 2025-08-22 22:55:59 +04:00
Ilya Laktyushin
a60a437206 Various improvements 2025-08-22 21:46:07 +04:00
Isaac
290d955b59 Merge commit '75c773e694' 2025-08-22 15:31:35 +02:00
Isaac
114401f62b Various improvements 2025-08-22 15:31:31 +02:00
Ilya Laktyushin
75c773e694 Update API [skip ci] 2025-08-22 15:52:58 +04:00
Mikhail Filimonov
8dac4b39c1 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-22 12:17:24 +01:00
Ilya Laktyushin
2c07764a31 Fix purchase manager 2025-08-21 20:27:34 +04:00
Mikhail Filimonov
ee0b13bfda Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-21 16:39:01 +01:00
Mikhail Filimonov
64ccf14ba2 unwrap value 2025-08-21 16:38:55 +01:00
Ilya Laktyushin
8abcfbd895 Various fixes 2025-08-21 16:01:12 +04:00
Mikhail Filimonov
6b65571ca1 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-21 09:18:50 +01:00
Mikhail Filimonov
fc535df5d2 - fix syntax 2025-08-21 09:18:43 +01:00
Ilya Laktyushin
ed2b41a1a1 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-21 09:08:54 +04:00
Ilya Laktyushin
0bac271cdb [WIP] Saved music 2025-08-21 09:08:35 +04:00
Ilya Laktyushin
66a614a9a4 Update API 2025-08-20 22:31:58 +04:00
Isaac
adf218345a Merge commit 'dc4b8cf999' 2025-08-19 17:24:36 +02:00
Isaac
ee749050f0 Bot forums 2025-08-19 17:24:33 +02:00
Ilya Laktyushin
dc4b8cf999 Various fixes 2025-08-19 12:12:22 +04:00
Ilya Laktyushin
927d6ad0a8 Saved music reordering 2025-08-19 12:11:47 +04:00
Mikhail Filimonov
8ba3fe6d4b Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-19 08:49:46 +01:00
Ilya Laktyushin
bdaf5f5a02 Various fixes 2025-08-18 17:33:54 +04:00
Ilya Laktyushin
ea63abbc8a Profile main tab 2025-08-18 16:53:01 +04:00
Ilya Laktyushin
f828becdb2 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-18 13:48:46 +04:00
Ilya Laktyushin
ba5b9295a3 Update API 2025-08-18 13:44:14 +04:00
Isaac
ded7e9695e [Temp] Create bot forum on Start 2025-08-15 15:11:12 +02:00
Mikhail Filimonov
2d04763fae Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-15 13:04:42 +01:00
Isaac
826c48a4dc Bot updates 2025-08-15 13:35:06 +02:00
Mikhail Filimonov
92e193e584 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-15 09:03:36 +01:00
Isaac
92156ffec0 Bot updates 2025-08-15 09:58:39 +02:00
Isaac
4c42c4d5a4 Merge commit '3d2d9a7654' 2025-08-15 09:18:32 +02:00
Isaac
b4a0e8809c Temp 2025-08-15 09:18:26 +02:00
Isaac
8843fbe5cb Support typing drafts 2025-08-15 09:18:11 +02:00
Ilya Laktyushin
1439c8c7b0 Various fixes 2025-08-14 18:50:54 +04:00
Mikhail Filimonov
6dc3045ccd Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-14 11:57:19 +01:00
Mikhail Filimonov
261e95cb8c - ProfileTabsOrder Engine item 2025-08-14 11:57:13 +01:00
Ilya Laktyushin
3d2d9a7654 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-13 18:07:28 +04:00
Ilya Laktyushin
91036bcdc2 Force external for video ads 2025-08-13 18:07:18 +04:00
Mikhail Filimonov
68c08c67b3 - BotLinkedForum dataItem 2025-08-13 10:43:10 +01:00
Ilya Laktyushin
8f70aa3957 Various fixes 2025-08-13 10:27:26 +04:00
Ilya Laktyushin
cc7fc32ab1 Update API 2025-08-12 16:10:08 +04:00
Ilya Laktyushin
8405cd5a19 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-12 13:12:47 +04:00
Ilya Laktyushin
b83e7d81ee Update API 2025-08-12 13:12:07 +04:00
Isaac
19c72085dd Merge commit 'b9e104bf2d' 2025-08-12 09:49:30 +02:00
Isaac
1b9b272b8a Update API 2025-08-12 09:49:27 +02:00
Ilya Laktyushin
b9e104bf2d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-12 04:03:05 +04:00
Ilya Laktyushin
c3fd609929 Update API 2025-08-12 03:48:18 +04:00
Isaac
313ccd7831 Merge commit '899e4cd5d1' 2025-08-11 18:17:27 +02:00
Isaac
624914b2c0 Update API 2025-08-11 18:17:23 +02:00
Mikhail Filimonov
899e4cd5d1 update macos headers 2025-08-11 16:47:44 +01:00
Isaac
403a163692 Merge commit '9146a42cfa'
# Conflicts:
#	submodules/TelegramCore/Sources/ApiUtils/TelegramMediaAction.swift
#	submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
2025-08-11 16:55:18 +02:00
Isaac
905a46e6cc Update API 2025-08-11 16:54:32 +02:00
Ilya Laktyushin
9146a42cfa Various improvements 2025-08-08 19:23:59 +04:00
Ilya Laktyushin
5c1952162b Update API [skip ci] 2025-08-08 17:00:51 +04:00
Isaac
a03dbbc365 Merge commit '1e4357c94e' 2025-08-08 13:25:10 +02:00
Isaac
709d474929 Update API 2025-08-08 13:24:44 +02:00
Ilya Laktyushin
1e4357c94e Gift format 2025-08-08 15:23:59 +04:00
Isaac
17111efc7c Merge commit 'a3f9ba1fe0' 2025-08-08 12:41:35 +02:00
Isaac
b328b84321 Experimental background persistence 2025-08-08 12:41:22 +02:00
Isaac
18a491fa48 Various improvements 2025-08-08 12:41:03 +02:00
Ilya Laktyushin
a3f9ba1fe0 Update API [skip ci] 2025-08-08 11:03:43 +04:00
Ilya Laktyushin
567ca066cf Bump 2025-08-08 00:51:43 +04:00
Ilya Laktyushin
62a02ec197 Fix 2025-08-08 00:39:30 +04:00
Isaac
e16f2ff47f Merge branch 'beta' 2025-08-05 17:44:17 +02:00
Isaac
a25bedd36b Rating 2025-08-05 17:43:59 +02:00
Ilya Laktyushin
bbb65862b9 Update API 2025-08-05 14:43:57 +04:00
Ilya Laktyushin
5da006c4ea Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-01 23:25:30 +02:00
Ilya Laktyushin
72c58813a8 Various improvements 2025-08-01 23:25:24 +02:00
Isaac
c9f9bf7daa Merge commit 'cefc76d4fc'
# Conflicts:
#	Telegram/Telegram-iOS/en.lproj/Localizable.strings
2025-08-01 21:30:17 +02:00
Isaac
179c1341be Various improvements 2025-08-01 21:29:26 +02:00
Ilya Laktyushin
cefc76d4fc Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-08-01 16:58:19 +02:00
Ilya Laktyushin
60c907e1a9 Update localization 2025-08-01 16:58:14 +02:00
Isaac
61b3025654 Fix colors 2025-08-01 16:22:26 +02:00
Isaac
0280cdbaec Merge commit 'c7949efcc2' 2025-08-01 16:07:26 +02:00
Isaac
375c2a6b6e Various improvements 2025-08-01 16:07:23 +02:00
Ilya Laktyushin
c7949efcc2 Fix gift buy button subtitle 2025-08-01 12:45:50 +02:00
Ilya Laktyushin
ddb09c821d Various improvements 2025-07-31 09:55:21 +02:00
Ilya Laktyushin
02097cc6da Add icon 2025-07-29 21:58:41 +02:00
Ilya Laktyushin
5dd0a03d9a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-29 21:50:07 +02:00
Ilya Laktyushin
711f8f7b46 Various improvements 2025-07-29 21:49:26 +02:00
Isaac
e23a02eb44 Merge branch 'beta'
# Conflicts:
#	submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift
#	versions.json
2025-07-29 20:55:11 +02:00
Isaac
edd33a0103 Update localization 2025-07-29 20:54:12 +02:00
Isaac
9e5b9d42c6 Merge commit '7a99577093' 2025-07-29 19:22:55 +02:00
Isaac
e574e2def7 Improvements 2025-07-29 19:22:41 +02:00
Ilya Laktyushin
7a99577093 Merge branches 'master' and 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-29 17:47:08 +02:00
Ilya Laktyushin
3c87b308f8 Various improvements 2025-07-29 17:39:46 +02:00
Isaac
b625243040 Various improvements 2025-07-29 15:48:11 +02:00
Isaac
c6946cc014 Clean build directory 2025-07-29 15:06:07 +02:00
Isaac
e91809a683 Various improvements 2025-07-29 14:36:00 +02:00
Isaac
7377b811e1 Various improvements 2025-07-29 13:44:38 +02:00
Isaac
bc1d03cebd Make full checkout 2025-07-29 13:44:25 +02:00
Isaac
c7bc6dc223 Merge commit '74cdd1816f' 2025-07-29 11:59:11 +02:00
Isaac
f273c81d33 Various improvements 2025-07-29 11:59:08 +02:00
Ilya Laktyushin
74cdd1816f Various fixes 2025-07-29 00:21:59 +02:00
Ilya Laktyushin
14ee4b56b5 Various improvements 2025-07-28 23:38:23 +02:00
Isaac
1da6943b7d Restore CI 2025-07-28 21:48:59 +02:00
Isaac
f671952424 Debug 2025-07-28 21:35:44 +02:00
Isaac
2d49ebf714 Update CI 2025-07-28 21:28:25 +02:00
Isaac
ef01d24f02 Story folders 2025-07-28 20:42:23 +02:00
Isaac
f32c9f52d5 Global search 2025-07-28 19:10:07 +02:00
Isaac
6f32d88a4e Fix syntax 2025-07-28 18:19:05 +02:00
Isaac
fd05480710 Fix build 2025-07-28 18:14:42 +02:00
Isaac
83f60686c8 Merge commit 'e3ed629d8f' 2025-07-28 18:00:27 +02:00
Isaac
bd797798e1 Rating 2025-07-28 18:00:24 +02:00
Ilya Laktyushin
e3ed629d8f Various improvements 2025-07-28 17:38:08 +02:00
Isaac
200b86a384 Merge commit '17140bf961' 2025-07-28 11:55:59 +02:00
Isaac
865cebe0e7 Levels 2025-07-28 11:55:56 +02:00
Ilya Laktyushin
17140bf961 Various improvements 2025-07-28 03:20:17 +02:00
Ilya Laktyushin
aa244fbcce Various improvements 2025-07-28 02:08:28 +02:00
Isaac
6ff5012e18 Rating 2025-07-28 00:29:25 +02:00
Isaac
633b44843a Merge commit 'cf3bc1edbd' 2025-07-27 23:40:40 +02:00
Isaac
87a4a0df9c Bump version 2025-07-27 23:40:29 +02:00
Ilya Laktyushin
cf3bc1edbd Various fixes 2025-07-27 23:36:37 +02:00
Ilya Laktyushin
7a93320a5c Fix gift view tooltips on iPad 2025-07-27 22:12:32 +02:00
Ilya Laktyushin
2c72d060c9 Fix build 2025-07-27 16:05:40 +02:00
Ilya Laktyushin
82543312c7 Various fixes 2025-07-27 15:24:29 +02:00
Isaac
43e0f92aa2 Merge commit 'f3a27124d7' 2025-07-27 15:01:57 +02:00
Isaac
e315e6da6e Global search 2025-07-27 15:01:53 +02:00
Ilya Laktyushin
f3a27124d7 Various improvements 2025-07-27 03:04:03 +02:00
Ilya Laktyushin
5a5892b3a7 Fix build 2025-07-26 12:26:56 +02:00
Ilya Laktyushin
380e6c4210 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-26 11:43:20 +02:00
Ilya Laktyushin
37e74f402e Gift improvements 2025-07-26 11:43:02 +02:00
Isaac
b8ac955792 Update 2025-07-25 17:40:09 +02:00
Isaac
b20652120e Merge branch 'story-folders'
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift
2025-07-25 15:21:33 +02:00
Isaac
46dad2eddc WIP 2025-07-25 15:20:36 +02:00
Isaac
0d2cffb033 Merge commit '8d5dc7ff60' 2025-07-24 22:47:05 +02:00
Isaac
0699602bbc Fix 2025-07-24 18:16:55 +02:00
Isaac
7fe2c54488 Hide features 2025-07-24 18:12:55 +02:00
Ilya Laktyushin
ee67dcb981 Disable list preprocessing on paste 2025-07-24 13:16:41 +02:00
Ilya Laktyushin
8d5dc7ff60 Disable list preprocessing on paste 2025-07-24 13:15:34 +02:00
Ilya Laktyushin
6617a0c45f Update API 2025-07-24 13:15:15 +02:00
Ilya Laktyushin
1cebd4ac6d Fix 2025-07-24 05:08:19 +02:00
Ilya Laktyushin
24aea17132 Fix 2025-07-24 05:07:17 +02:00
Ilya Laktyushin
5c2d7a642b Fix update screen layout 2025-07-24 04:42:14 +02:00
Ilya Laktyushin
3178a7472a Fix update screen layout 2025-07-24 04:41:10 +02:00
Ilya Laktyushin
ef0669ab91 Various fixes 2025-07-24 01:01:24 +02:00
Isaac
0055ca09cb Disable call conflict resolution 2025-07-24 00:10:02 +02:00
Ilya Laktyushin
8777f5da8f Fix build 2025-07-23 22:57:23 +02:00
Ilya Laktyushin
55e96a5a30 Fix add gifts load more 2025-07-23 22:37:01 +02:00
Ilya Laktyushin
b9a2af1e97 Bump version 2025-07-23 21:41:59 +02:00
Ilya Laktyushin
da930a44ad Fix crash 2025-07-23 21:41:19 +02:00
Ilya Laktyushin
9fbd857506 Various fixes 2025-07-22 19:20:26 +02:00
Isaac
cb1961ff72 Merge commit '2af0b2a8b7' into story-folders
# Conflicts:
#	MODULE.bazel.lock
#	submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift
#	submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift
#	submodules/TelegramUI/Components/PeerInfo/PeerInfoVisualMediaPaneNode/Sources/PeerInfoStoryPaneNode.swift
2025-07-22 18:28:44 +02:00
Isaac
0c9b15b181 Fix menu 2025-07-22 18:24:46 +02:00
Isaac
9c47496253 Fix 2025-07-22 17:35:00 +02:00
Isaac
bc49c5e788 Update 2025-07-22 17:24:33 +02:00
Isaac
edf2cfefc9 Add items while creating a folder 2025-07-22 16:25:15 +02:00
Isaac
a5ad030123 Update 2025-07-22 16:08:51 +02:00
Mikhail Filimonov
2af0b2a8b7 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-22 09:09:41 +02:00
Isaac
79c2f40d0b Merge commit 'db09966499' into story-folders
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift
2025-07-22 00:15:19 +02:00
Isaac
cf3dbeee29 Update 2025-07-22 00:13:32 +02:00
Isaac
32f0f1a07f Temp 2025-07-21 22:27:19 +02:00
Ilya Laktyushin
fd714756d2 Fix build 2025-07-21 17:42:40 +02:00
Mikhail Filimonov
209325ca3d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-21 17:03:03 +02:00
Ilya Laktyushin
89c03bc96a Hide gifts sortings in collections 2025-07-21 17:00:15 +02:00
Ilya Laktyushin
9dcbc81923 Various fixes 2025-07-21 16:46:14 +02:00
Mikhail Filimonov
e843a69542 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-21 16:23:30 +02:00
Ilya Laktyushin
6ced6dacd6 Various fixes 2025-07-21 16:04:37 +02:00
Ilya Laktyushin
28b0334952 Various fixes 2025-07-21 13:39:37 +02:00
Ilya Laktyushin
c9e8fe831a Various fixes 2025-07-21 01:08:46 +02:00
Ilya Laktyushin
9d703f5b60 Various fixes 2025-07-21 00:38:47 +02:00
Ilya Laktyushin
afaba07b76 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-20 19:50:07 +02:00
Ilya Laktyushin
c825438b72 Various improvements 2025-07-20 19:49:14 +02:00
Isaac
43bb746776 Hide in-progress features 2025-07-20 19:26:13 +02:00
Isaac
0817e0a943 Update module.bazel.lock 2025-07-20 18:51:35 +02:00
Isaac
2aace71289 Merge commit '66f78a352a' into story-folders 2025-07-20 18:50:19 +02:00
Isaac
72270d288e [Temp] fix local build 2025-07-20 18:50:16 +02:00
Ilya Laktyushin
66f78a352a Update localization 2025-07-20 12:58:48 +01:00
Ilya Laktyushin
e7e2fa1e83 Various fixes 2025-07-20 12:18:17 +01:00
Ilya Laktyushin
f97c2b9924 Various improvements 2025-07-20 10:14:50 +01:00
Mikhail Filimonov
3ea7da244f Merge branch 'story-folders'
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Messages/StoryListContext.swift
2025-07-20 10:54:30 +02:00
Ilya Laktyushin
5a1ea16354 Various improvements 2025-07-20 02:49:04 +01:00
Mikhail Filimonov
db09966499 reorder folders 2025-07-19 20:29:53 +02:00
Ilya Laktyushin
fd9b25b527 Various fixes 2025-07-19 15:53:00 +01:00
Ilya Laktyushin
eeaf5d4ac9 Fix build 2025-07-19 14:52:23 +01:00
Ilya Laktyushin
dff0a61d19 Various improvements 2025-07-19 12:51:42 +01:00
Isaac
a6544e5d57 Story folders 2025-07-18 16:10:54 +02:00
Isaac
817308f13e Merge commit 'fb43b34a2e' into story-folders
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
2025-07-18 11:55:03 +02:00
Isaac
4a527f3ac9 WIP 2025-07-18 11:54:19 +02:00
Mikhail Filimonov
1df896f59a Merge branch 'master' into story-folders
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
2025-07-17 09:46:42 +01:00
Isaac
5ad4331eeb WIP 2025-07-17 10:34:19 +02:00
Ilya Laktyushin
fb43b34a2e Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-16 20:38:17 +02:00
Ilya Laktyushin
555518a41d Gift collections improvements 2025-07-16 17:29:01 +01:00
Ilya Laktyushin
9bb46769a3 Various fixes 2025-07-16 17:22:42 +01:00
Mikhail Filimonov
709e3376a4 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGiftsCollections.swift
2025-07-16 12:20:12 +01:00
Mikhail Filimonov
66a889c636 public actions 2025-07-16 12:03:58 +01:00
Ilya Laktyushin
ef2d93c5a0 Update API 2025-07-15 14:01:58 +01:00
Ilya Laktyushin
3547bb0f2a Update API 2025-07-14 20:10:52 +01:00
Ilya Laktyushin
3945acbe01 Fix build 2025-07-14 14:18:10 +01:00
Ilya Laktyushin
dc0cf1d459 Fix build 2025-07-14 13:28:10 +01:00
Ilya Laktyushin
01d90f55b1 Merge commit '2ed6f9616b' 2025-07-14 13:21:14 +01:00
Ilya Laktyushin
b4832ff856 Update API 2025-07-14 12:50:11 +01:00
Isaac
7a1b0d3364 Merge branch 'master' into star-rating
# Conflicts:
#	submodules/TelegramCore/Sources/State/AccountViewTracker.swift
2025-07-11 17:22:48 +04:00
Isaac
8c5f0072bb History optimizations 2025-07-11 17:21:51 +04:00
Isaac
2ed6f9616b Peer star rating 2025-07-11 14:53:02 +04:00
Isaac
30ccc8017f Adjust transition gesture 2025-07-09 18:37:10 +04:00
Isaac
8d2b9255a6 Cleanup
(cherry picked from commit 4902b5fa36)
2025-07-09 17:48:21 +04:00
Isaac
5b15e139fd Fix reaction selection glitches
(cherry picked from commit 7d5185ed4d)
2025-07-09 17:48:15 +04:00
Isaac
636508fc97 Various improvements
(cherry picked from commit 7e240c7064)
2025-07-09 17:47:56 +04:00
Isaac
20a85a4ff7 Individual monoforum shared media
(cherry picked from commit b335bb83df)
2025-07-09 17:47:46 +04:00
Isaac
735b497a23 New address book implementation
(cherry picked from commit a16a3c3936)
2025-07-09 17:47:33 +04:00
Ilya Laktyushin
681ab8248e Cleanup 2025-07-09 09:15:54 +02:00
Ilya Laktyushin
68a003be20 Bump version 2025-07-09 09:09:18 +02:00
Ilya Laktyushin
0ae39dca5a Fix chat translation 2025-07-09 09:08:24 +02:00
Ilya Laktyushin
01f8a7e769 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-09 00:44:03 +02:00
Ilya Laktyushin
6d2757eb91 Various fixes 2025-07-09 00:43:23 +02:00
Isaac
4902b5fa36 Cleanup 2025-07-08 18:54:36 +04:00
Isaac
7d5185ed4d Fix reaction selection glitches 2025-07-08 18:37:19 +04:00
Isaac
7d3e4ece26 Merge commit '2b5b56a5bb' 2025-07-08 15:59:23 +04:00
Isaac
7e240c7064 Various improvements 2025-07-08 15:59:17 +04:00
Isaac
b335bb83df Individual monoforum shared media 2025-07-08 15:58:43 +04:00
Isaac
a16a3c3936 New address book implementation 2025-07-08 15:57:27 +04:00
Ilya Laktyushin
2b5b56a5bb Merge commit '3e31d12db6' into beta 2025-07-02 22:05:08 +02:00
Ilya Laktyushin
3e31d12db6 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-02 22:03:41 +02:00
Ilya Laktyushin
72c466ca13 Various improvements 2025-07-02 22:03:34 +02:00
Isaac
0880e7864a Merge commit '9a414b9f09' 2025-07-02 19:25:35 +02:00
Isaac
82768efe11 Fix 2025-07-02 19:25:23 +02:00
Ilya Laktyushin
9a414b9f09 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-07-02 14:31:56 +02:00
Ilya Laktyushin
37cea84896 Update API 2025-07-02 14:30:55 +02:00
Isaac
a6ad87dc63 Bump version 2025-07-01 19:38:56 +02:00
Isaac
800f7d3ac2 Update tgcalls 2025-07-01 19:38:45 +02:00
Isaac
21e8bc02ca Cleanup 2025-07-01 19:38:35 +02:00
Isaac
7b18685825 Fix user suggest changes 2025-07-01 16:10:32 +02:00
Isaac
c5f2953e90 Various improvements 2025-07-01 15:49:15 +02:00
Isaac
af3d7ada55 Merge commit 'd696a53dcb' 2025-07-01 14:57:37 +02:00
Isaac
adbc7bad61 Various improvements 2025-07-01 14:57:33 +02:00
Mikhail Filimonov
d696a53dcb Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-30 09:12:41 +01:00
Ilya Laktyushin
d3f42e6cb0 Various improvements 2025-06-30 00:09:17 +02:00
Ilya Laktyushin
f610e8b3b3 Various improvements 2025-06-30 00:06:27 +02:00
Isaac
deed7905b6 Temp 2025-06-29 22:23:54 +02:00
Isaac
1b066a3c8e Merge commit '1507e99c1d' 2025-06-29 22:23:08 +02:00
Ilya Laktyushin
1507e99c1d Various improvements 2025-06-29 20:49:10 +02:00
Ilya Laktyushin
7076cc93a5 Various improvements 2025-06-29 20:35:33 +02:00
Ilya Laktyushin
be6890d189 Various improvements 2025-06-29 20:27:53 +02:00
Isaac
bdfcc56613 Merge commit '9af928467b'
# Conflicts:
#	Telegram/Telegram-iOS/en.lproj/Localizable.strings
2025-06-29 19:40:06 +02:00
Ilya Laktyushin
9af928467b Various improvements 2025-06-29 19:38:11 +02:00
Ilya Laktyushin
43091b01d2 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-29 19:18:27 +02:00
Ilya Laktyushin
8b5d475378 Various improvements 2025-06-29 19:18:18 +02:00
Isaac
4fe928574f Cleanup 2025-06-29 19:02:51 +02:00
Isaac
9072cef8c4 Fix build 2025-06-29 19:00:16 +02:00
Isaac
e79e1b2cf9 Update API 2025-06-29 18:22:00 +02:00
Isaac
73062c70e6 Merge commit '4c962e6a6d'
# Conflicts:
#	Telegram/Telegram-iOS/en.lproj/Localizable.strings
#	submodules/PremiumUI/Sources/PremiumIntroScreen.swift
#	submodules/TelegramUI/Components/Stars/StarsTransactionScreen/Sources/StarsTransactionScreen.swift
#	submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift
2025-06-29 18:17:04 +02:00
Isaac
3ed857bfc3 Various improvements 2025-06-29 18:15:50 +02:00
Ilya Laktyushin
4c962e6a6d Various improvements 2025-06-29 17:35:30 +02:00
Ilya Laktyushin
12e85b67b8 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-29 14:55:07 +02:00
Ilya Laktyushin
4016ae8a25 Update localization 2025-06-29 14:54:42 +02:00
Isaac
b2909a3241 Limit min stars 2025-06-29 14:23:52 +02:00
Isaac
ea9f53acb8 Merge commit 'c2a10931b6' 2025-06-29 14:01:34 +02:00
Isaac
0849431ca9 Updates 2025-06-29 14:01:31 +02:00
Ilya Laktyushin
c2a10931b6 Various improvements 2025-06-29 11:57:12 +02:00
Ilya Laktyushin
a05b846703 Various improvements 2025-06-29 11:13:07 +02:00
Ilya Laktyushin
30c2bbc94b Various improvements 2025-06-29 00:41:38 +02:00
Ilya Laktyushin
09b7e77e88 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-28 23:51:21 +02:00
Ilya Laktyushin
2ce6d8c66c Various fixes 2025-06-28 23:51:09 +02:00
Isaac
529951f1ba Update tgcalls 2025-06-28 23:47:07 +02:00
Isaac
dee385f501 Merge commit 'df3eab0a74' 2025-06-28 23:42:22 +02:00
Isaac
73218834ff Various improvements 2025-06-28 23:42:18 +02:00
Ilya Laktyushin
df3eab0a74 Various fixes 2025-06-28 22:19:33 +02:00
Isaac
15c9af3ab2 Merge commit 'cbb4a890b2' 2025-06-28 20:42:59 +02:00
Isaac
496c43fcf9 Fix spm 2025-06-28 20:42:54 +02:00
Isaac
efd0f35509 WIP 2025-06-28 20:42:47 +02:00
Isaac
a23deded22 Cleanup 2025-06-28 19:48:34 +02:00
Ilya Laktyushin
cbb4a890b2 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-28 17:41:39 +02:00
Ilya Laktyushin
8862492480 Update API 2025-06-28 17:38:45 +02:00
Isaac
7512f7f017 Cleanup 2025-06-28 13:14:15 +02:00
Isaac
8b2bcc462c Build system 2025-06-28 11:33:57 +02:00
Mikhail Filimonov
b1b5b348b3 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-27 17:46:26 +01:00
Mikhail Filimonov
e15f0982cb bug fixes 2025-06-27 17:46:14 +01:00
Isaac
f79a244bf2 Various improvements 2025-06-27 17:36:37 +02:00
Isaac
10c28d982e Various improvements 2025-06-27 12:45:19 +02:00
Isaac
fd324106e3 Various improvements 2025-06-27 09:58:46 +02:00
Isaac
a78224b965 Add scheduled messages post alert 2025-06-27 00:15:15 +02:00
Isaac
5f207b4231 Merge commit 'd7dbeed5d6' 2025-06-26 20:29:26 +02:00
Isaac
3e40713aad Various improvements 2025-06-26 20:29:23 +02:00
Mikhail Filimonov
d7dbeed5d6 group call e2e-offset bug fix 2025-06-26 16:23:19 +01:00
Isaac
8818ef04ad Merge commit '3b46e1d3d0' 2025-06-26 15:02:25 +02:00
Isaac
abfdf04e9f Update API 2025-06-26 15:02:21 +02:00
Ilya Laktyushin
3b46e1d3d0 Various fixes 2025-06-26 14:09:26 +02:00
Ilya Laktyushin
dbda23b1e1 Various fixes 2025-06-25 21:53:07 +02:00
Ilya Laktyushin
9a43e49289 Fix build 2025-06-25 16:30:24 +02:00
Ilya Laktyushin
98c3b67f96 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-25 12:01:28 +02:00
Ilya Laktyushin
cae2388f95 Various improvements 2025-06-25 12:00:37 +02:00
Isaac
484c350538 Various improvements 2025-06-24 17:27:17 +02:00
Isaac
183db2a8e4 Fix action button layout 2025-06-24 15:28:44 +02:00
Isaac
119db20d25 Various improvements 2025-06-24 15:06:05 +02:00
Isaac
4513f7d2e4 Various improvements 2025-06-24 14:23:39 +02:00
Isaac
f2e96efdb5 Adjust icon 2025-06-24 13:29:25 +02:00
Isaac
6ca38476a4 Transaction screen currency 2025-06-24 13:24:22 +02:00
Isaac
d27741e5d9 Stars 2025-06-24 13:19:36 +02:00
Isaac
adae44e26f Merge commit '34372148fb'
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift
#	submodules/TelegramUI/Components/Stars/StarsAvatarComponent/Sources/StarsAvatarComponent.swift
#	submodules/TelegramUI/Components/Stars/StarsTransactionScreen/Sources/StarsTransactionScreen.swift
#	submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsBalanceComponent.swift
#	submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsListPanelComponent.swift
2025-06-24 13:06:19 +02:00
Isaac
b56a0143f3 Stars 2025-06-24 13:02:37 +02:00
Ilya Laktyushin
34372148fb Various fixes 2025-06-24 07:35:35 +02:00
Ilya Laktyushin
212164b072 Fix build 2025-06-24 01:46:25 +02:00
Ilya Laktyushin
0da5f08f22 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-24 01:25:12 +02:00
Ilya Laktyushin
d166e32b3e Various improvements 2025-06-24 01:24:14 +02:00
Isaac
51a16c7110 [WIP] Stars [skip ci] 2025-06-24 00:16:00 +02:00
Isaac
9a14b076c6 Update API [skip ci] 2025-06-23 21:52:31 +02:00
Isaac
2180826318 Cleanup 2025-06-23 20:27:40 +02:00
Isaac
3c31a513e1 Merge commit '472bf7d3b1' 2025-06-21 23:08:16 +02:00
Isaac
e57538b321 Cleanup 2025-06-21 23:08:11 +02:00
Isaac
d1e2951849 Remove vorbis 2025-06-21 23:07:48 +02:00
Ilya Laktyushin
472bf7d3b1 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-21 13:40:08 +02:00
Ilya Laktyushin
c22e60092f Update API 2025-06-21 13:40:00 +02:00
Isaac
618306b65e Merge commit '88d91ee774' 2025-06-21 12:17:27 +02:00
Isaac
3ec622d2ee Cleanup 2025-06-21 12:17:20 +02:00
Ilya Laktyushin
88d91ee774 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-20 23:01:46 +02:00
Ilya Laktyushin
4d0d62075a Various improvements 2025-06-20 23:01:21 +02:00
Isaac
484de3829d Merge commit '6e4660dbc0' 2025-06-20 15:37:30 +02:00
Isaac
df3e2db84c Suggested posts 2025-06-20 15:37:26 +02:00
Isaac
14eaec4cdd Roll back list view animation change 2025-06-20 08:52:31 +02:00
Ilya Laktyushin
6e4660dbc0 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-20 00:16:50 +02:00
Ilya Laktyushin
0a56b5bfa7 Various improvements 2025-06-20 00:16:21 +02:00
Isaac
7dd7386068 Fix build 2025-06-19 22:04:17 +02:00
Isaac
10c87a2057 Fix build 2025-06-19 21:46:57 +02:00
Isaac
5b5586e2e8 Merge commit '2f440b5453' 2025-06-19 21:40:57 +02:00
Isaac
ad0e48ac21 Fix parsing 2025-06-19 21:40:53 +02:00
Ilya Laktyushin
2f440b5453 Various improvements 2025-06-19 15:17:38 +02:00
Ilya Laktyushin
546f6ca7c2 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-19 01:27:49 +02:00
Ilya Laktyushin
c5223959b2 Various improvements 2025-06-19 01:26:50 +02:00
Isaac
07dc55194b Cleanup 2025-06-18 17:26:56 +02:00
Isaac
1b2cdb9a9b Cleanup 2025-06-18 17:24:21 +02:00
Isaac
8d40ccce0f Cleanup 2025-06-18 12:26:54 +04:00
Isaac
d5a6cb86d2 Cleanup 2025-06-18 11:57:34 +04:00
Isaac
504cb1d596 Cleanup 2025-06-18 11:47:25 +04:00
Isaac
d1ad1668c4 Fix forward to monoforum 2025-06-17 18:35:54 +04:00
Isaac
6dc45113d2 [WIP] Post suggestions 2025-06-17 18:09:45 +04:00
Isaac
55c7b6551f [WIP] Suggested posts 2025-06-17 17:07:56 +04:00
Isaac
ab470b6be7 [WIP] Post suggestion 2025-06-17 15:22:39 +04:00
Isaac
da225fd4d8 Merge commit '1b888befa1' 2025-06-17 13:55:50 +04:00
Isaac
06eaf81fa9 [WIP] Post suggestion 2025-06-17 13:55:44 +04:00
Ilya Laktyushin
1b888befa1 Various fixes 2025-06-13 18:50:02 +02:00
Ilya Laktyushin
8ed9cb99e6 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-13 18:19:08 +02:00
Ilya Laktyushin
88405d99ec Various improvements 2025-06-13 18:19:01 +02:00
Isaac
f1efac862b Bump version 2025-06-13 20:42:13 +08:00
Isaac
0a30a0ee56 Suggested posts 2025-06-13 20:01:10 +08:00
Isaac
f1b98f6dd8 Update API [skip ci] 2025-06-13 17:54:04 +08:00
Isaac
76a24167d9 Update API 2025-06-13 02:22:28 +08:00
Isaac
f7ecaef3eb Merge commit 'a835c0a6f5' 2025-06-13 02:15:39 +08:00
Isaac
2c53fd2273 Update API 2025-06-13 02:15:04 +08:00
Ilya Laktyushin
a835c0a6f5 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-06-11 21:56:06 +02:00
Ilya Laktyushin
91eb2ac8bd Various fixes 2025-06-11 21:56:00 +02:00
Isaac
d0e130ec8b Update Telegram.ipa path 2025-06-11 17:47:27 +08:00
Isaac
3bb622782e Cleanup 2025-06-11 17:47:01 +08:00
Isaac
e03895329f Fix td min iOS 2025-06-11 17:13:24 +08:00
Isaac
f11ebd9559 Merge commit 'f59abe1689' 2025-06-11 16:59:58 +08:00
Isaac
c7a2fe5d3e Update to iOS 13 2025-06-11 16:59:53 +08:00
Isaac
5200c378c6 Fix local bazellocation 2025-06-11 13:38:14 +08:00
Isaac
c42b2bd9c0 Various improvements 2025-06-11 13:37:58 +08:00
Ilya Laktyushin
f59abe1689 Various improvements 2025-06-10 22:11:07 +02:00
Isaac
400de1ef11 Merge commit '2d1e99affe' 2025-06-10 12:07:10 +08:00
Isaac
8d2639f940 Update ffmpeg to 7.1.1 2025-06-10 12:07:05 +08:00
Isaac
46f8362501 Fix ffmpeg rotation metadata 2025-06-10 12:06:22 +08:00
Isaac
9f4b35211c Update build system 2025-06-10 12:05:51 +08:00
Ilya Laktyushin
2d1e99affe Add todo haptic 2025-06-09 21:04:55 +02:00
Ilya Laktyushin
d7634beb50 Various fixes 2025-06-09 20:46:26 +02:00
Ilya Laktyushin
9edf52ed36 Cleanup 2025-06-08 19:16:02 +02:00
Ilya Laktyushin
3fd4154ddd Merge branch 'todo' 2025-06-08 18:33:02 +02:00
Ilya Laktyushin
41ae916106 Various improvements 2025-06-08 18:28:49 +02:00
Mikhail Filimonov
bc04d3c8e9 ads 2025-06-07 18:30:09 +01:00
Isaac
cf8fe78769 Monoforums 2025-06-06 21:51:03 +08:00
Isaac
d486f529a3 Various improvements 2025-06-06 20:20:42 +08:00
Ilya Laktyushin
562c621ec4 Merge branch 'todo' of gitlab.com:peter-iakovlev/telegram-ios into todo 2025-06-06 09:56:11 +02:00
Ilya Laktyushin
8709581d6a Update API 2025-06-06 09:52:11 +02:00
Isaac
cd3c27fcc2 Various improvements 2025-06-06 15:13:43 +08:00
Isaac
1dd07df394 Update API 2025-06-06 00:51:05 +08:00
Isaac
e53af6f87d Build system experiments 2025-06-06 00:33:41 +08:00
Isaac
74eb315215 Use server default for channel message price 2025-06-06 00:33:30 +08:00
Isaac
b0c824d79f Fix forum drafts 2025-06-05 20:58:50 +08:00
Isaac
a173850d41 Send videomessages to monoforum "all" tab 2025-06-05 20:36:29 +08:00
Isaac
e3afecd82c Fix monoforum loading placeholder 2025-06-05 20:17:41 +08:00
Isaac
2ca01d18eb Fix monoforum search 2025-06-05 19:59:04 +08:00
Isaac
b1371bf1ee Merge commit '8dadd30702' 2025-06-05 19:09:22 +08:00
Isaac
b5c3d6f34f Various improvements 2025-06-05 19:09:18 +08:00
Ilya Laktyushin
8dadd30702 Fix recording pause tooltip on iPad 2025-06-05 01:46:50 +02:00
Isaac
40b770dde8 Hide demo layout 2025-06-04 23:46:57 +08:00
Isaac
8afaf50d59 Bump version 2025-06-04 23:38:52 +08:00
Isaac
1cbc239dc0 Monoforums 2025-06-04 23:38:44 +08:00
Isaac
99e09e0d5a Move things around a bit 2025-06-04 16:42:53 +08:00
Isaac
69feac4d97 Various improvements 2025-06-03 23:07:46 +08:00
Mikhail Filimonov
5b2a54163b todo peerIds 2025-06-03 11:55:11 +01:00
Isaac
cf112917d6 Fix layout 2025-06-03 00:23:10 +08:00
Isaac
a8ee490b16 Model list view spring animation is supposed to be 1 second 2025-06-02 23:56:23 +08:00
Isaac
c2f0633161 Implement new emoji metadata file format 2025-06-02 23:55:34 +08:00
Mikhail Filimonov
973dc12985 Merge branch 'master' into todo 2025-06-02 10:56:08 +01:00
Isaac
d9a2d06270 Various improvements 2025-05-30 23:06:26 +08:00
Isaac
4fdbe44825 Various improvements 2025-05-30 21:08:32 +08:00
Ilya Laktyushin
997bcf7edf Update API 2025-05-30 12:37:57 +02:00
Isaac
0a1be88185 Update bazel module lock 2025-05-29 16:10:00 +08:00
Isaac
a1ce5e5726 Merge branch 'master' into beta
# Conflicts:
#	Telegram/Telegram-iOS/en.lproj/Localizable.strings
#	versions.json
2025-05-29 16:08:41 +08:00
Isaac
92065b2861 Build experiments 2025-05-29 16:06:51 +08:00
Isaac
2e53aa417f Locally update star amount on sent 2025-05-29 16:05:00 +08:00
Isaac
2fd6f40884 Ban monoforum users in the channel 2025-05-29 13:30:08 +08:00
Isaac
eb3f95ea63 Monoforums 2025-05-29 02:05:13 +08:00
Isaac
98dc32fe4c Merge commit '0077a070f2' 2025-05-29 00:23:47 +08:00
Isaac
7b72c1a034 Monoforums 2025-05-29 00:23:43 +08:00
Ilya Laktyushin
0077a070f2 Various fixes 2025-05-28 17:24:15 +02:00
Ilya Laktyushin
34cef80179 Merge branches 'master' and 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-28 16:19:56 +02:00
Ilya Laktyushin
31926980e7 Various fixes 2025-05-28 16:19:25 +02:00
Mikhail Filimonov
7fe9ce7321 - additional method 2025-05-28 12:49:27 +01:00
Mikhail Filimonov
82d38a8403 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-28 12:45:08 +01:00
Isaac
da477ec84e Update td 2025-05-28 17:05:49 +08:00
Isaac
db34a7c175 Monoforums 2025-05-28 17:05:37 +08:00
Isaac
78edb66f86 Monoforums 2025-05-28 00:23:00 +08:00
Isaac
8d65fb3495 Monoforums 2025-05-27 23:37:35 +08:00
Isaac
66ce61e756 Monoforums 2025-05-27 21:51:30 +08:00
Isaac
df088af209 Monoforums 2025-05-27 21:17:05 +08:00
Isaac
545140337b Always open keyboard when setting up a reply 2025-05-27 19:30:50 +08:00
Isaac
3b275b5e98 Read forum topics when reaching bottom in "All" 2025-05-27 19:10:37 +08:00
Isaac
cf97d7bb3b Fix secret chat association 2025-05-27 19:10:12 +08:00
Isaac
3cad999c75 Fix monoforum user unread counters 2025-05-27 18:41:24 +08:00
Isaac
8f7006281c Fix monoforum audio recording 2025-05-27 16:57:05 +08:00
Mikhail Filimonov
ecaae4c29a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-27 08:15:52 +01:00
Isaac
e2bc739c7f Monoforums 2025-05-27 13:13:53 +08:00
Isaac
0d56fcc294 Monoforums 2025-05-27 02:59:05 +08:00
Isaac
d2d16117f2 Fix build 2025-05-27 02:31:14 +08:00
Isaac
5d2b252850 Monoforums 2025-05-27 02:19:48 +08:00
Isaac
c984cb956b Monoforums 2025-05-27 00:56:39 +08:00
Isaac
60f2b98ee8 Monoforums 2025-05-26 23:38:55 +08:00
Isaac
cf5223ab46 Merge commit '3985c538a8' 2025-05-26 22:08:01 +08:00
Isaac
40e26fc25c Monoforums 2025-05-26 22:07:58 +08:00
Mikhail Filimonov
ade92569c1 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-26 09:11:58 +01:00
Ilya Laktyushin
3985c538a8 Update localization 2025-05-26 01:05:11 +02:00
Ilya Laktyushin
e27ff72830 Various fixes 2025-05-26 00:34:24 +02:00
Ilya Laktyushin
4e804bf9d9 Various improvements 2025-05-25 22:36:50 +02:00
Ilya Laktyushin
7b5883c115 Various fixes 2025-05-25 18:57:37 +02:00
Ilya Laktyushin
ce3af41ebe Various fixes 2025-05-25 16:37:55 +02:00
Ilya Laktyushin
bf15144237 Various fixes 2025-05-25 14:34:07 +02:00
Ilya Laktyushin
76246efb5d Various fixes 2025-05-25 13:18:29 +02:00
Ilya Laktyushin
870488c183 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-25 12:25:39 +02:00
Ilya Laktyushin
64e772f0b1 Gift resell price suggestion 2025-05-25 12:19:15 +02:00
Isaac
a464698638 Merge commit 'c4c05851a7' 2025-05-24 22:43:58 +08:00
Isaac
5cdce4b21a Support monoforum reactions 2025-05-24 22:42:26 +08:00
Ilya Laktyushin
c4c05851a7 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-24 16:38:45 +02:00
Ilya Laktyushin
ff29e58d4b Various improvements 2025-05-24 16:38:39 +02:00
Isaac
0542113ace Fix replies 2025-05-24 00:56:41 +08:00
Isaac
2a3e3ad4ba Monoforums 2025-05-24 00:05:48 +08:00
Isaac
3910ecdca2 Monoforums 2025-05-23 23:03:52 +08:00
Isaac
3f2533ae68 Merge commit 'b0c6afdcee' 2025-05-23 19:47:09 +08:00
Isaac
4c423437a3 Monoforums 2025-05-23 19:47:05 +08:00
Isaac
77e21b4047 Monoforums 2025-05-23 18:04:36 +08:00
Ilya Laktyushin
b0c6afdcee Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-23 11:17:15 +02:00
Ilya Laktyushin
c353a04323 Various fixes 2025-05-23 11:17:09 +02:00
Mikhail Filimonov
e94c979900 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-23 09:42:55 +01:00
Isaac
23e52bc1f7 Merge commit '40780242fe' 2025-05-23 15:56:20 +08:00
Isaac
9633013275 Monoforums 2025-05-23 15:56:01 +08:00
Mikhail Filimonov
d1e1fffed9 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-23 08:13:47 +01:00
Ilya Laktyushin
40780242fe Support poll options count configuration 2025-05-22 21:54:12 +02:00
Ilya Laktyushin
e6f4910254 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-22 21:19:56 +02:00
Ilya Laktyushin
cfbee4943d Gift store animations 2025-05-22 21:19:50 +02:00
Isaac
855efe40a6 Monoforums 2025-05-23 01:11:06 +08:00
Isaac
d574855c17 Merge commit 'e7772bb581' 2025-05-23 00:37:32 +08:00
Isaac
c264378b6a Monoforums 2025-05-23 00:37:21 +08:00
Ilya Laktyushin
e7772bb581 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-22 15:23:34 +02:00
Ilya Laktyushin
23834d139b Various fixes 2025-05-22 15:23:28 +02:00
Isaac
c2052b559a Monoforums 2025-05-22 21:15:58 +08:00
Isaac
e2660e38e7 Merge commit '880fd391c4' 2025-05-22 19:39:55 +08:00
Isaac
56532e3ab8 Monoforums 2025-05-22 19:39:52 +08:00
Mikhail Filimonov
902e913b93 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-22 12:09:38 +01:00
Isaac
e43307d945 Fix saved message navigation icon 2025-05-22 12:29:31 +08:00
Ilya Laktyushin
880fd391c4 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-22 06:12:10 +02:00
Ilya Laktyushin
4180b348f1 Various improvements 2025-05-22 06:12:04 +02:00
Isaac
f4074a4d01 Cleanup 2025-05-22 12:10:15 +08:00
Isaac
30acac1660 Don't offer "next channel to read" when it's not needed 2025-05-22 12:10:07 +08:00
Mikhail Filimonov
902346bd0d Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-21 21:17:52 +01:00
Isaac
c7c8beba5b Fix pinned animation 2025-05-22 02:42:33 +08:00
Isaac
417908a179 Merge commit '6c337b0f84' 2025-05-22 02:29:25 +08:00
Isaac
4c3ad04015 Refactor chat controller data management 2025-05-22 02:29:14 +08:00
Isaac
cd3ffe902e Bazel 2025-05-22 02:28:38 +08:00
Mikhail Filimonov
432ef8f8c8 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-21 10:03:11 +01:00
Ilya Laktyushin
6c337b0f84 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-20 22:31:22 +02:00
Ilya Laktyushin
81e11d6d36 Various improvements 2025-05-20 22:30:48 +02:00
Isaac
ba931407b3 Merge commit '62f156440f' 2025-05-21 00:35:59 +08:00
Isaac
a0e92f1f38 Update layout 2025-05-21 00:35:55 +08:00
Isaac
f1d0f694f5 [WIP] Monoforums 2025-05-21 00:23:48 +08:00
Mikhail Filimonov
c94e050e58 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-20 16:45:11 +01:00
Ilya Laktyushin
62f156440f Update API 2025-05-20 17:44:56 +02:00
Mikhail Filimonov
f0ceabd6f7 monoforums 2025-05-20 16:43:39 +01:00
Isaac
88e2d839d7 Merge branch 'master' into monoforum-temp 2025-05-20 17:26:20 +08:00
Isaac
5841e96301 Merge commit '92eb80265e' 2025-05-20 17:25:58 +08:00
Isaac
109fa6b537 [Temp] 2025-05-20 17:25:39 +08:00
Isaac
f7db73db40 Update API 2025-05-20 17:23:26 +08:00
Mikhail Filimonov
92eb80265e Merge branch 'monoforums' 2025-05-19 09:55:55 +01:00
Mikhail Filimonov
7afac7e0e9 -bugfixes 2025-05-19 09:55:09 +01:00
Isaac
3a47dab24e Fix apply read index 2025-05-18 15:31:19 +08:00
Isaac
4b47c48685 Fix forum chat list item 2025-05-18 15:31:06 +08:00
Isaac
00cd571c9b Unbump xcode version 2025-05-18 15:24:33 +08:00
Ilya Laktyushin
e5762bd9c8 Various fixes 2025-05-18 04:35:56 +04:00
Ilya Laktyushin
02a86faa7c Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-18 04:33:05 +04:00
Ilya Laktyushin
b8a4748388 Various fixes 2025-05-18 04:32:32 +04:00
Isaac
7bf76198bf Fix the callkit fix 2025-05-17 23:29:27 +08:00
Isaac
1853144218 Bump version 2025-05-17 02:56:51 +08:00
Isaac
b394d7a958 Cleanup 2025-05-17 02:34:15 +08:00
Isaac
3c59dcef70 Use openssl for provisioning profile decryption 2025-05-17 01:13:33 +08:00
Isaac
f681453bd0 Update API 2025-05-17 00:34:35 +08:00
Isaac
830c38f4bb Native match cert decryption 2025-05-17 00:34:22 +08:00
Isaac
6a7cc64883 Fix build 2025-05-16 22:25:54 +08:00
Isaac
98b05bfbc6 Merge branch 'monoforums' 2025-05-16 22:14:18 +08:00
Isaac
be6fda9404 Update bazel rules 2025-05-16 22:07:26 +08:00
Isaac
280762c7c1 Experiment 2025-05-16 22:07:15 +08:00
Mikhail Filimonov
3ff51a5ef8 Merge branch 'monoforums' of gitlab.com:peter-iakovlev/telegram-ios into monoforums 2025-05-16 14:07:13 +01:00
Isaac
09c49d47d9 [WIP] Monoforums 2025-05-16 21:03:00 +08:00
Mikhail Filimonov
5f9e166f8b Merge branch 'monoforums' of gitlab.com:peter-iakovlev/telegram-ios into monoforums 2025-05-16 09:41:59 +01:00
Isaac
245ad761be Fix monoforum search 2025-05-16 12:44:16 +08:00
Mikhail Filimonov
58986c0a4f Merge branch 'monoforums' of gitlab.com:peter-iakovlev/telegram-ios into monoforums 2025-05-15 18:03:13 +01:00
Isaac
1a56afcb48 [WIP] Monoforums 2025-05-16 01:02:25 +08:00
Ilya Laktyushin
b6db0715d0 Various fixes 2025-05-15 17:43:33 +04:00
Mikhail Filimonov
65eb853b56 Merge branch 'monoforums' of gitlab.com:peter-iakovlev/telegram-ios into monoforums 2025-05-15 09:11:37 +01:00
Mikhail Filimonov
fa52568dde peerId 2025-05-15 09:11:30 +01:00
Isaac
b752a49432 Update API 2025-05-15 00:54:50 +08:00
Isaac
03f2d0d9b9 Merge commit '2ba773373c' into monoforums 2025-05-15 00:07:20 +08:00
Ilya Laktyushin
3b7ddc33ee Merge commit '0401bc8ef1' into beta 2025-05-14 18:53:42 +04:00
Ilya Laktyushin
0401bc8ef1 Various fixes 2025-05-14 18:51:52 +04:00
Ilya Laktyushin
4882a3b9b2 Update localization
(cherry picked from commit ada73e1e20)
2025-05-14 01:02:57 +08:00
Ilya Laktyushin
3fe4720668 Fix build
(cherry picked from commit fb0479facd)
2025-05-14 01:02:37 +08:00
Isaac
a47dd6ff9e Merge commit '0ae2f9b53a' into beta 2025-05-14 01:02:21 +08:00
Isaac
96be5f6410 Bump version 2025-05-14 01:01:28 +08:00
Ilya Laktyushin
e39a3dbdd6 Various fixes
(cherry picked from commit 0b448bf68f)
2025-05-14 00:51:38 +08:00
Isaac
25a3ae793b Attempt to fix gallery glitch
(cherry picked from commit c4b0444e53)
2025-05-14 00:51:16 +08:00
Isaac
15b769a274 Don't show fake call UI on old iOS versions
(cherry picked from commit 78f382a8f1)
2025-05-14 00:51:08 +08:00
Isaac
f90402102b [WIP] Monoforums 2025-05-14 00:50:46 +08:00
Ilya Laktyushin
ada73e1e20 Update localization 2025-05-13 16:16:30 +04:00
Ilya Laktyushin
fb0479facd Fix build 2025-05-13 16:15:08 +04:00
Ilya Laktyushin
9927abd73a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-13 13:42:39 +04:00
Ilya Laktyushin
0b448bf68f Various fixes 2025-05-13 13:41:41 +04:00
Isaac
9e18743b1b Support Xcode 16.3 2025-05-13 11:40:24 +08:00
Isaac
c3222c046f Merge branch 'master' into monoforums 2025-05-12 11:32:07 +04:00
Isaac
a775b2c62c Merge commit '0ae2f9b53a' 2025-05-12 11:13:34 +04:00
Isaac
c4b0444e53 Attempt to fix gallery glitch 2025-05-12 11:13:00 +04:00
Isaac
78f382a8f1 Don't show fake call UI on old iOS versions 2025-05-12 11:11:45 +04:00
Isaac
9d2aa61ea0 Bazel upgrade 2025-05-12 11:11:05 +04:00
Isaac
610c051e38 Cleanup 2025-05-11 03:16:53 +04:00
Isaac
140efd6cfd [WIP] Monoforums 2025-05-10 18:02:55 +01:00
Mikhail Filimonov
2ba773373c Merge branch 'monoforums' of gitlab.com:peter-iakovlev/telegram-ios into monoforums
# Conflicts:
#	submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift
2025-05-08 20:58:33 +01:00
Isaac
0e119dd6f1 [WIP] Monoforums 2025-05-08 20:56:55 +01:00
Isaac
2bd66ced8c Merge commit '0ae2f9b53a' into monoforums 2025-05-08 15:04:41 +01:00
Isaac
01e5d87002 Merge branch 'master' into monoforums
# Conflicts:
#	submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift
#	submodules/TranslateUI/Sources/ChatTranslation.swift
2025-05-08 15:04:24 +01:00
Ilya Laktyushin
0ae2f9b53a Fix build 2025-05-08 01:29:19 +04:00
Isaac
aa357d463c Remove post suggestions 2025-05-07 22:09:26 +01:00
Isaac
064ab69058 Fix disposable leak 2025-05-07 22:07:50 +01:00
Isaac
4e9d624877 Fix apple intelligence gesture conflict 2025-05-07 22:07:40 +01:00
Mikhail Filimonov
4fb90392b0 Merge branch 'master' into monoforums
# Conflicts:
#	submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift
#	submodules/TranslateUI/Sources/ChatTranslation.swift
2025-05-07 17:44:26 +01:00
Isaac
a39313a4bb [WIP] Monoforums 2025-05-07 14:47:00 +01:00
Ilya Laktyushin
a523f70a14 Various fixes 2025-05-07 17:14:29 +04:00
Ilya Laktyushin
641310f4a8 Various fixes 2025-05-07 16:46:41 +04:00
Ilya Laktyushin
2fc5a19f50 Various fixes 2025-05-07 16:17:40 +04:00
Ilya Laktyushin
064024514c Various fixes 2025-05-07 16:01:08 +04:00
Ilya Laktyushin
6e00be4796 Various fixes 2025-05-07 15:56:38 +04:00
Ilya Laktyushin
60168420dc Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-06 19:06:52 +04:00
Ilya Laktyushin
80a901704c Fix boost perks order 2025-05-06 19:06:42 +04:00
Isaac
e8cf06d3be Merge commit 'fe49c78134' 2025-05-06 17:00:42 +02:00
Isaac
59f69bea05 Fix empty proxy update 2025-05-06 17:00:37 +02:00
Isaac
28f246749f [WIP] Monoforums 2025-05-06 17:00:11 +02:00
Ilya Laktyushin
fe49c78134 Fix build 2025-05-06 15:33:10 +04:00
Ilya Laktyushin
ad5b0c3a6a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-06 15:27:33 +04:00
Ilya Laktyushin
e788bb7801 Fix translation 2025-05-06 15:26:36 +04:00
Mikhail Filimonov
ecb1711970 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-06 08:20:21 +01:00
Ilya Laktyushin
b9aa229182 Fix text formatting when pasting from notes on iPad 2025-05-06 06:46:51 +04:00
Ilya Laktyushin
b7f84a97b5 Various fixes 2025-05-06 04:14:21 +04:00
Ilya Laktyushin
7afa30f3d8 Various fixes 2025-05-06 03:43:48 +04:00
Ilya Laktyushin
9fcc3248fa Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-05-06 02:09:53 +04:00
Ilya Laktyushin
3865e253ff Various fixes 2025-05-06 02:09:44 +04:00
Isaac
9db5eb726d Change defaults 2025-05-05 22:31:26 +02:00
Isaac
995fea2943 Cleanup for release 2025-05-05 22:30:03 +02:00
Isaac
631f942a7f Revert "Improve story video playback"
This reverts commit d4443f9682.
2025-05-05 22:20:22 +02:00
Isaac
17df575f54 Revert "Fix typo and crash"
This reverts commit e060b91947.
2025-05-05 22:20:06 +02:00
Isaac
c37c825333 Merge remote-tracking branch 'refs/remotes/origin/master' 2025-05-05 22:18:56 +02:00
Isaac
22ea05b3aa [WIP] Monoforums 2025-05-05 22:18:39 +02:00
Isaac
3db26de77b Merge branch 'master' into monoforums
# Conflicts:
#	submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift
2025-05-05 18:11:19 +02:00
Ilya Laktyushin
79eb359587 Various fixes 2025-05-05 20:08:50 +04:00
Isaac
984d22009b Merge commit 'ef20f4229c' 2025-05-05 18:05:04 +02:00
Isaac
a77e9fd905 Merge branch 'master' into monoforums 2025-05-05 18:04:51 +02:00
Isaac
241c3832fa Cleanup 2025-05-05 18:04:44 +02:00
Isaac
4b90fffb69 Call improvements 2025-05-05 18:04:32 +02:00
Isaac
cbb09e4780 [WIP] Monoforums 2025-05-05 18:02:50 +02:00
Isaac
65a0b41071 Build system 2025-05-05 17:58:19 +02:00
Ilya Laktyushin
ef20f4229c Fix multiple stories upload progress 2025-05-05 19:48:42 +04:00
Ilya Laktyushin
ee38ee55d4 Various fixes 2025-05-05 18:42:51 +04:00
Ilya Laktyushin
fa46338010 Various fixes 2025-05-03 17:07:17 +04:00
Ilya Laktyushin
c04e8f3c11 Various fixes 2025-05-03 05:54:09 +04:00
Ilya Laktyushin
60aef02fa5 Fix build 2025-05-02 18:50:50 +04:00
Ilya Laktyushin
fe2cc49a55 Various fixes 2025-05-02 18:31:42 +04:00
Ilya Laktyushin
6334e86721 Bump version 2025-05-02 17:18:11 +04:00
Ilya Laktyushin
da164c2332 Various fixes 2025-05-02 17:03:23 +04:00
Ilya Laktyushin
751e20043f Various fixes 2025-05-02 00:51:14 +04:00
Ilya Laktyushin
c9c4d78e30 Various fixes 2025-05-02 00:45:42 +04:00
Ilya Laktyushin
874fac0c63 Various fixes 2025-05-01 20:38:45 +04:00
Mikhail Filimonov
1f43a83c5c revert ffmpeg headers 2025-04-30 22:33:37 +01:00
Ilya Laktyushin
f8c872db55 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-30 16:55:11 +04:00
Ilya Laktyushin
d09a563200 Various fixes 2025-04-30 16:55:02 +04:00
Isaac
058a5297ea Merge commit 'fb853d50b9' 2025-04-29 18:15:05 +02:00
Isaac
e060b91947 Fix typo and crash 2025-04-29 17:36:16 +02:00
Ilya Laktyushin
fb853d50b9 Various fixes 2025-04-29 18:54:14 +04:00
Isaac
e341c0f028 Merge commit 'dd2227223d' 2025-04-29 16:45:42 +02:00
Isaac
d4443f9682 Improve story video playback 2025-04-29 16:44:43 +02:00
Isaac
9a2aff5b1e Update lottie-cpp 2025-04-29 16:43:39 +02:00
Isaac
254aea276b Update shimmer effect 2025-04-29 16:43:18 +02:00
Ilya Laktyushin
dd2227223d Merge branches 'master' and 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-29 13:52:22 +04:00
Ilya Laktyushin
4a9258cc65 Various fixes 2025-04-29 13:51:54 +04:00
Isaac
313833b7d9 Merge commit 'c5081979f0' 2025-04-29 00:33:05 +02:00
Isaac
46d9465841 Chat list notices 2025-04-29 00:32:23 +02:00
Ilya Laktyushin
c5081979f0 Various fixes 2025-04-29 02:27:17 +04:00
Ilya Laktyushin
10d5fdcac3 Fix music player playlist crash 2025-04-29 02:07:41 +04:00
Isaac
b92293efe9 Merge commit '9e0600edfa' into post-suggestion
# Conflicts:
#	submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift
2025-04-28 23:37:49 +02:00
Isaac
89bcbcf4e5 [WIP] Post suggestions 2025-04-28 23:37:02 +02:00
Isaac
1f869f309f Refactoring 2025-04-28 23:36:35 +02:00
Isaac
e77402d7b3 [WIP] Chatlist suggestions 2025-04-28 23:35:47 +02:00
Isaac
084bb5bcd5 [WIP] Post suggestions 2025-04-28 23:34:03 +02:00
Ilya Laktyushin
9e0600edfa Various fixes 2025-04-25 18:13:30 +04:00
Ilya Laktyushin
1ed853e255 Various fixes 2025-04-25 14:33:25 +04:00
Isaac
d6334b9748 Merge branch 'master' into post-suggestion 2025-04-25 10:55:31 +01:00
Isaac
e8dc1e4d93 Cleanup 2025-04-25 10:55:19 +01:00
Isaac
6ff961d250 Various improvements 2025-04-25 10:54:34 +01:00
Ilya Laktyushin
c4731d8b8d Various improvements 2025-04-24 21:12:40 +04:00
Ilya Laktyushin
9483448aa3 Update API 2025-04-24 17:53:39 +04:00
Ilya Laktyushin
9f6c3a920f Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-24 15:06:32 +04:00
Ilya Laktyushin
d5139b6363 Various fixes 2025-04-24 15:06:21 +04:00
Mikhail Filimonov
7482abfd3c Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
2025-04-24 11:59:03 +01:00
Mikhail Filimonov
a6a807ffcb Merge branch 'gift-resale'
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
2025-04-24 11:58:28 +01:00
Ilya Laktyushin
999f8c8032 Various fixes 2025-04-24 14:49:17 +04:00
Ilya Laktyushin
9b062fd5b8 Update API 2025-04-24 12:49:22 +04:00
Isaac
9b0bcee0a7 Call debugging 2025-04-23 12:20:11 +04:00
Isaac
da2849dfcf Cleanup 2025-04-23 12:19:21 +04:00
Isaac
603d5754db [WIP] Post suggestions 2025-04-23 12:18:56 +04:00
Isaac
96a5df0b68 Update gitignore 2025-04-23 12:16:42 +04:00
Isaac
f344b46dea Bump version 2025-04-23 12:16:29 +04:00
Ilya Laktyushin
2962851527 Various improvements 2025-04-22 21:06:46 +04:00
Ilya Laktyushin
14064f94eb Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-21 17:02:46 +04:00
Ilya Laktyushin
a8c7b217a4 Various improvements 2025-04-21 17:02:37 +04:00
Isaac
8d1c8f43ec Unbump version 2025-04-18 18:32:27 +04:00
Isaac
3fa887367c Merge commit 'f696cfb915'
# Conflicts:
#	Telegram/Telegram-iOS/en.lproj/Localizable.strings
2025-04-18 17:58:57 +04:00
Isaac
4bbea1f0d0 Conference improvements 2025-04-18 17:56:24 +04:00
Ilya Laktyushin
f696cfb915 Fix 2025-04-18 17:10:01 +04:00
Mikhail Filimonov
037890cfa5 Merge branch 'gift-resale' of gitlab.com:peter-iakovlev/telegram-ios into gift-resale
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift
2025-04-18 12:59:52 +01:00
Isaac
0d4b8ee2c0 Add code readme 2025-04-18 14:12:07 +04:00
Ilya Laktyushin
7fd14c1427 Fix build 2025-04-18 14:02:30 +04:00
Ilya Laktyushin
7a261aec95 Merge branch 'gift-resale' 2025-04-18 13:49:45 +04:00
Ilya Laktyushin
d8dd96e39e [WIP] Multiple story upload 2025-04-18 13:47:15 +04:00
Isaac
0bde0019f1 Merge branch 'beta' 2025-04-18 01:27:36 +04:00
Isaac
587ac7bf00 Update tgcalls 2025-04-18 01:12:11 +04:00
Isaac
0c7c73a3e9 Fix call panel
(cherry picked from commit ebdd7b37ed)
2025-04-18 01:11:36 +04:00
Isaac
239862cae2 Fix conference
(cherry picked from commit 56058e73f0)
2025-04-18 01:01:22 +04:00
Isaac
99c05b67c4 Update tgcalls 2025-04-18 01:00:31 +04:00
Isaac
b484d03de6 Merge branch 'beta' 2025-04-17 23:57:25 +04:00
Isaac
caeef02be3 Update tgcalls 2025-04-17 23:57:17 +04:00
Isaac
a18ff6a0a1 Fix default create group ttl 2025-04-17 23:57:02 +04:00
Isaac
d49d2271cf Conference improvements 2025-04-17 23:56:32 +04:00
Isaac
ebdd7b37ed Fix call panel 2025-04-17 22:01:19 +04:00
Mikhail Filimonov
c3c4e17b13 remove gift 2025-04-17 17:28:34 +01:00
Isaac
56058e73f0 Fix conference 2025-04-17 20:04:24 +04:00
Isaac
c1f9068c11 Merge branch 'beta' 2025-04-17 19:36:18 +04:00
Ilya Laktyushin
746239cf69 Various improvements 2025-04-17 16:28:59 +04:00
Ilya Laktyushin
02711f268d Merge branch 'master' into gift-resale 2025-04-17 14:57:21 +04:00
Ilya Laktyushin
ffed4a5e32 Fix 2025-04-17 14:50:00 +04:00
Ilya Laktyushin
86930f1a7e Merge branch 'gift-resale' of gitlab.com:peter-iakovlev/telegram-ios into gift-resale 2025-04-17 14:38:43 +04:00
Ilya Laktyushin
acb25b0a16 Fix gift reorder option availability 2025-04-17 14:38:23 +04:00
Mikhail Filimonov
27a2f38ff6 Merge branch 'master' into gift-resale
# Conflicts:
#	submodules/TelegramUI/Sources/SharedAccountContext.swift
2025-04-17 09:39:55 +01:00
Ilya Laktyushin
a43e5fc16b Various improvements 2025-04-16 13:54:14 +04:00
Isaac
1c44d7a36f Update tgcalls 2025-04-16 00:07:52 +04:00
Isaac
fc14d83988 Merge commit '62e53f8960' 2025-04-15 23:04:29 +04:00
Isaac
844ab9ae15 Update tgcalls 2025-04-15 23:04:11 +04:00
Isaac
16489db78e Update vscode settings 2025-04-15 23:00:55 +04:00
Mikhail Filimonov
ffc6589fa1 update macos 2025-04-15 21:34:30 +03:00
Mikhail Filimonov
cc285ef23c update to latest commit 2025-04-15 21:18:58 +03:00
Isaac
9a2215de29 Conference 2025-04-15 19:30:05 +04:00
Mikhail Filimonov
62a3b0d6ae fix typo 2025-04-15 17:52:53 +03:00
Isaac
c7269fa310 Conference updates 2025-04-15 17:49:31 +04:00
Mikhail Filimonov
54625af501 Merge branch 'beta' into gift-resale 2025-04-15 09:58:56 +03:00
Ilya Laktyushin
62e53f8960 Various fixes 2025-04-15 00:22:05 +04:00
Isaac
77bfc86c6f Merge branch 'beta' 2025-04-14 21:16:36 +04:00
Isaac
75d6745372 Update tgcalls 2025-04-14 21:15:35 +04:00
Isaac
4a97994bff Conference users from blockchain 2025-04-14 21:02:36 +04:00
Isaac
7593cc2724 Group call participants may not have a peer available (support blockchain ids) 2025-04-14 20:18:33 +04:00
Ilya Laktyushin
facbd5492c Various fixes 2025-04-14 19:23:29 +04:00
Ilya Laktyushin
1f051f737a Various fixes 2025-04-14 19:16:00 +04:00
Isaac
1ab31f1b44 Update td 2025-04-14 18:32:26 +04:00
Ilya Laktyushin
c3051cbf90 Update API 2025-04-14 15:57:24 +04:00
Mikhail Filimonov
73b8c2d3c4 bump 2025-04-13 23:26:02 +04:00
Isaac
cc06ddf3b1 Bump version 2025-04-12 23:32:56 +04:00
Isaac
672d5ddbd1 Merge commit 'b7a0e9e2d7' 2025-04-12 23:02:07 +04:00
Isaac
5f01a83214 Conference 2025-04-12 23:01:52 +04:00
Ilya Laktyushin
e5f37ee6a9 Update API 2025-04-12 13:54:21 +04:00
Ilya Laktyushin
66e8f140c1 Merge branch 'master' into gift-resale 2025-04-12 13:35:10 +04:00
Ilya Laktyushin
b7a0e9e2d7 Various fixes 2025-04-12 12:22:56 +04:00
Ilya Laktyushin
522576cb37 Various fixes 2025-04-12 04:33:56 +04:00
Ilya Laktyushin
b130511450 [WIP] Gift resale 2025-04-12 02:19:32 +04:00
Isaac
15e138e492 Add td as a submodule 2025-04-11 20:55:43 +04:00
Isaac
07037a82e7 Remove embedded td 2025-04-11 20:08:41 +04:00
Isaac
c6ff9717d4 Conference 2025-04-11 20:08:27 +04:00
Isaac
6ee705e786 Support Muted by admin in conference 2025-04-11 17:53:56 +04:00
Isaac
dcde323740 Conference 2025-04-11 17:16:36 +04:00
Isaac
22b4c30774 Conference updates 2025-04-11 14:41:49 +04:00
Isaac
a1631b421a Conference updates 2025-04-11 12:56:35 +04:00
Ilya Laktyushin
da86483d66 Add explicit gift availability decoding 2025-04-11 12:45:20 +04:00
Ilya Laktyushin
fd0c7918ff Update API 2025-04-11 12:11:48 +04:00
Isaac
de7104e48f Merge commit '1d67c6f8dc'
# Conflicts:
#	submodules/CallListUI/Sources/CallListControllerNode.swift
2025-04-10 20:03:31 +04:00
Isaac
84ad1344c7 Confrence updates 2025-04-10 19:56:53 +04:00
Ilya Laktyushin
0c524a3e8b Merge branch 'master' into gift-resale 2025-04-10 17:22:10 +04:00
Ilya Laktyushin
829ccedc80 Update API 2025-04-10 16:55:02 +04:00
Mikhail Filimonov
1d67c6f8dc Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-10 15:40:53 +04:00
Ilya Laktyushin
d92ac9275f Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-10 15:27:29 +04:00
Ilya Laktyushin
fec3db13d5 Fix gift reorder option availability 2025-04-10 15:16:03 +04:00
Isaac
8b0030ca9b Fix phone number discovery option 2025-04-09 18:43:25 +04:00
Isaac
700a71f393 Update localization 2025-04-09 18:21:11 +04:00
Isaac
5134cc2ff2 Merge commit '56b383d9db' 2025-04-09 17:16:43 +04:00
Isaac
cd30285d87 Conference updates 2025-04-09 17:16:30 +04:00
Ilya Laktyushin
56b383d9db Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-09 15:03:42 +04:00
Ilya Laktyushin
8fece7c49a Various fixes 2025-04-09 15:01:57 +04:00
Mikhail Filimonov
00c4a89add Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-09 12:46:30 +04:00
Isaac
7b1c4595b8 Merge commit '51512ad436' 2025-04-09 12:45:47 +04:00
Isaac
105b8fd8bd Update API 2025-04-09 12:45:43 +04:00
Mikhail Filimonov
bebb448ffb Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-09 11:40:20 +04:00
Ilya Laktyushin
51512ad436 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-08 20:37:10 +04:00
Ilya Laktyushin
3cc5231185 Various fixes 2025-04-08 20:36:32 +04:00
Isaac
85fba82266 Remove appcenter 2025-04-08 20:17:45 +04:00
Isaac
2387dbd1ad Merge commit '55953feeb1' 2025-04-08 20:17:16 +04:00
Isaac
a2234e9271 Conference updates 2025-04-08 20:17:13 +04:00
Ilya Laktyushin
55953feeb1 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-08 20:07:15 +04:00
Ilya Laktyushin
732a430119 Fix negative number formatting 2025-04-08 20:07:07 +04:00
Mikhail Filimonov
9ea3a38ebb Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-08 19:30:19 +04:00
Isaac
654b258d97 Conference updates 2025-04-08 18:20:10 +04:00
Isaac
2ab4af656b Conference calls 2025-04-08 16:35:41 +04:00
Isaac
cb83bc1b67 Conference calls 2025-04-08 15:58:03 +04:00
Mikhail Filimonov
6de900e87a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-08 15:32:31 +04:00
Mikhail Filimonov
b0defe9ce6 macos headers 2025-04-08 15:32:12 +04:00
Isaac
5af756488a Fix build 2025-04-08 14:50:28 +04:00
Isaac
c78095e2d3 Conference updates 2025-04-08 14:38:46 +04:00
Isaac
81ae40bcde Update encryption key animations 2025-04-08 02:44:02 +04:00
Isaac
51a657c41c Conference updates 2025-04-07 18:13:22 +04:00
Isaac
dd359090fd Merge commit '4830be32b3' 2025-04-07 12:50:28 +04:00
Isaac
9e165ca150 Conference updates 2025-04-07 12:50:23 +04:00
Ilya Laktyushin
4830be32b3 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-06 23:05:33 +04:00
Ilya Laktyushin
5b2a41fdae Fix 2025-04-06 23:05:21 +04:00
Isaac
c64c8ab240 Merge commit '2242097992' 2025-04-06 18:55:45 +04:00
Isaac
f9191aba6b Conference updates 2025-04-06 18:55:42 +04:00
Ilya Laktyushin
2242097992 Various improvements 2025-04-06 15:04:29 +04:00
Ilya Laktyushin
6ae44df975 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-05 19:19:48 +04:00
Ilya Laktyushin
88e5ff8f6b Various improvements 2025-04-05 19:18:54 +04:00
Isaac
e6fc58d797 Fix build 2025-04-04 22:21:56 +04:00
Isaac
f0bb504b6c Merge commit 'ed20a51ed2' 2025-04-04 22:17:32 +04:00
Isaac
157692bc48 Conference update 2025-04-04 22:17:28 +04:00
Mikhail Filimonov
ed20a51ed2 - tdbinding typo fix 2025-04-04 20:35:22 +04:00
Mikhail Filimonov
b0c637bfff macos related changes 2025-04-04 16:58:42 +04:00
Mikhail Filimonov
5f6f1de1d3 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-04 16:57:45 +04:00
Isaac
0a499f4e2b Conference updates 2025-04-04 16:51:46 +04:00
Isaac
e8b7f53c84 Conference updates 2025-04-04 14:04:52 +04:00
Mikhail Filimonov
9052f0d32e Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-04 12:03:00 +04:00
Isaac
e03a9d818e Conference updates 2025-04-04 11:16:34 +04:00
Mikhail Filimonov
9367fa95d7 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-04 11:02:38 +04:00
Isaac
a2c624c3b3 Conference improvements 2025-04-03 19:33:12 +04:00
Mikhail Filimonov
d49a85b35a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-03 18:45:57 +04:00
Mikhail Filimonov
0cf707f2c7 macos changes 2025-04-03 18:45:49 +04:00
Isaac
077fdb4d82 Merge commit '13669eee96' 2025-04-03 17:39:29 +04:00
Isaac
5fa86c6a33 Conference updates 2025-04-03 17:39:24 +04:00
Ilya Laktyushin
13669eee96 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-03 17:07:12 +04:00
Ilya Laktyushin
c5168b8905 Various improvements 2025-04-03 17:06:20 +04:00
Isaac
a72b61423a Update tgcalls 2025-04-03 17:00:51 +04:00
Mikhail Filimonov
b78817526e Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-03 08:52:07 +04:00
Isaac
1a31d83699 Conference calls 2025-04-03 00:37:42 +04:00
Isaac
5deca3fac7 Add peerId 2025-04-02 20:39:51 +04:00
Isaac
6112405c9f Fix build 2025-04-02 18:28:10 +04:00
Isaac
86e311ec44 Fix build 2025-04-02 18:21:59 +04:00
Isaac
5076c948d8 Remove conference debug setting 2025-04-02 18:17:48 +04:00
Isaac
f546a7ab20 Cleanup build scripts 2025-04-02 18:17:22 +04:00
Mikhail Filimonov
0a67b254f8 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-01 20:01:32 +04:00
Isaac
518e04cab7 Fix typo 2025-04-01 18:26:09 +04:00
Isaac
61f247235a Add firebase app distribution 2025-04-01 18:22:12 +04:00
Isaac
2393424bde Conference calls 2025-04-01 17:18:08 +04:00
Mikhail Filimonov
dd863d3948 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-04-01 13:56:38 +04:00
Isaac
b90065451b Merge commit '81d23edd72' 2025-04-01 13:56:11 +04:00
Isaac
54c5314462 Update conference calls 2025-04-01 13:56:08 +04:00
Mikhail Filimonov
7e550200aa macos related changes. 2025-04-01 12:02:45 +04:00
Ilya Laktyushin
81d23edd72 Fix build 2025-03-31 15:31:49 +04:00
Ilya Laktyushin
09c940bfe2 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-03-31 15:25:24 +04:00
Ilya Laktyushin
0186f12972 Various improvements 2025-03-31 15:24:55 +04:00
Isaac
c3c092967f Update API 2025-03-31 00:41:33 +04:00
Isaac
2c32a62f6a Conference updates 2025-03-30 22:40:22 +04:00
Isaac
7c73b91129 Move things around 2025-03-30 21:32:17 +04:00
Isaac
36e564e53d Fix release build 2025-03-30 02:13:07 +04:00
Isaac
895e16710b Bump version 2025-03-30 02:08:02 +04:00
Isaac
dd471503ba Merge commit '7d8920db82'
# Conflicts:
#	submodules/CallListUI/Sources/CallListController.swift
2025-03-30 02:07:46 +04:00
Isaac
aaf52d4282 Conference calls 2025-03-30 02:06:50 +04:00
Isaac
66c244f540 Add LSP support 2025-03-30 02:06:26 +04:00
Isaac
747f4b9d20 Update tgcalls 2025-03-30 02:05:52 +04:00
Isaac
cebe18e6d6 Improve HLS video thumbnail generation 2025-03-30 02:05:09 +04:00
Ilya Laktyushin
7d8920db82 Various fixes 2025-03-28 18:50:04 +04:00
Ilya Laktyushin
03a604d543 Various improvements 2025-03-28 17:19:10 +04:00
Ilya Laktyushin
d423ebeac0 Various fixes 2025-03-27 18:36:25 +04:00
Ilya Laktyushin
19e37d149b Improved pinned gift replace panel 2025-03-27 15:13:08 +04:00
Ilya Laktyushin
b19e056a37 Various fixes 2025-03-27 15:11:46 +04:00
Ilya Laktyushin
97eea98f11 Various fixes 2025-03-27 01:02:27 +04:00
Isaac
2739a839ed Fix flatbuffers serialization 2025-03-25 12:36:31 +01:00
Ilya Laktyushin
6ae4aa2b73 Fix 2025-03-24 14:47:42 +04:00
Ilya Laktyushin
bf620b4703 Fix 2025-03-24 14:18:00 +04:00
Ilya Laktyushin
e26a2c3e21 Fix 2025-03-24 13:43:20 +04:00
Ilya Laktyushin
a8b02015ce Various improvements 2025-03-24 05:27:50 +04:00
Ilya Laktyushin
a651bb589d Various fixes 2025-03-23 18:24:16 +04:00
Ilya Laktyushin
f720277d29 Various improvements 2025-03-23 03:56:44 +04:00
Ilya Laktyushin
fa93715135 Bump version 2025-03-22 19:47:31 +04:00
Ilya Laktyushin
9a103ddbcf Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-03-21 18:43:36 +04:00
Ilya Laktyushin
5956d5142f Various improvements 2025-03-21 18:41:49 +04:00
Isaac
a4b39e6fd0 Merge branch 'beta'
# Conflicts:
#	submodules/TelegramUI/Sources/ChatInterfaceInputContexts.swift
2025-03-21 10:56:17 +01:00
Isaac
b7f6ed2107 Fix image serialization 2025-03-21 10:49:59 +01:00
Isaac
2e0597ffe0 Bump version 2025-03-20 20:18:16 +01:00
Isaac
fb68e14a24 Update webrtc and tgcalls 2025-03-20 20:09:31 +01:00
Isaac
7c700f9f80 Fix BrowserScreen memory leak
(cherry picked from commit 006b14bda7)
2025-03-20 20:04:53 +01:00
Isaac
7d02650616 Update webrtc and tgcalls 2025-03-20 20:02:25 +01:00
Ilya Laktyushin
c8fe12cb8e Various fixes 2025-03-20 21:53:52 +04:00
Isaac
2b66b91f3a Bump version 2025-03-19 19:42:56 +01:00
Ilya Laktyushin
454b77da4e Merge branches 'master' and 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-03-19 22:03:26 +04:00
Ilya Laktyushin
66d1aedcb0 Various fixes 2025-03-19 22:03:17 +04:00
Isaac
93b421cd73 Merge commit '5e79ec4b32' 2025-03-19 18:56:56 +01:00
Isaac
7e2c6da812 FlatBuffers implementation debugging 2025-03-19 18:56:39 +01:00
Isaac
b732a6c578 Additional call-related functions [temp] 2025-03-19 18:56:24 +01:00
Isaac
26f7d180a7 Forgot to commit 2025-03-19 18:55:59 +01:00
Isaac
006b14bda7 Fix BrowserScreen memory leak 2025-03-19 18:55:42 +01:00
Isaac
17dd059f13 [WIP] Conference 2025-03-19 18:55:24 +01:00
Isaac
40b19cfef2 Check idea from https://github.com/TelegramMessenger/Telegram-iOS/pull/1712/commits/be6bc8845d20930d2335dfc8695bad3a75144166 2025-03-19 18:51:04 +01:00
Isaac
20ec0b6e05 Merge branch 'temp-pp1'
# Conflicts:
#	submodules/AvatarNode/Sources/AvatarNode.swift
#	submodules/DebugSettingsUI/Sources/DebugController.swift
2025-03-19 18:50:12 +01:00
Ilya Laktyushin
5e79ec4b32 Frozen account improvements 2025-03-19 16:40:26 +04:00
Ilya Laktyushin
ef3eb05d69 Frozen account improvements 2025-03-19 14:39:39 +04:00
Ilya Laktyushin
344bbb4fcd Various fixes 2025-03-19 00:10:51 +04:00
Ilya Laktyushin
d6eecb7844 Various improvements 2025-03-18 20:12:41 +04:00
Ilya Laktyushin
730f03dcd8 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-03-18 16:18:44 +04:00
Ilya Laktyushin
39dd9110f5 Various improvements 2025-03-18 16:18:34 +04:00
Mikhail Filimonov
82ed854341 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-03-18 15:33:29 +04:00
Mikhail Filimonov
52bdb13bdc prem disallow 2025-03-18 15:22:35 +04:00
Ilya Laktyushin
8a8ff6fddc Various fixes 2025-03-18 14:55:03 +04:00
Mikhail Filimonov
fd20831e92 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
# Conflicts:
#	submodules/TelegramCore/Sources/TelegramEngine/Peers/AdPeers.swift
2025-03-18 14:48:20 +04:00
Mikhail Filimonov
e6f9f2e2e6 some ad fixes 2025-03-18 14:40:45 +04:00
Ilya Laktyushin
2454a7a876 Various improvements 2025-03-18 14:39:58 +04:00
Isaac
4c626fdd13 [Temp] 2025-03-17 21:56:57 +01:00
Mikhail Filimonov
f7b7fc151a Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-03-17 21:31:53 +04:00
Ilya Laktyushin
4291cd6279 Update API 2025-03-17 21:10:07 +04:00
Mikhail Filimonov
8563fa6abd Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-03-17 19:28:41 +04:00
Ilya Laktyushin
7e4195a6eb Merge commit '371ec63cc7' 2025-03-17 14:28:57 +04:00
Ilya Laktyushin
371ec63cc7 Fix 2025-03-17 14:27:27 +04:00
Mikhail Filimonov
52b44764f4 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-03-17 11:35:12 +04:00
Ilya Laktyushin
a78cd98a3e Fix build 2025-03-17 01:32:49 +04:00
Ilya Laktyushin
e4c5b85739 Merge commit '765bca915e' 2025-03-17 01:26:47 +04:00
Ilya Laktyushin
765bca915e Use embedded gift remaining count if no actual data available 2025-03-17 01:01:07 +04:00
Ilya Laktyushin
04a6fa02e2 Merge commit 'c529ba1c87' 2025-03-17 00:40:46 +04:00
Ilya Laktyushin
c529ba1c87 Various fixes 2025-03-17 00:17:58 +04:00
Ilya Laktyushin
5473a8d25d Various fixes 2025-03-16 14:05:50 +04:00
Ilya Laktyushin
c00d75ca5b Improve ton gift owner display 2025-03-16 13:57:58 +04:00
Ilya Laktyushin
91da8e11ff Merge branches 'master' and 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-03-16 13:53:11 +04:00
Ilya Laktyushin
47fad1f11a Fix blockchain gift display 2025-03-16 13:53:00 +04:00
Isaac
90f0bcbc8a Bump version 2025-03-16 00:10:05 +01:00
Isaac
0b38b11ce6 VoIP updates
(cherry picked from commit 13488b2eaa)
2025-03-16 00:09:10 +01:00
Isaac
5546558197 Fix stream call audio when using shared audio context 2025-03-15 20:49:14 +01:00
Isaac
f0d2f4d225 Merge commit '2effcb42b7' 2025-03-14 15:37:22 +01:00
Isaac
1cd1c1e0b3 Merge branch 'temp-ppp'
# Conflicts:
#	submodules/TelegramUI/Sources/AccountContext.swift
2025-03-14 15:37:17 +01:00
Isaac
13488b2eaa VoIP updates 2025-03-14 15:36:23 +01:00
Isaac
1304f0f098 IOSurface experiment 2025-03-14 15:34:45 +01:00
Isaac
97c02dd5b5 IOSurface experiment 2025-03-14 15:34:31 +01:00
Isaac
daaa6a7e2e IOSurface experiment 2025-03-14 15:34:16 +01:00
Ilya Laktyushin
2effcb42b7 Various improvements 2025-03-14 16:19:07 +04:00
Ilya Laktyushin
fed338985d Various improvements 2025-03-14 13:35:44 +04:00
Ilya Laktyushin
ff34190f92 Update API 2025-03-14 06:04:23 +04:00
Ilya Laktyushin
e9ef89be5e Merge commit 'c6718b3a5e' 2025-03-13 16:43:06 +04:00
Ilya Laktyushin
c6718b3a5e Various fixes 2025-03-13 15:31:01 +04:00
Isaac
6d1732d830 Fix default to speaker
(cherry picked from commit 950c3d9f1e)
2025-03-13 00:37:18 +01:00
Isaac
f9f58e1ca7 Merge branch 'beta' of gitlab.com:peter-iakovlev/telegram-ios into beta 2025-03-13 00:35:29 +01:00
Isaac
6faefd876a Merge commit '399933bc5e' 2025-03-13 00:35:11 +01:00
Isaac
bb015f2bfa Various improvements 2025-03-13 00:34:59 +01:00
Isaac
950c3d9f1e Fix default to speaker 2025-03-13 00:34:46 +01:00
Isaac
46e71cd7c7 Merge branch 'beta'
# Conflicts:
#	Telegram/Telegram-iOS/en.lproj/Localizable.strings
2025-03-13 00:30:16 +01:00
Ilya Laktyushin
399933bc5e Fix build 2025-03-12 22:19:43 +04:00
Ilya Laktyushin
c5ed3139b7 Merge commit 'eabf0985ef' 2025-03-12 21:59:51 +04:00
Ilya Laktyushin
eabf0985ef Various fixes 2025-03-12 21:24:42 +04:00
Ilya Laktyushin
369116767a Various fixes 2025-03-12 18:57:22 +04:00
Ilya Laktyushin
a67c0b41af Bump version 2025-03-12 00:40:37 +04:00
Ilya Laktyushin
5ee53ad996 Various fixes 2025-03-12 00:40:11 +04:00
Ilya Laktyushin
bafbe20063 Various improvements 2025-03-11 18:48:35 +04:00
Ilya Laktyushin
80cd8f7b32 Various improvements 2025-03-11 06:49:43 +04:00
Ilya Laktyushin
ebfa8f08a1 Fix gift message flag 2025-03-10 18:17:55 +04:00
Ilya Laktyushin
2ecbaf4507 Various improvements 2025-03-10 15:32:15 +04:00
Isaac
509de0f5e9 Update .gitignore 2025-03-10 11:41:18 +01:00
Isaac
21c9965750 Merge commit 'b378b7b282' into beta 2025-03-08 18:31:01 +01:00
Isaac
588f5cb8c0 Guard resource parsing 2025-03-08 18:30:57 +01:00
Ilya Laktyushin
b864b88935 Various fixes 2025-03-08 03:11:26 +04:00
Ilya Laktyushin
0f8def4348 Various fixes 2025-03-08 03:10:12 +04:00
Ilya Laktyushin
f619e628f1 Fix 2025-03-08 00:56:28 +04:00
Ilya Laktyushin
15c181bc52 Fix paid message resend 2025-03-08 00:47:07 +04:00
Ilya Laktyushin
8ddd793a36 Fix build 2025-03-08 00:17:11 +04:00
Ilya Laktyushin
a6708979ba Fix 2025-03-08 00:15:34 +04:00
Ilya Laktyushin
9bba73a8ff Fix 2025-03-08 00:12:08 +04:00
Ilya Laktyushin
a9ce88255d Various fixes 2025-03-08 00:01:18 +04:00
Ilya Laktyushin
c39ba69250 Fix filtered gifts pinning 2025-03-07 23:18:38 +04:00
Ilya Laktyushin
1483207919 Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios 2025-03-07 21:56:59 +04:00
Ilya Laktyushin
cdd987e627 Various fixes 2025-03-07 21:56:17 +04:00
Isaac
d7a8f0dcc3 Update localization 2025-03-07 17:53:00 +01:00
Isaac
383ab9e479 Various improvements 2025-03-07 17:52:50 +01:00
Mikhail Filimonov
05c05c62ec - macos fixes 2025-03-07 18:42:10 +04:00
Isaac
a63a3074bd Bump version 2025-03-04 16:18:53 +01:00
Isaac
0d4a8403fc Fix more leaks 2025-03-04 16:18:44 +01:00
18288 changed files with 1874657 additions and 293634 deletions

View file

@ -1,39 +1,41 @@
build --action_env=ZERO_AR_DATE=1
build --apple_platform_type=ios
build --enable_platform_specific_config
build --apple_crosstool_top=@local_config_apple_cc//:toolchain
build --crosstool_top=@local_config_apple_cc//:toolchain
build --host_crosstool_top=@local_config_apple_cc//:toolchain
build --cxxopt='-std=c++17'
build --per_file_copt="third-party/webrtc/.*\.cpp$","@-std=c++17"
build --per_file_copt="third-party/webrtc/.*\.cc$","@-std=c++17"
build --per_file_copt="third-party/webrtc/.*\.mm$","@-std=c++17"
build --per_file_copt="submodules/LottieMeshSwift/LottieMeshBinding/Sources/.*\.mm$","@-std=c++17"
build --per_file_copt="submodules/LottieCpp/lottiecpp/Sources/.*\.mm$","@-std=c++17"
build --per_file_copt="submodules/LottieCpp/lottiecpp/Sources/.*\.cpp$","@-std=c++17"
build --per_file_copt="submodules/LottieCpp/lottiecpp/PlatformSpecific/Darwin/Sources/.*\.mm$","@-std=c++17"
build --per_file_copt="submodules/LottieCpp/lottiecpp/PlatformSpecific/Darwin/Sources/.*\.cpp$","@-std=c++17"
build --per_file_copt="Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/.*\.cpp$","@-std=c++17"
build --per_file_copt="Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/.*\.mm$","@-std=c++17"
# macOS-specific settings (auto-applied on macOS via --enable_platform_specific_config)
build:macos --apple_platform_type=ios
build:macos --apple_crosstool_top=@local_config_apple_cc//:toolchain
build:macos --crosstool_top=@local_config_apple_cc//:toolchain
build:macos --host_crosstool_top=@local_config_apple_cc//:toolchain
build:macos --per_file_copt=".*\.m$","@-fno-objc-msgsend-selector-stubs"
build:macos --per_file_copt=".*\.mm$","@-fno-objc-msgsend-selector-stubs"
build:macos --features=debug_prefix_map_pwd_is_dot
build:macos --features=swift.cacheable_swiftmodules
build:macos --features=swift.debug_prefix_map
build:macos --features=swift.enable_vfsoverlays
build:dbg --features=swift.emit_swiftsourceinfo
build --swiftcopt=-whole-module-optimization
build --per_file_copt=".*\.m$","@-fno-objc-msgsend-selector-stubs"
build --per_file_copt=".*\.mm$","@-fno-objc-msgsend-selector-stubs"
#build --linkopt="-ld_classic"
build --features=debug_prefix_map_pwd_is_dot
build --features=swift.cacheable_swiftmodules
build --features=swift.debug_prefix_map
build --features=swift.enable_vfsoverlays
# Linux-specific settings (auto-applied on Linux via --enable_platform_specific_config)
build:linux --action_env=CC
build:linux --action_env=CXX
build --strategy=Genrule=standalone
build --spawn_strategy=standalone
build --strategy=SwiftCompile=standalone
build --define RULES_SWIFT_BUILD_DUMMY_WORKER=1
build:macos --strategy=SwiftCompile=worker
build --noenable_bzlmod
# SourceKit BSP: Swift indexing features (macOS only)
common:macos --features=swift.index_while_building
common:macos --features=swift.use_global_index_store
common:macos --features=swift.use_global_module_cache
common:macos --features=oso_prefix_is_pwd
# SourceKit BSP: Index build config (used for background indexing)
common:index_build --experimental_convenience_symlinks=ignore
common:index_build --show_result=0
common:index_build --noshow_loading_progress
common:index_build --noshow_progress
common:index_build --noannounce_rc
common:index_build --noshow_timestamps
common:index_build --curses=no
common:index_build --color=no

View file

@ -1 +1,2 @@
# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
spm-files

15
.gitignore vendored
View file

@ -69,4 +69,17 @@ submodules/OpusBinding/SharedHeaders/*
submodules/FFMpegBinding/SharedHeaders/*
submodules/OpenSSLEncryptionProvider/SharedHeaders/*
submodules/TelegramCore/FlatSerialization/Sources/*
buildServer.json
buildServer.json
.build/**
Telegram.LSP.json
**/.build/**
spm-files
xcode-files
.bsp/**
.sourcekit-lsp/**
/.claude/
**/.claude/settings.local.json
**/.vscode/launch.json
/buildbox/*
**/node_modules/
tools/sim-watcher/dist/

View file

@ -21,15 +21,14 @@ internal:
script:
- export PATH=/opt/homebrew/opt/ruby/bin:$PATH
- export PATH=`gem environment gemdir`/bin:$PATH
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="build-system/appcenter-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=adhoc --configuration=release_arm64
- python3 -u build-system/Make/DeployToAppCenter.py --configuration="$TELEGRAM_PRIVATE_DATA_PATH/appcenter-configurations/appcenter-internal.json" --ipa="build/artifacts/Telegram.ipa" --dsyms="build/artifacts/Telegram.DSYMs.zip"
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="build-system/appcenter-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=adhoc --configuration=release_arm64 --embedWatchApp --watchApiId="$TELEGRAM_WATCHOS_APP_ID" --watchApiHash="$TELEGRAM_WATCHOS_APP_HASH"
- python3 -u build-system/Make/DeployBuild.py --configuration="$TELEGRAM_PRIVATE_DATA_PATH/deploy-configurations/internal-configuration.json" --ipa="build/artifacts/Telegram.ipa" --dsyms="build/artifacts/Telegram.DSYMs.zip"
- rm -rf build-input/configuration-repository-workdir
- rm -rf build-input/configuration-repository
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="$TELEGRAM_PRIVATE_DATA_PATH/build-configurations/enterprise-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=enterprise --configuration=release_arm64 --embedWatchApp --watchApiId="$TELEGRAM_WATCHOS_APP_ID" --watchApiHash="$TELEGRAM_WATCHOS_APP_HASH"
- python3 -u build-system/Make/DeployBuild.py --configuration="$TELEGRAM_PRIVATE_DATA_PATH/deploy-configurations/enterprise-configuration.json" --ipa="build/artifacts/Telegram.ipa" --dsyms="build/artifacts/Telegram.DSYMs.zip"
environment:
name: internal
artifacts:
when: always
paths:
- build/artifacts
expire_in: 1 week
internal_testflight:
tags:
@ -40,10 +39,15 @@ internal_testflight:
except:
- tags
script:
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="build-system/appstore-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=appstore --configuration=release_arm64
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="build-system/appstore-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=appstore --configuration=release_arm64 --embedWatchApp --watchApiId="$TELEGRAM_WATCHOS_APP_ID" --watchApiHash="$TELEGRAM_WATCHOS_APP_HASH"
- python3 -u build-system/Make/Make.py remote-deploy-testflight --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --ipa="build/artifacts/Telegram.ipa" --dsyms="build/artifacts/Telegram.DSYMs.zip"
environment:
name: testflight_llc
artifacts:
when: always
paths:
- build/artifacts
expire_in: 1 week
appstore_development:
tags:
@ -55,7 +59,6 @@ appstore_development:
- tags
script:
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="$TELEGRAM_PRIVATE_DATA_PATH/build-configurations/enterprise-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=enterprise --configuration=release_arm64
- python3 -u build-system/Make/DeployToAppCenter.py --configuration="$TELEGRAM_PRIVATE_DATA_PATH/appcenter-configurations/appstore-development.json" --ipa="build/artifacts/Telegram.ipa" --dsyms="build/artifacts/Telegram.DSYMs.zip"
environment:
name: appstore-development
artifacts:
@ -74,8 +77,8 @@ experimental_i:
script:
- export PATH=/opt/homebrew/opt/ruby/bin:$PATH
- export PATH=`gem environment gemdir`/bin:$PATH
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="build-system/appstore-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=adhoc --configuration=release_arm64
- python3 -u build-system/Make/DeployToAppCenter.py --configuration="$TELEGRAM_PRIVATE_DATA_PATH/appcenter-configurations/appcenter-experimental.json" --ipa="build/artifacts/Telegram.ipa" --dsyms="build/artifacts/Telegram.DSYMs.zip"
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="build-system/appcenter-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=adhoc --configuration=release_arm64
- python3 -u build-system/Make/Make.py remote-deploy-testflight --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --ipa="build/artifacts/Telegram.ipa" --dsyms="build/artifacts/Telegram.DSYMs.zip"
environment:
name: experimental
artifacts:
@ -93,7 +96,6 @@ experimental:
- tags
script:
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="$TELEGRAM_PRIVATE_DATA_PATH/build-configurations/enterprise-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=enterprise --configuration=release_arm64
- python3 -u build-system/Make/DeployToAppCenter.py --configuration="$TELEGRAM_PRIVATE_DATA_PATH/appcenter-configurations/appcenter-experimental2.json" --ipa="build/artifacts/Telegram.ipa" --dsyms="build/artifacts/Telegram.DSYMs.zip"
environment:
name: experimental-2
artifacts:
@ -113,7 +115,7 @@ beta_testflight:
script:
- export PATH=/opt/homebrew/opt/ruby/bin:$PATH
- export PATH=`gem environment gemdir`/bin:$PATH
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="build-system/appstore-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=appstore --configuration=release_arm64
- python3 -u build-system/Make/Make.py remote-build --darwinContainers="$DARWIN_CONTAINERS" --darwinContainersHost="$DARWIN_CONTAINERS_HOST" --cacheHost="$TELEGRAM_BAZEL_CACHE_HOST" --configurationPath="build-system/appstore-configuration.json" --gitCodesigningRepository="$TELEGRAM_GIT_CODESIGNING_REPOSITORY" --gitCodesigningType=appstore --configuration=release_arm64 --embedWatchApp --watchApiId="$TELEGRAM_WATCHOS_APP_ID" --watchApiHash="$TELEGRAM_WATCHOS_APP_HASH"
environment:
name: testflight_llc
artifacts:

9
.gitmodules vendored
View file

@ -29,3 +29,12 @@ url=../tgcalls.git
[submodule "third-party/dav1d/dav1d"]
path = third-party/dav1d/dav1d
url = https://github.com/ali-fareed/dav1d.git
[submodule "third-party/td/td"]
path = third-party/td/td
url = https://github.com/tdlib/td
[submodule "third-party/XcodeGen"]
path = third-party/XcodeGen
url = https://github.com/yonaskolb/XcodeGen.git
[submodule "build-system/bazel-rules/sourcekit-bazel-bsp"]
path = build-system/bazel-rules/sourcekit-bazel-bsp
url = https://github.com/spotify/sourcekit-bazel-bsp.git

19
.vscode/launch.json vendored
View file

@ -1,19 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "sweetpad-lldb",
"request": "attach",
"name": "Attach to running app (SweetPad)",
"preLaunchTask": "sweetpad: launch",
"codelldbAttributes": {
"initCommands": [
"command source ~/.lldbinit-Xcode"
]
}
}
]
}

32
.vscode/settings.json vendored
View file

@ -1,5 +1,29 @@
{
"sweetpad.build.xcodeWorkspacePath": "Telegram/Telegram.xcodeproj/project.xcworkspace",
"lldb.library": "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB",
"lldb.launch.expressions": "native"
}
"swift.disableSwiftPackageManagerIntegration": true,
"swift.autoGenerateLaunchConfigurations": false,
"swift.disableAutoResolve": true,
"search.followSymlinks": false,
"files.exclude": {
".git/**": true
},
"files.watcherExclude": {
".git/**": true
},
"search.exclude": {
".git/**": true
},
"swift.sourcekit-lsp.backgroundIndexing": "on",
"swift.sourcekit-lsp.trace.server": "messages",
"terminal.integrated.profiles.osx": {
"zsh": {
"path": "/bin/zsh",
"args": [
"-l",
"-i"
]
}
},
"swift.sourcekit-lsp.serverPath": "${workspaceFolder}/build-input/sourcekit-lsp",
"sourcekit-bazel-bsp.rulesAppleName": "build_bazel_rules_apple",
"cmake.sourceDirectory": "/Users/ali/build/telegram/telegram-ios/submodules/rlottie/rlottie/test"
}

19
.vscode/tasks.json vendored
View file

@ -1,19 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "sweetpad",
"action": "launch",
"problemMatcher": [
"$sweetpad-watch", // ! Required for debugging
"$sweetpad-xcodebuild-default",
"$sweetpad-xcbeautify-errors",
"$sweetpad-xcbeautify-warnings"
],
"label": "sweetpad: launch",
"detail": "Build and Launch the app",
"isBackground": true // ! Required for debugging
}
]
}

View file

@ -0,0 +1,2 @@
schemaVersion: 1
enabledWorkflows: ["simulator", "debugging", "ui-automation"]

31
BUILD.bazel Normal file
View file

@ -0,0 +1,31 @@
load("@sourcekit_bazel_bsp//rules:setup_sourcekit_bsp.bzl", "setup_sourcekit_bsp")
exports_files(["versions.json"])
setup_sourcekit_bsp(
name = "setup_sourcekit_bsp",
bazel_wrapper = "./build-input/bazel-8.4.2-darwin-arm64",
files_to_watch = [
"Telegram/**/*.swift",
"Telegram/**/*.h",
"Telegram/**/*.m",
"Telegram/**/*.mm",
"Telegram/**/*.c",
"Telegram/**/*.cpp",
"submodules/**/*.swift",
"submodules/**/*.h",
"submodules/**/*.m",
"submodules/**/*.mm",
"submodules/**/*.c",
"submodules/**/*.cpp",
],
aquery_flags = [
],
index_flags = [
"config=index_build",
],
index_build_batch_size = 10,
targets = [
"//Telegram:Telegram",
],
)

161
CLAUDE.md Normal file
View file

@ -0,0 +1,161 @@
# CLAUDE.md
This file provides guidance to AI assistants when working with code in this repository.
## Build
The app is built using Bazel via the `Make.py` wrapper. There is no selective per-module build — the only supported invocation builds the full `Telegram/Telegram` target.
**Command:**
```sh
python3 build-system/Make/Make.py --overrideXcodeVersion \
--cacheDir ~/telegram-bazel-cache \
build \
--configurationPath build-system/appstore-configuration.json \
--gitCodesigningRepository git@gitlab.com:peter-iakovlev/fastlanematch.git \
--gitCodesigningType development --gitCodesigningUseCurrent --buildNumber=1 --configuration=debug_sim_arm64
```
Add `--continueOnError` after `build` (forwards to bazel's `--keep_going`) when verifying changes that may surface errors in many files at once — it lets the full set of errors land in one pass instead of stopping at the first failing target.
The build needs `TELEGRAM_CODESIGNING_GIT_PASSWORD` in the environment. It is set in `~/.zshrc` but Claude Code's bash tool does NOT source shell config by default. Prefix build commands with `source ~/.zshrc 2>/dev/null;` to pick it up.
## Code Style Guidelines
- **Naming**: PascalCase for types, camelCase for variables/methods
- **Imports**: Group and sort imports at the top of files
- **Error Handling**: Properly handle errors with appropriate redaction of sensitive data
- **Formatting**: Use standard Swift/Objective-C formatting and spacing
- **Types**: Prefer strong typing and explicit type annotations where needed
- **Documentation**: Document public APIs with comments
## Project Structure
- Core launch and application extensions code is in `Telegram/` directory
- Most code is organized into libraries in `submodules/`
- External code is located in `third-party/`
- No tests are used at the moment
## Embedded watch app (`Telegram/WatchApp`)
A standalone watchOS Telegram client (developed in the separate `~/build/tgwatch` repo) is vendored into this repo at `Telegram/WatchApp/` and can be embedded into the **device** IPA under `Telegram.app/Watch/`. It is built by `xcodebuild` (not Bazel) and codesigned by the Bazel build.
**Build it:** add `--embedWatchApp` to a Make.py **device** build (`--configuration=debug_arm64` or `release_arm64`) together with `--watchApiId`, `--watchApiHash`, `--watchSigningIdentity`, `--watchProvisioningProfile`. Off by default (it adds a ~4-min xcodebuild step); simulator builds never embed, and the default `debug_sim_arm64` build is unaffected.
**`Telegram/WatchApp/` is a synced snapshot — do not hand-edit it.** The source of truth and dev tooling live in the `tgwatch` repo. To change the watch app, edit it there, then re-sync with `tgwatch/tools/export-sources.sh /abs/path/to/telegram-ios/Telegram/WatchApp` and commit the result. The committed `tgwatch.xcodeproj` is generated (kept via a `!tgwatch.xcodeproj` negation in `Telegram/WatchApp/.gitignore`, since the root `.gitignore` ignores `*.xcodeproj`); `.build`/`.swiftpm`/`xcuserdata` are excluded.
**How it's wired:** `//Telegram:TelegramWatchApp` (rule in `Telegram/prebuilt_watchos.bzl`) runs in **two actions**: `PrebuiltWatchosCompile` (`Telegram/prebuilt_watchos_compile.sh`) runs xcodebuild on the snapshot in a writable temp copy with PLACEHOLDER version/api values (the bundle ids are baked from the snapshot's pbxproj/Info.plist — `ph.telegra.Telegraph.watchkitapp` / `ph.telegra.Telegraph`), emitting an unsigned `.app`; `PrebuiltWatchosPatchSign` (`Telegram/prebuilt_watchos_patch.sh`) then rewrites **six** per-build Info.plist keys (`CFBundleShortVersionString`, `CFBundleVersion`, `TG_API_ID`, `TG_API_HASH`, `CFBundleIdentifier`, `WKCompanionAppBundleIdentifier`) and codesigns the `.app` + nested `TDLibFramework.framework` (identity + the watchkitapp profile from `--define`s). The result feeds the `Telegram` `ios_application`'s `watch_application` slot (gated by the `//Telegram:embedWatchApp` flag). The rule takes `bundle_id` (set to `"{telegram_bundle_id}.watchkitapp"` in `Telegram/BUILD`) and derives the host bundle id by stripping the `.watchkitapp` suffix; both are passed to the patch worker as args (not action inputs), so the patch action re-runs when the host bundle id changes but the (expensive) compile stays cached. **The compile action's only inputs are the snapshot (+ its worker)** — so changing the version, build number, api id/hash, host bundle id, or signing identity re-runs only the cheap patch+sign action, not xcodebuild; xcodebuild re-runs only when the snapshot changes. This is correct because none of those values reach the compiled binary: each lands only in the Info.plist (via `$(...)` substitution and a runtime `Bundle.main.object(forInfoDictionaryKey:)` lookup in `Secrets.swift`, except for the bundle-id keys which only Info.plist consumers read).
**Non-obvious invariants** (also in the `.bzl` comments): `AppleBundleInfo`'s public init is banned — use the internal `new_applebundleinfo`; `watch_application` requires BOTH `AppleBundleInfo` (with a non-None `infoplist` File) AND `WatchosApplicationBundleInfo`; the embedded watch app's `CFBundleShortVersionString`/`CFBundleVersion` must exactly equal the host's (sourced from `versions.json['app']` + `--define=buildNumber`); the host does NOT re-sign the embedded watch app, so the worker must sign it; the watch bundle id `ph.telegra.Telegraph.watchkitapp` must track the host `telegram_bundle_id`.
**Status:** verified with **development** signing on `debug_arm64` only. Open follow-ups before App Store shipping: secure timestamp (drop `codesign --timestamp=none`), distribution profile (`get-task-allow=false`), `release_arm64` + `altool --validate-app`, and committing a `Package.resolved` for hermetic remote-SwiftPM resolution.
## View frame ownership
A view does not control its own `frame`. The parent (or a layout system) sets the frame; the view positions its own subviews against `self.bounds` in response.
This matters in two places specifically:
- **Reusable components (`UIView`/`ASDisplayNode` subclasses).** Public methods like `update(...)` / `apply(...)` rebuild internal state, mutate child frames, and read `self.bounds` to lay them out — but they do not write `self.frame`. The caller has already chosen the frame; mutating it from inside the component overrides that choice and fights the parent's next layout pass.
- **`asyncLayout`-style content nodes.** The measure pass runs off-main and returns a size; the apply step runs on main and the chat layout system positions the node. A child view that writes `self.frame` from `update()` corrupts the size the parent just measured.
Rare exceptions: top-level view-controller views integrating with the system's first-responder/inset model. If you find yourself wanting `self.frame = …` from inside a child view, refactor so the parent positions it instead.
## InstantPage V2 & rich-text messages
Typed markdown with structure the regular message-entity set can't represent (headings, lists, tables, formulas, nested blockquotes) is sent as a **rich message** — a `RichTextMessageAttribute` carrying an `InstantPage`, drawn by `ChatMessageRichDataBubbleContentNode` via the **InstantPage V2** renderer (with AI-streaming progressive reveal, inline custom emoji, and entity cases). The detailed architecture and non-obvious invariants — streaming reveal, V2 table/text-box layout, custom-emoji & entity round-trips, task-list checkboxes, nested blockquotes, thinking blocks, the markdown send / edit / copy / paste paths, and surfacing rich-message media through the shared-media/gallery/preview pipelines via `Message.effectiveMedia` — live in [`docs/instantpage-richtext.md`](docs/instantpage-richtext.md).
## Postbox → TelegramEngine refactor (in progress)
A gradual migration is underway to eliminate direct `import Postbox` from consumer submodules in favor of `TelegramEngine`.
**Historical record:** Wave-by-wave outcomes, the running tally of Postbox-free modules, the full wave-selection guidance, and the `TelegramEngine.Resources` facade inventory (also authoritatively defined in `submodules/TelegramCore/Sources/TelegramEngine/Resources/TelegramEngineResources.swift`) live in [`docs/superpowers/postbox-refactor-log.md`](docs/superpowers/postbox-refactor-log.md). Read that file when you need wave-specific context, a full worked example of a pattern, or the history of a particular module's migration.
See the log for per-wave detail; the current wave count and the list of still-open migration opportunities live in the `project_postbox_refactor_next_wave.md` memory file.
### Rules that apply to every wave
1. `TelegramCore` does **not** `@_exported import Postbox`. Once a consumer drops `import Postbox`, every remaining Postbox-type reference must use an engine-typealiased equivalent.
2. **Never typealias `Postbox`, `Account`, or `MediaBox`.** These umbrella types rename without encapsulating. Narrow utility typealiases (`MemoryBuffer`, `PostboxDecoder`, `PostboxEncoder`, `AdaptedPostboxDecoder`, `MediaResource`, …) remain allowed and expected.
3. No new engine wrapper **structs** unless the wave's spec explicitly allows — only typealiases and thin forwarding methods.
4. **Discovery first:** before adding any new engine wrapper/typealias, grep `submodules/TelegramCore/Sources/TelegramEngine/` for existing equivalents. Record the search result in the commit message.
5. **Abandonment protocol:** if a module can only be refactored by violating rule 2 or by editing a module outside the current wave's list, mark the task Abandoned with a recorded reason. Do NOT substitute a new module mid-wave.
6. Full project build per module. No unit tests exist in this project.
7. **TelegramCore never imports UIKit/Display.** `TelegramCore` is shared with the Telegram-Mac codebase; its Bazel `deps` and source files must not reference UIKit, Display, or any Apple-UI framework. UIKit-needing helpers (image scaling, rendering, etc.) stay in consumer-side submodules.
8. **Never substitute Postbox protocols (`Media`, `Peer`, `Message`) with `Any` / `AnyObject`** in code that previously used them. Type erasure throws away the domain semantics that the next reader expects. Use the matching engine wrapper (`EngineMedia`, `EnginePeer`, `EngineMessage`) — extending it as needed (e.g. add a missing case-init or convenience). If neither typealias nor wrapper covers the use site, restore the original Postbox import + type for now and flag the case for a future facade. Existing `Any`/`AnyObject` parameters predating the refactor are not in scope for this rule.
### Engine typealias cheat sheet (existing aliases)
```
PeerId → EnginePeer.Id
MessageId → EngineMessage.Id
MessageIndex → EngineMessage.Index
MessageTags → EngineMessage.Tags
MessageAttribute → EngineMessage.Attribute
MessageFlags → EngineMessage.Flags
MessageForwardInfo → EngineMessage.ForwardInfo
MediaId → EngineMedia.Id
PreferencesEntry → EnginePreferencesEntry
TempBox → EngineTempBox
PinnedItemId → EngineChatList.PinnedItem.Id
MemoryBuffer → EngineMemoryBuffer (added 2026-04)
PostboxDecoder → EnginePostboxDecoder (added 2026-04)
PostboxEncoder → EnginePostboxEncoder (added 2026-04)
AdaptedPostboxDecoder → EngineAdaptedPostboxDecoder (added 2026-04)
ItemCollectionId → EngineItemCollectionId (added 2026-04-20)
FetchResourceSourceType → EngineFetchResourceSourceType (added 2026-04-20)
FetchResourceError → EngineFetchResourceError (added 2026-04-20)
StoryId → EngineStoryId (added 2026-05-02)
ChatListIndex → EngineChatListIndex (added 2026-05-03)
TempBoxFile → EngineTempBoxFile (added 2026-05-03)
ItemCollectionItemIndex → EngineItemCollectionItemIndex (added 2026-05-03)
ItemCollectionViewEntryIndex → EngineItemCollectionViewEntryIndex (added 2026-05-03)
ValueBoxEncryptionParameters → EngineValueBoxEncryptionParameters (added 2026-05-03)
MessageAndThreadId → EngineMessageAndThreadId (added 2026-05-03)
PeerStoryStats → EnginePeerStoryStats (added 2026-05-03)
MessageHistoryAnchorIndex → EngineMessageHistoryAnchorIndex (added 2026-05-03)
ChatListTotalUnreadStateCategory → EngineChatListTotalUnreadStateCategory (added 2026-05-03)
ChatListTotalUnreadStateStats → EngineChatListTotalUnreadStateStats (added 2026-05-03)
PeerSummaryCounterTags → EnginePeerSummaryCounterTags (added 2026-05-03)
ChatListTotalUnreadState → EngineChatListTotalUnreadState (added 2026-05-04)
ItemCacheEntryId → EngineItemCacheEntryId (added 2026-05-04)
HashFunctions → EngineHashFunctions (added 2026-05-04 wave 251)
CachedMediaResourceRepresentationResult → EngineCachedMediaResourceRepresentationResult (added 2026-05-04 wave 265)
MediaResourceDataFetchResult → EngineMediaResourceDataFetchResult (added 2026-05-04 wave 266)
MediaResourceDataFetchError → EngineMediaResourceDataFetchError (added 2026-05-04 wave 266)
MediaResourceStatus → EngineMediaResourceStatus (added 2026-05-04 wave 272)
```
**Free-function thin forwarders in TelegramCore** (rule 3 allows):
- `engineFileSize(_ path:, useTotalFileAllocatedSize: Bool = false)` — forwards to Postbox's `fileSize(...)` (added 2026-05-04 wave 268)
**TelegramEngineUnauthorized.resources facade**: `UnauthorizedResources.storeResourceData(id: EngineMediaResource.Id, data:, synchronous:)` — bridges to `account.postbox.mediaBox.storeResourceData` (added 2026-05-04 wave 271)
For the `MediaResource` Postbox protocol, prefer the TelegramCore subtype `TelegramMediaResource` when the consumer's usage allows (note: `EngineMediaResource` is a wrapper **class**, not a typealias, so it is not interchangeable with the protocol).
### MediaResource → EngineMediaResource consumer migration
`EngineMediaResource` is a `final class` in `TelegramCore` wrapping a `MediaResource` value. Unlike the typealiases above it is **not** interchangeable with the protocol, but it does provide wrap/unwrap helpers:
- `EngineMediaResource(rawResource)` — wrap a raw `MediaResource`.
- `engineResource._asResource()` — unwrap to the raw `MediaResource`.
- `EngineMediaResource.ResourceData(rawResourceData)` — wrap `MediaResourceData`.
- `EngineMediaResource.Id(rawMediaResourceId)` — wrap `MediaResourceId`.
**Pattern for facade functions:** when a `TelegramEngine.<Area>` method leaks raw `MediaResource` in its public signature, **change the facade signature in place** to `EngineMediaResource` (and change any closure parameter types the same way). Bridge inside the facade body by calling the existing `_internal_*` function with `engineResource._asResource()` / wrapping raw inputs from inner closures with `EngineMediaResource(rawResource)`. Update all call sites in the same commit. The `_internal_*` function stays on raw `MediaResource` — it is the Postbox-facing layer.
Do **not** add opt-in `EngineMediaResource` overloads alongside raw-`MediaResource` overloads. Duplicate signatures fragment the public API and leave the leak in place forever.
For consumer modules, prefer `EngineMediaResource` as the type in properties, locals, generic arguments and function parameters when the usage is a pure type reference. Do **not** try to use `EngineMediaResource` where a class must conform to `TelegramMediaResource` (Postbox protocol) or override `isEqual(to: MediaResource)` — those remain `import Postbox`.
## tgcalls Testbench
This repo includes a tgcalls testbench (CLI tool, Go/Pion SFU, Docker build) layered on top of the iOS source. All testbench code, build instructions, and architecture docs live inside the tgcalls submodule:
- `submodules/TgVoipWebrtc/tgcalls/CLAUDE.md` — top-level testbench overview, build/run commands
- `submodules/TgVoipWebrtc/tgcalls/tools/cli/CLAUDE.md` — CLI test tool architecture
- `submodules/TgVoipWebrtc/tgcalls/tools/go_sfu/CLAUDE.md` — Go SFU internals
- `submodules/TgVoipWebrtc/CLAUDE.md` — tgcalls library internals + macOS/Linux build patches
Build the test binary from this directory with:
`./build-input/bazel-8.4.2 build //submodules/TgVoipWebrtc/tgcalls/tools/cli:tgcalls_cli`

View file

@ -1,6 +1,89 @@
###############################################################################
# Bazel now uses Bzlmod by default to manage external dependencies.
# Please consider migrating your external dependencies from WORKSPACE to MODULE.bazel.
#
# For more details, please check https://github.com/bazelbuild/bazel/issues/18958
###############################################################################
http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
bazel_dep(name = "bazel_features", version = "1.33.0")
bazel_dep(name = "bazel_skylib", version = "1.8.1")
bazel_dep(name = "platforms", version = "0.0.11")
bazel_dep(name = "rules_go", version = "0.60.0", repo_name = "io_bazel_rules_go")
go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk")
go_sdk.download(version = "1.24.2")
bazel_dep(name = "gazelle", version = "0.43.0", repo_name = "bazel_gazelle")
go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//submodules/TgVoipWebrtc/tgcalls/tools/go_sfu:go.mod")
use_repo(
go_deps,
"com_github_pion_datachannel",
"com_github_pion_dtls_v3",
"com_github_pion_ice_v4",
"com_github_pion_logging",
"com_github_pion_rtcp",
"com_github_pion_sctp",
"com_github_pion_srtp_v3",
)
bazel_dep(name = "rules_xcodeproj")
local_path_override(
module_name = "rules_xcodeproj",
path = "./build-system/bazel-rules/rules_xcodeproj",
)
bazel_dep(name = "rules_apple", repo_name = "build_bazel_rules_apple")
local_path_override(
module_name = "rules_apple",
path = "./build-system/bazel-rules/rules_apple",
)
bazel_dep(name = "rules_swift", repo_name = "build_bazel_rules_swift")
local_path_override(
module_name = "rules_swift",
path = "./build-system/bazel-rules/rules_swift",
)
bazel_dep(name = "apple_support", repo_name = "build_bazel_apple_support")
local_path_override(
module_name = "apple_support",
path = "./build-system/bazel-rules/apple_support",
)
http_file(
name = "cmake_tar_gz",
sha256 = "3be85f5b999e327b1ac7d804cbc9acd767059e9f603c42ec2765f6ab68fbd367",
urls = ["https://github.com/Kitware/CMake/releases/download/v4.1.2/cmake-4.1.2-macos-universal.tar.gz"],
)
http_file(
name = "meson_tar_gz",
sha256 = "999b65f21c03541cf11365489c1fad22e2418bb0c3d50ca61139f2eec09d5496",
urls = ["https://github.com/mesonbuild/meson/releases/download/1.6.0/meson-1.6.0.tar.gz"],
)
http_file(
name = "ninja-mac_zip",
sha256 = "89a287444b5b3e98f88a945afa50ce937b8ffd1dcc59c555ad9b1baf855298c9",
urls = ["https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-mac.zip"],
)
http_file(
name = "flatbuffers_zip",
sha256 = "c5cd6a605ff20350c7faa19d8eeb599df6117ea4aabd16ac58a7eb5ba82df4e7",
urls = ["https://github.com/google/flatbuffers/archive/refs/tags/v24.12.23.zip"],
)
provisioning_profile_repository = use_extension("@build_bazel_rules_apple//apple:apple.bzl", "provisioning_profile_repository_extension")
#provisioning_profile_repository.setup(
# fallback_profiles = "//path/to/some:filegroup", # Profiles to use if one isn't found locally
#)
bazel_dep(name = "build_configuration")
local_path_override(
module_name = "build_configuration",
path = "./build-input/configuration-repository",
)
bazel_dep(name = "sourcekit_bazel_bsp", version = "0.7.1")
local_path_override(
module_name = "sourcekit_bazel_bsp",
path = "build-system/bazel-rules/sourcekit-bazel-bsp",
)

1136
MODULE.bazel.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1 +1 @@
9677ed109bd94f16fece4cf5e4ca033f
c27f02cf6e413fdc

View file

@ -8,33 +8,37 @@ load("@build_bazel_rules_apple//apple:ios.bzl",
"ios_application",
"ios_extension",
"ios_framework",
"ios_unit_test",
"ios_ui_test",
"ios_ui_test_suite",
)
load(
"@build_bazel_rules_apple//apple/testing/default_runner:ios_test_runner.bzl",
"ios_test_runner",
)
load("@build_bazel_rules_apple//apple:resources.bzl",
"swift_intent_library",
)
load("@build_bazel_rules_apple//apple:watchos.bzl",
"watchos_application",
"watchos_extension",
)
load("@build_bazel_rules_swift//swift:swift.bzl",
"swift_library",
)
load(
"@rules_xcodeproj//xcodeproj:defs.bzl",
"top_level_target",
"top_level_targets",
"top_level_target",
"xcodeproj",
"xcode_provisioning_profile",
)
load("@build_bazel_rules_apple//apple:apple.bzl", "local_provisioning_profile")
load("//Telegram:prebuilt_watchos.bzl",
"apple_prebuilt_watchos_application",
)
load("//build-system/bazel-utils:plist_fragment.bzl",
"plist_fragment",
)
@ -48,13 +52,16 @@ load(
"telegram_team_id",
"telegram_enable_icloud",
"telegram_enable_siri",
"telegram_enable_watch",
)
load("@build_bazel_rules_apple//apple:resources.bzl",
"swift_intent_library",
)
load("//build-system/bazel-utils:spm.bzl",
"generate_spm",
)
config_setting(
name = "debug",
values = {
@ -94,6 +101,19 @@ config_setting(
},
)
bool_flag(
name = "embedWatchApp",
build_setting_default = False,
visibility = ["//visibility:public"],
)
config_setting(
name = "embedWatchAppSetting",
flag_values = {
":embedWatchApp": "True",
},
)
config_setting(
name = "projectIncludeReleaseSetting",
flag_values = {
@ -140,8 +160,7 @@ genrule(
],
)
minimum_os_version = "12.0"
minimum_watchos_version="9.0"
minimum_os_version = "13.0"
notificationServiceExtensionVersion = "v1"
@ -255,13 +274,6 @@ filegroup(
],
)
filegroup(
name = "WatchAppStringResources",
srcs = glob([
"Telegram-iOS/*.lproj/Localizable.strings",
], exclude = ["Telegram-iOS/*.lproj/**/.*"]),
)
filegroup(
name = "AppIntentVocabularyResources",
srcs = glob([
@ -297,13 +309,6 @@ filegroup(
], exclude = ["Telegram-iOS/DefaultAppIcon.xcassets/**/.*"]),
)
filegroup(
name = "BlackAppIcon",
srcs = glob([
"Telegram-iOS/BlackIcon.xcassets/**/*",
], exclude = ["Telegram-iOS/BlackIcon.xcassets/**/.*"]),
)
filegroup(
name = "DefaultIcon",
srcs = glob([
@ -311,13 +316,6 @@ filegroup(
]),
)
filegroup(
name = "AdditionalIcons",
srcs = glob([
"Telegram-iOS/*.png",
]),
)
alternate_icon_folders = [
"BlackIcon",
"BlackClassicIcon",
@ -333,6 +331,8 @@ alternate_icon_folders = [
"PremiumTurbo",
]
composer_icon_folders = ["Telegram"]
[
filegroup(
name = "{}".format(name),
@ -342,6 +342,15 @@ alternate_icon_folders = [
) for name in alternate_icon_folders
]
[
filegroup(
name = "{}_icon".format(name),
srcs = glob([
"Telegram-iOS/{}.icon/**/*".format(name),
]),
) for name in composer_icon_folders
]
filegroup(
name = "LaunchScreen",
srcs = glob([
@ -351,6 +360,7 @@ filegroup(
objc_library(
name = "Main",
module_name = "Main",
srcs = [
"Telegram-iOS/main.m"
],
@ -358,6 +368,7 @@ objc_library(
swift_library(
name = "Lib",
module_name = "Lib",
srcs = glob([
"Telegram-iOS/Application.swift",
]),
@ -391,7 +402,8 @@ plist_fragment(
"""
<key>CFBundleVersion</key>
<string>{buildNumber}</string>
"""
""",
defaults = {"buildNumber": "1"},
)
plist_fragment(
@ -493,7 +505,7 @@ icloud_fragment = "" if not telegram_enable_icloud else """
<string>iCloud.{telegram_bundle_id}</string>
</array>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>{telegram_team_id}.*</string>
<string>{telegram_team_id}.{telegram_bundle_id}</string>
<key>com.apple.developer.icloud-container-environment</key>
<string>{telegram_icloud_environment}</string>
""".format(
@ -508,6 +520,8 @@ associated_domains_fragment = "" if telegram_bundle_id not in official_bundle_id
<string>applinks:telegram.me</string>
<string>applinks:t.me</string>
<string>applinks:*.t.me</string>
<string>webcredentials:t.me</string>
<string>webcredentials:telegram.org</string>
</array>
"""
@ -539,6 +553,12 @@ official_communication_notifications_fragment = """
"""
communication_notifications_fragment = official_communication_notifications_fragment if telegram_bundle_id in official_bundle_ids else ""
official_notification_filtering_fragment = """
<key>com.apple.developer.usernotifications.filtering</key>
<true/>
"""
notification_filtering_fragment = official_notification_filtering_fragment if telegram_bundle_id == "ph.telegra.Telegraph" else ""
store_signin_fragment = """
<key>com.apple.developer.applesignin</key>
<array>
@ -547,6 +567,12 @@ store_signin_fragment = """
"""
signin_fragment = store_signin_fragment if telegram_bundle_id in store_bundle_ids else ""
official_background_gpu_fragment = """
<key>com.apple.developer.background-tasks.continued-processing.gpu</key>
<true/>
"""
background_gpu_fragment = official_background_gpu_fragment if telegram_bundle_id == "ph.telegra.Telegraph" else ""
plist_fragment(
name = "TelegramEntitlements",
extension = "entitlements",
@ -560,74 +586,29 @@ plist_fragment(
unrestricted_voip_fragment,
carplay_fragment,
communication_notifications_fragment,
notification_filtering_fragment,
signin_fragment,
background_gpu_fragment,
])
)
filegroup(
name = "TelegramWatchExtensionResources",
srcs = glob([
"Watch/Extension/Resources/**/*",
], exclude = ["Watch/Extension/Resources/**/.*"]),
)
filegroup(
name = "TelegramWatchAppResources",
srcs = glob([
"Watch/Extension/Resources/**/*.png",
], exclude = ["Watch/Extension/Resources/**/.*"]),
)
filegroup(
name = "TelegramWatchAppAssets",
srcs = glob([
"Watch/App/Assets.xcassets/**/*",
], exclude = ["Watch/App/Assets.xcassets/**/.*"]),
)
filegroup(
name = "TelegramWatchAppInterface",
srcs = glob([
"Watch/App/Base.lproj/Interface.storyboard",
]),
)
objc_library(
name = "TelegramWatchLib",
srcs = glob([
"Watch/Extension/**/*.m",
"Watch/SSignalKit/**/*.m",
"Watch/Bridge/**/*.m",
"Watch/WatchCommonWatch/**/*.m",
"Watch/Extension/**/*.h",
"Watch/SSignalKit/**/*.h",
"Watch/Bridge/**/*.h",
"Watch/WatchCommonWatch/**/*.h",
]),
copts = [
"-DTARGET_OS_WATCH=1",
"-ITelegram/Watch",
"-ITelegram/Watch/Extension",
"-ITelegram/Watch/Bridge",
],
sdk_frameworks = [
"WatchKit",
"WatchConnectivity",
"ClockKit",
"UserNotifications",
"CoreLocation",
"CoreGraphics",
],
)
plist_fragment(
genrule(
name = "VersionInfoPlist",
extension = "plist",
template =
"""
srcs = ["//:versions.json"],
outs = ["VersionInfoPlist.plist"],
cmd = """
version=$$(python3 -c "import json; print(json.load(open('$(location //:versions.json)'))['app'])")
cat > $@ <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>{telegramVersion}</string>
"""
<string>$$version</string>
</dict>
</plist>
PLIST
""",
)
plist_fragment(
@ -652,162 +633,6 @@ plist_fragment(
"""
)
plist_fragment(
name = "WatchExtensionNSExtensionInfoPlist",
extension = "plist",
template =
"""
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>WKAppBundleIdentifier</key>
<string>{telegram_bundle_id}.watchkitapp</string>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.watchkit</string>
</dict>
""".format(
telegram_bundle_id = telegram_bundle_id,
)
)
plist_fragment(
name = "WatchAppCompanionInfoPlist",
extension = "plist",
template =
"""
<key>WKCompanionAppBundleIdentifier</key>
<string>{telegram_bundle_id}</string>
""".format(
telegram_bundle_id = telegram_bundle_id,
)
)
plist_fragment(
name = "WatchExtensionInfoPlist",
extension = "plist",
template =
"""
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>{telegram_bundle_id}.watchkitapp.watchkitextension</string>
<key>CFBundleName</key>
<string>Telegram</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>WKExtensionDelegateClassName</key>
<string>TGExtensionDelegate</string>
""".format(
telegram_bundle_id = telegram_bundle_id,
)
)
plist_fragment(
name = "WatchAppInfoPlist",
extension = "plist",
template =
"""
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleIdentifier</key>
<string>{telegram_bundle_id}.watchkitapp</string>
<key>CFBundleName</key>
<string>Telegram</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>WKWatchKitApp</key>
<true/>
<key>CFBundlePackageType</key>
<string>APPL</string>
""".format(
telegram_bundle_id = telegram_bundle_id,
)
)
watchos_extension(
name = "TelegramWatchExtension",
bundle_id = "{telegram_bundle_id}.watchkitapp.watchkitextension".format(
telegram_bundle_id = telegram_bundle_id,
),
bundle_name = "TelegramWatchExtension",
infoplists = [
":WatchExtensionInfoPlist",
":VersionInfoPlist",
":BuildNumberInfoPlist",
":AppNameInfoPlist",
":WatchExtensionNSExtensionInfoPlist",
],
minimum_os_version = minimum_watchos_version,
provisioning_profile = select({
":disableProvisioningProfilesSetting": None,
"//conditions:default": "@build_configuration//provisioning:WatchExtension.mobileprovision",
}),
resources = [
":TelegramWatchExtensionResources",
],
strings = [
":WatchAppStringResources",
],
deps = [
":TelegramWatchLib",
],
)
genrule(
name = "StripWatchosStubBinary",
cmd_bash =
"""
echo 'lipo -remove armv7k -remove arm64 -remove arm64e $$1/TelegramWatch.app/_WatchKitStub/WK -output $$1/TelegramWatch.app/_WatchKitStub/WK' > $(location StripWatchosStubBinary.sh)
echo '' >> $(location StripWatchosStubBinary.sh)
""",
outs = [
"StripWatchosStubBinary.sh",
],
executable = True,
visibility = [
"//visibility:public",
]
)
watchos_application(
name = "TelegramWatchApp",
bundle_id = "{telegram_bundle_id}.watchkitapp".format(
telegram_bundle_id = telegram_bundle_id,
),
bundle_name = "TelegramWatch",
extension = ":TelegramWatchExtension",
infoplists = [
":WatchAppInfoPlist",
":VersionInfoPlist",
":BuildNumberInfoPlist",
":AppNameInfoPlist",
":WatchAppCompanionInfoPlist",
],
minimum_os_version = minimum_watchos_version,
provisioning_profile = select({
":disableProvisioningProfilesSetting": None,
"//conditions:default": "@build_configuration//provisioning:WatchApp.mobileprovision",
}),
ipa_post_processor = ":StripWatchosStubBinary",
resources = [
":TelegramWatchAppResources",
":TelegramWatchAppAssets",
],
storyboards = [
":TelegramWatchAppInterface",
],
strings = [
],
)
plist_fragment(
name = "MtProtoKitInfoPlist",
extension = "plist",
@ -952,29 +777,6 @@ plist_fragment(
)
)
ios_framework(
name = "TelegramApiFramework",
bundle_id = "{telegram_bundle_id}.TelegramApi".format(
telegram_bundle_id = telegram_bundle_id,
),
families = [
"iphone",
"ipad",
],
infoplists = [
":TelegramApiInfoPlist",
":BuildNumberInfoPlist",
":VersionInfoPlist",
":RequiredDeviceCapabilitiesPlist",
],
minimum_os_version = minimum_os_version,
extension_safe = True,
ipa_post_processor = strip_framework,
deps = [
"//submodules/TelegramApi:TelegramApi",
],
)
plist_fragment(
name = "TelegramCoreInfoPlist",
extension = "plist",
@ -1759,6 +1561,7 @@ plist_fragment(
<array>
<string>{telegram_bundle_id}.refresh</string>
<string>{telegram_bundle_id}.cleanup</string>
<string>{telegram_bundle_id}.upload.*</string>
</array>
<key>CFBundleAllowMixedLocalizations</key>
<true/>
@ -1784,6 +1587,8 @@ plist_fragment(
<string>here-location</string>
<string>yandexmaps</string>
<string>yandexnavi</string>
<string>yandextaxi</string>
<string>yangoride</string>
<string>comgooglemaps</string>
<string>youtube</string>
<string>twitter</string>
@ -1811,6 +1616,8 @@ plist_fragment(
<string>ucbrowser</string>
<string>dolphin</string>
<string>instagram-stories</string>
<string>yangomaps</string>
<string>vivaldi</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
@ -1848,7 +1655,6 @@ plist_fragment(
</array>
<key>UIAppFonts</key>
<array>
<string>SFCompactRounded-Semibold.otf</string>
<string>AremacFS-Regular.otf</string>
<string>AremacFS-Semibold.otf</string>
</array>
@ -1888,7 +1694,7 @@ plist_fragment(
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<true/>
<key>UIViewEdgeAntialiasing</key>
<false/>
<key>UIViewGroupOpacity</key>
@ -1938,6 +1744,19 @@ xcode_provisioning_profile(
provisioning_profile = ":Telegram_local_profile",
)
apple_prebuilt_watchos_application(
name = "TelegramWatchApp",
# Watch bundle id tracks the host config ("<host>.watchkitapp"). The rule passes it
# to xcodebuild as PRODUCT_BUNDLE_IDENTIFIER (baked + signed); the watch Info.plist
# derives WKCompanionAppBundleIdentifier from it via $(PRODUCT_BUNDLE_IDENTIFIER:base),
# so the embedded watch app is correct for any host (ph.telegra.Telegraph,
# org.telegram.TelegramInternal, ...) with no post-build plist patching.
bundle_id = "{telegram_bundle_id}.watchkitapp".format(
telegram_bundle_id = telegram_bundle_id,
),
tags = ["manual"],
)
ios_application(
name = "Telegram",
bundle_id = "{telegram_bundle_id}".format(
@ -1957,14 +1776,13 @@ ios_application(
":RequiredDeviceCapabilitiesPlist",
":UrlTypesInfoPlist",
],
app_icons = [ ":{}_icon".format(name) for name in composer_icon_folders ],
alternate_icons = [
":{}".format(name) for name in alternate_icon_folders
],
#ipa_post_processor = ":AddAlternateIcons",
resources = [
":LaunchScreen",
":DefaultAppIcon",
#":AdditionalIcons",
#":DefaultAppIcon",
],
frameworks = [
":MtProtoKitFramework",
@ -1987,10 +1805,13 @@ ios_application(
":BroadcastUploadExtension",
],
}),
# Embed the in-repo tgwatch watch app (Telegram/WatchApp) under Watch/ only when
# --//Telegram:embedWatchApp is set (Make.py sets it for device configs when
# --embedWatchApp is passed). Off by default, so simulator/dev builds are unaffected.
watch_application = select({
":disableExtensionsSetting": None,
"//conditions:default": None#":TelegramWatchApp",
}) if telegram_enable_watch else None,
":embedWatchAppSetting": ":TelegramWatchApp",
"//conditions:default": None,
}),
deps = [
":Main",
":Lib",
@ -2000,16 +1821,13 @@ ios_application(
xcodeproj(
name = "Telegram_xcodeproj",
build_mode = "bazel",
bazel_path = telegram_bazel_path,
project_name = "Telegram",
tags = ["manual"],
top_level_targets = top_level_targets(
labels = [
":Telegram",
],
target_environments = ["device", "simulator"],
),
top_level_targets = [
top_level_target(":Telegram", target_environments = ["device", "simulator"]),
":iOSAppUITestSuite",
],
xcode_configurations = {
"Debug": {
"//command_line_option:compilation_mode": "dbg",
@ -2021,7 +1839,83 @@ xcodeproj(
default_xcode_configuration = "Debug"
)
# Temporary targets used to simplify webrtc build tests
filegroup(
name = "TestSources",
srcs = glob(["Tests/Sources/**/*.swift"]),
)
ios_test_runner(
name = "iPhone-17__26.2",
device_type = "iPhone 17",
os_version = "26.2",
)
swift_library(
name = "iOSAppUITestSuite.library",
testonly = True,
srcs = [":TestSources"],
module_name = "iOSAppUITestSuite",
tags = ["manual"],
)
ios_ui_test_suite(
name = "iOSAppUITestSuite",
bundle_id = "org.telegram.Telegram-iOS-uitests",
minimum_os_version = minimum_os_version,
runners = [
":iPhone-17__26.2",
],
tags = ["manual"],
test_host = "//Telegram",
visibility = ["@rules_xcodeproj//xcodeproj:generated"],
deps = [":iOSAppUITestSuite.library"],
)
# Temporary targets used to simplify build tests
ios_application(
name = "spm_build_app",
bundle_id = "{telegram_bundle_id}".format(
telegram_bundle_id = telegram_bundle_id,
),
families = ["iphone", "ipad"],
minimum_os_version = minimum_os_version,
provisioning_profile = select({
":disableProvisioningProfilesSetting": None,
"//conditions:default": "@build_configuration//provisioning:Telegram.mobileprovision",
}),
entitlements = ":TelegramEntitlements.entitlements",
infoplists = [
":TelegramInfoPlist",
":BuildNumberInfoPlist",
":VersionInfoPlist",
":RequiredDeviceCapabilitiesPlist",
":UrlTypesInfoPlist",
],
deps = [
#"//submodules/Display",
#"//submodules/TelegramCore",
#"//submodules/FFMpegBinding",
#"//third-party/webrtc",
#"//third-party/webrtc:webrtc_objc",
#"//submodules/AsyncDisplayKit",
#"//submodules/ObjCRuntimeUtils",
#"//submodules/OpusBinding",
#"//third-party/boringssl:ssl",
#"//third-party/boringssl:crypto",
#"//submodules/TelegramVoip",
#"//third-party/recaptcha:RecaptchaEnterprise",
"//submodules/TelegramUI",
],
)
generate_spm(
name = "spm_build_root",
deps = [
":spm_build_app",
]
)
ios_application(
name = "webrtc_build_test",
@ -2043,7 +1937,8 @@ ios_application(
":UrlTypesInfoPlist",
],
deps = [
"//third-party/webrtc:webrtc_lib",
"//third-party/webrtc",
"//third-party/webrtc:webrtc_objc",
],
)
@ -2070,53 +1965,3 @@ ios_application(
"//third-party/libvpx:vpx",
],
)
swift_library(
name = "TelegramCoreBuildTestLib",
module_name = "TelegramCoreBuildTestLib",
srcs = glob([
"Tests/TelegramCoreBuildTest/**/*.swift",
]),
copts = [
"-warnings-as-errors",
],
data = [
":WidgetAssets",
],
deps = [
"//submodules/BuildConfig:BuildConfig",
"//submodules/WidgetItems:WidgetItems_iOS14",
"//submodules/WidgetItemsUtils:WidgetItemsUtils",
"//submodules/AppLockState:AppLockState",
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
"//submodules/Postbox:Postbox",
"//submodules/TelegramCore:TelegramCore",
"//submodules/OpenSSLEncryptionProvider:OpenSSLEncryptionProvider",
"//Telegram:GeneratedSources",
],
)
ios_application(
name = "TelegramCoreBuildTest",
bundle_id = "{telegram_bundle_id}".format(
telegram_bundle_id = telegram_bundle_id,
),
families = ["iphone", "ipad"],
minimum_os_version = minimum_os_version,
provisioning_profile = select({
":disableProvisioningProfilesSetting": None,
"//conditions:default": "@build_configuration//provisioning:Telegram.mobileprovision",
}),
entitlements = ":TelegramEntitlements.entitlements",
infoplists = [
":TelegramInfoPlist",
":BuildNumberInfoPlist",
":VersionInfoPlist",
":RequiredDeviceCapabilitiesPlist",
":UrlTypesInfoPlist",
],
frameworks = [
":TelegramCoreFramework",
],
deps = [":TelegramCoreBuildTestLib"],
)

View file

@ -6,7 +6,7 @@ import SwiftSignalKit
import BuildConfig
import BroadcastUploadHelpers
import AudioToolbox
import Postbox
import TelegramCore
import CoreMedia
import AVFoundation
@ -163,13 +163,15 @@ private final class EmbeddedBroadcastUploadImpl: BroadcastUploadImpl {
enableNoiseSuppression: false,
disableAudioInput: true,
enableSystemMute: false,
preferX264: false,
useReferenceImpl: false,
prioritizeVP8: false,
logPath: "",
onMutedSpeechActivityDetected: { _ in },
encryptionKey: nil,
isConference: false,
audioIsActiveByDefault: true,
isStream: false,
sharedAudioDevice: nil
sharedAudioDevice: nil,
encryptionContext: nil
)
self.callContext = callContext
self.joinPayloadDisposable = (callContext.joinPayload
@ -330,12 +332,12 @@ private final class EmbeddedBroadcastUploadImpl: BroadcastUploadImpl {
let rootPath = rootPathForBasePath(appGroupUrl.path)
TempBox.initializeShared(basePath: rootPath, processType: "share", launchSpecificId: Int64.random(in: Int64.min ... Int64.max))
EngineTempBox.initializeShared(basePath: rootPath, processType: "share", launchSpecificId: Int64.random(in: Int64.min ... Int64.max))
let logsPath = rootPath + "/logs/broadcast-logs"
let _ = try? FileManager.default.createDirectory(atPath: logsPath, withIntermediateDirectories: true, attributes: nil)
let embeddedBroadcastImplementationTypePath = rootPath + "/broadcast-coordination-type"
let embeddedBroadcastImplementationTypePath = rootPath + "/broadcast-coordination-type-v2"
var useIPCContext = false
if let typeData = try? Data(contentsOf: URL(fileURLWithPath: embeddedBroadcastImplementationTypePath)), let type = String(data: typeData, encoding: .utf8) {

View file

@ -23,7 +23,6 @@ swift_library(
"//submodules/PersistentStringHash:PersistentStringHash",
"//submodules/Utils/RangeSet",
"//submodules/Media/ConvertOpusToAAC",
],
visibility = [
"//visibility:public",

View file

@ -17,6 +17,9 @@ import AppLockState
import NotificationsPresentationData
import RangeSet
import ConvertOpusToAAC
import CoreServices
import ImageIO
import UniformTypeIdentifiers
private let queue = Queue()
@ -275,13 +278,18 @@ private extension CGSize {
}
}
private func convertLottieImage(data: Data) -> UIImage? {
private func convertLottieImage(data: Data, size: CGSize, forceSquare: Bool) -> UIImage? {
let decompressedData = TGGUnzipData(data, 512 * 1024) ?? data
guard let animation = LottieInstance(data: decompressedData, fitzModifier: .none, colorReplacements: nil, cacheKey: "") else {
return nil
}
let size = animation.dimensions.fitted(CGSize(width: 200.0, height: 200.0))
let context = DrawingContext(size: size, scale: 1.0, opaque: false, clear: true)
let actualSize: CGSize
if forceSquare {
actualSize = animation.dimensions.fitted(size)
} else {
actualSize = size
}
let context = DrawingContext(size: actualSize, scale: 1.0, opaque: false, clear: true)
animation.renderFrame(with: 0, into: context.bytes.assumingMemoryBound(to: UInt8.self), width: Int32(context.scaledSize.width), height: Int32(context.scaledSize.height), bytesPerRow: Int32(context.bytesPerRow))
return context.generateImage()
}
@ -486,9 +494,21 @@ private func peerAvatar(mediaBox: MediaBox, accountPeerId: PeerId, peer: Peer, i
@available(iOSApplicationExtension 10.0, iOS 10.0, *)
private struct NotificationContent: CustomStringConvertible {
struct CustomEmoji {
var range: Range<Int>
var fileId: Int64
init(range: Range<Int>, fileId: Int64) {
self.range = range
self.fileId = fileId
}
}
var title: String?
var subtitle: String?
var body: String?
var customEmoji: [CustomEmoji] = []
var resolvedEmojiFiles: [Int64: String] = [:]
var threadId: String?
var sound: String?
var badge: Int?
@ -519,6 +539,7 @@ private struct NotificationContent: CustomStringConvertible {
string += " senderImage: \(self.senderImage != nil ? "non-empty" : "empty"),\n"
string += " isLockedMessage: \(String(describing: self.isLockedMessage)),\n"
string += " attachments: \(self.attachments),\n"
string += " resolvedEmojiFiles: \(self.resolvedEmojiFiles.count) files,\n"
string += "}"
return string
}
@ -565,11 +586,51 @@ private struct NotificationContent: CustomStringConvertible {
content.title = title
}
}
if let subtitle = self.subtitle {
content.subtitle = subtitle
}
if let body = self.body {
content.body = body
if #available(iOS 18.0, *) {
if !self.resolvedEmojiFiles.isEmpty {
let attributedString = NSMutableAttributedString(string: body)
let sortedEmoji = self.customEmoji.sorted(by: { $0.range.lowerBound < $1.range.lowerBound })
for emoji in sortedEmoji.reversed() {
if emoji.range.lowerBound < 0 || emoji.range.upperBound > attributedString.length {
continue
}
guard let filePath = self.resolvedEmojiFiles[emoji.fileId] else {
continue
}
guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
continue
}
let image: UIImage
if let lottieImage = convertLottieImage(data: fileData, size: CGSize(width: 40.0, height: 40.0), forceSquare: false) {
image = lottieImage
} else if let webpImage = WebP.convert(fromWebP: fileData) {
image = webpImage
} else {
continue
}
let emojiRange = NSRange(location: emoji.range.lowerBound, length: emoji.range.upperBound - emoji.range.lowerBound)
let substring = attributedString.attributedSubstring(from: emojiRange)
let glyph = try! Customoji.makeGlyph(from: image, description: substring.string, tileSizes: [40], cropToSquare: false)
let imageString = NSAttributedString(adaptiveImageGlyph: glyph, attributes: [:])
attributedString.replaceCharacters(in: emojiRange, with: "")
attributedString.insert(imageString, at: emojiRange.lowerBound)
}
content.setValue(attributedString, forKey: "attributedBody")
} else {
content.body = body
}
} else {
content.body = body
}
}
if !content.title.isEmpty || !content.subtitle.isEmpty || !content.body.isEmpty {
@ -925,8 +986,19 @@ private final class NotificationServiceHandler {
var peer: EnginePeer?
var localContactId: String?
}
struct GroupCallData {
var id: Int64
var fromId: PeerId
var fromTitle: String
var memberCount: Int
var isVideo: Bool
var messageId: Int32
var accountId: Int64
}
var callData: CallData?
var groupCallData: GroupCallData?
if let messageIdString = payloadJson["msg_id"] as? String {
messageId = Int32(messageIdString)
@ -952,8 +1024,33 @@ private final class NotificationServiceHandler {
peerId = PeerId(namespace: Namespaces.Peer.SecretChat, id: PeerId.Id._internalFromInt64Value(encryptionIdValue))
}
}
#if DEBUG
if let locKey = payloadJson["loc-key"] as? String, locKey == "CONF_CALL_REQUEST" {
}
#endif
if let callIdString = payloadJson["call_id"] as? String, let callAccessHashString = payloadJson["call_ah"] as? String, let peerId = peerId, let updates = payloadJson["updates"] as? String {
if let peerId, let locKey = payloadJson["loc-key"] as? String, (locKey == "CONF_CALL_REQUEST" || locKey == "CONF_VIDEOCALL_REQUEST"), let callIdString = payloadJson["call_id"] as? String, let messageIdString = payloadJson["msg_id"] as? String {
if let callId = Int64(callIdString), let messageId = Int32(messageIdString) {
if let fromTitle = payloadJson["call_conference_from"] as? String {
let isVideo = locKey == "CONF_VIDEOCALL_REQUEST"
var memberCount = 0
if let callParticipantsCountString = payloadJson["call_participants_cnt"] as? String, let callParticipantsCount = Int(callParticipantsCountString) {
memberCount = callParticipantsCount
}
groupCallData = GroupCallData(
id: callId,
fromId: peerId,
fromTitle: fromTitle,
memberCount: memberCount,
isVideo: isVideo,
messageId: messageId,
accountId: recordId.int64
)
}
}
} else if let callIdString = payloadJson["call_id"] as? String, let callAccessHashString = payloadJson["call_ah"] as? String, let peerId = peerId, let updates = payloadJson["updates"] as? String {
if let callId = Int64(callIdString), let callAccessHash = Int64(callAccessHashString) {
var peer: EnginePeer?
@ -982,26 +1079,29 @@ private final class NotificationServiceHandler {
enum Action {
case logout
case poll(peerId: PeerId, content: NotificationContent, messageId: MessageId?, reportDelivery: Bool)
case poll(peerId: PeerId, content: NotificationContent, messageId: MessageId?, reportDelivery: Bool, enableInlineEmoji: Bool)
case pollStories(peerId: PeerId, content: NotificationContent, storyId: Int32, isReaction: Bool)
case deleteMessage([MessageId])
case readReactions([MessageId])
case readMessage(MessageId)
case readStories(peerId: PeerId, maxId: Int32)
case call(CallData)
case groupCall(GroupCallData)
}
var action: Action?
if let callData = callData {
action = .call(callData)
} else if let groupCallData {
action = .groupCall(groupCallData)
} else if let locKey = payloadJson["loc-key"] as? String {
switch locKey {
case "SESSION_REVOKE":
action = .logout
case "MESSAGE_MUTED":
if let peerId = peerId {
action = .poll(peerId: peerId, content: NotificationContent(isLockedMessage: nil), messageId: nil, reportDelivery: false)
action = .poll(peerId: peerId, content: NotificationContent(isLockedMessage: nil), messageId: nil, reportDelivery: false, enableInlineEmoji: false)
}
case "MESSAGE_DELETED":
if let peerId = peerId {
@ -1122,7 +1222,7 @@ private final class NotificationServiceHandler {
content.userInfo["peerId"] = "\(peerId.toInt64())"
content.userInfo["accountId"] = "\(recordId.int64)"
if let silentString = payloadJson["silent"] as? String {
if let silentValue = Int(silentString), silentValue != 0 {
content.silent = true
@ -1186,16 +1286,49 @@ private final class NotificationServiceHandler {
action = .pollStories(peerId: peerId, content: content, storyId: storyId, isReaction: isReaction)
} else {
var reportDelivery = false
if let reportDeliveryUntilDate = aps["report_delivery_until_date"] as? Int32 {
if let reportDeliveryUntilDate = aps["report_delivery_until_date"] as? String, let reportDeliveryUntilDateValue = Int32(reportDeliveryUntilDate) {
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
if reportDeliveryUntilDate > currentTime {
if reportDeliveryUntilDateValue > currentTime {
reportDelivery = true
}
}
action = .poll(peerId: peerId, content: content, messageId: messageIdValue, reportDelivery: reportDelivery)
var enableInlineEmoji = true
if let _ = aps["_ddie"] {
enableInlineEmoji = false
}
action = .poll(peerId: peerId, content: content, messageId: messageIdValue, reportDelivery: reportDelivery, enableInlineEmoji: enableInlineEmoji)
}
updateCurrentContent(content)
} else if let aps = payloadJson["aps"] as? [String: Any], let url = payloadJson["url"] as? String {
var content: NotificationContent = NotificationContent(isLockedMessage: nil)
content.userInfo["url"] = url
content.userInfo["peerId"] = "777000"
content.userInfo["accountId"] = "\(recordId.int64)"
if let sound = aps["sound"] as? String {
content.sound = sound
}
if let alert = aps["alert"] as? [String: Any] {
if let topicTitleValue = payloadJson["topic_title"] as? String {
topicTitle = topicTitleValue
if let title = alert["title"] as? String {
content.title = "\(topicTitleValue) (\(title))"
} else {
content.title = topicTitleValue
}
} else {
content.title = alert["title"] as? String
}
content.subtitle = alert["subtitle"] as? String
content.body = alert["body"] as? String
} else if let alert = aps["alert"] as? String {
content.body = alert
} else {
content.body = "You have a new message"
}
updateCurrentContent(content)
completed()
return
}
}
@ -1243,6 +1376,51 @@ private final class NotificationServiceHandler {
content.body = "Incoming Call"
}
updateCurrentContent(content)
completed()
}
})
}
case let .groupCall(groupCallData):
if let stateManager = strongSelf.stateManager {
let content = NotificationContent(isLockedMessage: nil)
updateCurrentContent(content)
let _ = (stateManager.postbox.transaction { transaction -> TelegramUser? in
return transaction.getPeer(groupCallData.fromId) as? TelegramUser
}).start(next: { fromPeer in
var voipPayload: [AnyHashable: Any] = [
"group_call_id": "\(groupCallData.id)",
"msg_id": "\(groupCallData.messageId)",
"video": "\(groupCallData.isVideo ? 1 : 0)",
"member_count": "\(groupCallData.memberCount)",
"from_id": "\(groupCallData.fromId.id._internalGetInt64Value())",
"from_title": groupCallData.fromTitle,
"accountId": "\(groupCallData.accountId)"
]
if let phoneNumber = fromPeer?.phone {
voipPayload["phoneNumber"] = phoneNumber
}
if #available(iOS 14.5, *), voiceCallSettings.enableSystemIntegration {
Logger.shared.log("NotificationService \(episode)", "Will report voip notification")
let content = NotificationContent(isLockedMessage: nil)
updateCurrentContent(content)
CXProvider.reportNewIncomingVoIPPushPayload(voipPayload, completion: { error in
Logger.shared.log("NotificationService \(episode)", "Did report voip notification, error: \(String(describing: error))")
completed()
})
} else {
var content = NotificationContent(isLockedMessage: nil)
if let peer = fromPeer {
content.title = peer.debugDisplayTitle
content.body = incomingCallMessage
} else {
content.body = "Incoming Call"
}
updateCurrentContent(content)
completed()
}
@ -1254,7 +1432,7 @@ private final class NotificationServiceHandler {
let content = NotificationContent(isLockedMessage: nil)
updateCurrentContent(content)
completed()
case let .poll(peerId, initialContent, messageId, reportDelivery):
case let .poll(peerId, initialContent, messageId, reportDelivery, enableInlineEmoji):
Logger.shared.log("NotificationService \(episode)", "Will poll")
if let stateManager = strongSelf.stateManager {
let shouldKeepConnection = stateManager.network.shouldKeepConnection
@ -1273,7 +1451,7 @@ private final class NotificationServiceHandler {
let mediaAttachment = mediaAttachment ?? customMedia
var fetchMediaSignal: Signal<Data?, NoError> = .single(nil)
if let mediaAttachment = mediaAttachment {
if let mediaAttachment {
var contentType: MediaResourceUserContentType = .other
var fetchResource: TelegramMultipartFetchableResource?
if let image = mediaAttachment as? TelegramMediaImage, let representation = largestImageRepresentation(image.representations), let resource = representation.resource as? TelegramMultipartFetchableResource {
@ -1440,10 +1618,146 @@ private final class NotificationServiceHandler {
}
let wasDisplayed = stateManager.postbox.transaction { transaction -> Bool in
var wasDisplayed = false
if let messageId {
return _internal_getMessageNotificationWasDisplayed(transaction: transaction, id: messageId)
} else {
return false
wasDisplayed = _internal_getMessageNotificationWasDisplayed(transaction: transaction, id: messageId)
}
return wasDisplayed
}
let maxEmojiCount: Int = 10
var uniqueEmojiIds: [Int64] = []
for emoji in content.customEmoji {
if !uniqueEmojiIds.contains(emoji.fileId) {
uniqueEmojiIds.append(emoji.fileId)
if uniqueEmojiIds.count >= maxEmojiCount {
break
}
}
}
let resolvedEmojiFiles: Signal<[Int64: String], NoError> = _internal_resolveInlineStickers(postbox: stateManager.postbox, network: stateManager.network, fileIds: uniqueEmojiIds)
|> mapToSignal { files -> Signal<[Int64: String], NoError> in
var fetchSignals: [Signal<(Int64, String?), NoError>] = []
for (_, file) in files {
if let resource = file.resource as? TelegramMultipartFetchableResource {
let fetchSignal: Signal<(Int64, String?), NoError>
if let path = stateManager.postbox.mediaBox.completedResourcePath(resource) {
fetchSignal = .single((file.fileId.id, path))
} else {
let intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError> = .single([(0 ..< Int64.max, MediaBoxFetchPriority.maximum)])
let fetchDataSignal: Signal<Data?, NoError> = Signal { subscriber in
final class DataValue {
var data = Data()
var missingRanges = RangeSet<Int64>(0 ..< Int64.max)
}
let collectedData = Atomic<DataValue>(value: DataValue())
return standaloneMultipartFetch(
accountPeerId: stateManager.accountPeerId,
postbox: stateManager.postbox,
network: stateManager.network,
resource: resource,
datacenterId: resource.datacenterId,
size: nil,
intervals: intervals,
parameters: MediaResourceFetchParameters(
tag: nil,
info: resourceFetchInfo(resource: resource),
location: messageId.flatMap { messageId in
return MediaResourceStorageLocation(
peerId: peerId,
messageId: messageId
)
},
contentType: .sticker,
isRandomAccessAllowed: true
),
encryptionKey: nil,
decryptedSize: nil,
continueInBackground: false,
useMainConnection: true
).start(next: { result in
switch result {
case let .dataPart(offset, data, dataRange, _):
var isCompleted = false
let _ = collectedData.modify { current in
let current = current
let fillRange = Int(offset) ..< (Int(offset) + data.count)
if current.data.count < fillRange.upperBound {
current.data.count = fillRange.upperBound
}
current.data.withUnsafeMutableBytes { buffer -> Void in
let bytes = buffer.baseAddress!.assumingMemoryBound(to: UInt8.self)
data.copyBytes(to: bytes.advanced(by: Int(offset)), from: Int(dataRange.lowerBound) ..< Int(dataRange.upperBound))
}
current.missingRanges.remove(contentsOf: Int64(fillRange.lowerBound) ..< Int64(fillRange.upperBound))
if current.missingRanges.isEmpty {
isCompleted = true
}
return current
}
if isCompleted {
let data = collectedData.with({ $0.data })
subscriber.putNext( data)
subscriber.putCompletion()
}
case let .resourceSizeUpdated(size):
var isCompleted = false
let _ = collectedData.modify { current in
let current = current
current.missingRanges.remove(contentsOf: size ..< Int64.max)
if current.missingRanges.isEmpty {
isCompleted = true
}
return current
}
if isCompleted {
let data = collectedData.with({ $0.data })
subscriber.putNext(data)
subscriber.putCompletion()
}
default:
break
}
}, error: { _ in
subscriber.putNext(nil)
subscriber.putCompletion()
}, completed: {
let data = collectedData.with({ $0.data })
subscriber.putNext(data)
subscriber.putCompletion()
})
}
fetchSignal = fetchDataSignal |> map { data -> (Int64, String?) in
guard let data else {
return (file.fileId.id, nil)
}
stateManager.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
if let path = stateManager.postbox.mediaBox.completedResourcePath(resource) {
return (file.fileId.id, path)
} else {
return (file.fileId.id, nil)
}
}
}
fetchSignals.append(fetchSignal)
}
}
return combineLatest(fetchSignals)
|> map { results -> [Int64: String] in
var result: [Int64: String] = [:]
for (id, path) in results {
if let path {
result[id] = path
}
}
return result
}
}
@ -1453,9 +1767,11 @@ private final class NotificationServiceHandler {
|> timeout(10.0, queue: queue, alternate: .single(nil)),
fetchNotificationSoundSignal
|> timeout(10.0, queue: queue, alternate: .single(nil)),
wasDisplayed
wasDisplayed,
resolvedEmojiFiles
|> timeout(10.0, queue: queue, alternate: .single([:])),
)
|> deliverOn(queue)).start(next: { mediaData, notificationSoundData, wasDisplayed in
|> deliverOn(queue)).start(next: { mediaData, notificationSoundData, wasDisplayed, resolvedEmojiFiles in
guard let strongSelf = self, let stateManager = strongSelf.stateManager else {
completed()
return
@ -1527,7 +1843,7 @@ private final class NotificationServiceHandler {
stateManager.postbox.mediaBox.storeResourceData(resource.id, data: mediaData, synchronous: true)
}
if let storedPath = stateManager.postbox.mediaBox.completedResourcePath(resource) {
if let data = try? Data(contentsOf: URL(fileURLWithPath: storedPath)), let image = convertLottieImage(data: data) {
if let data = try? Data(contentsOf: URL(fileURLWithPath: storedPath)), let image = convertLottieImage(data: data, size: CGSize(width: 200.0, height: 200.0), forceSquare: false) {
let tempFile = TempBox.shared.tempFile(fileName: "image.png")
let _ = try? image.pngData()?.write(to: URL(fileURLWithPath: tempFile.path))
if let attachment = try? UNNotificationAttachment(identifier: "image", url: URL(fileURLWithPath: tempFile.path), options: nil) {
@ -1566,6 +1882,8 @@ private final class NotificationServiceHandler {
}
}
}
content.resolvedEmojiFiles = resolvedEmojiFiles
Logger.shared.log("NotificationService \(episode)", "Updating content to \(content)")
@ -1628,7 +1946,11 @@ private final class NotificationServiceHandler {
var content = initialContent
if let interactionAuthorId = interactionAuthorId {
if inAppNotificationSettings.displayNameOnLockscreen, let peer = transaction.getPeer(interactionAuthorId) {
if inAppNotificationSettings.displayNameOnLockscreen, var peer = transaction.getPeer(interactionAuthorId) {
if let channel = peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = transaction.getPeer(linkedMonoforumId) {
peer = mainChannel
}
var foundLocalId: String?
transaction.enumerateDeviceContactImportInfoItems({ _, value in
if let value = value as? TelegramDeviceContactImportedData {
@ -1678,11 +2000,34 @@ private final class NotificationServiceHandler {
|> takeLast
|> mapToSignal { content, _ -> Signal<(NotificationContent, Media?), NoError> in
return stateManager.postbox.transaction { transaction -> (NotificationContent, Media?) in
var content = content
var parsedMedia: Media?
if let messageId, let message = transaction.getMessage(messageId), !message.containsSecretMedia {
if let messageId, let message = transaction.getMessage(messageId), !message.containsSecretMedia, !message.attributes.contains(where: { $0 is MediaSpoilerMessageAttribute }) {
if let media = message.media.first {
parsedMedia = media
}
if enableInlineEmoji, let textEntitiesAttribute = message.textEntitiesAttribute, let author = message.author {
let authorTitle = author.debugDisplayTitle
var needsPrefix = false
if message.id.peerId.namespace == Namespaces.Peer.CloudGroup {
needsPrefix = true
} else if let channel = message.peers[message.id.peerId] as? TelegramChannel {
if case .group = channel.info {
needsPrefix = true
}
}
let messagePrefix = needsPrefix ? "\(authorTitle): " : ""
let messagePrefixLength = (messagePrefix as NSString).length
for entity in textEntitiesAttribute.entities {
if case let .CustomEmoji(_, fileId) = entity.type {
content.customEmoji.append(NotificationContent.CustomEmoji(range: (entity.range.lowerBound + messagePrefixLength) ..< (entity.range.upperBound + messagePrefixLength), fileId: fileId))
}
}
if !content.customEmoji.isEmpty {
content.body = messagePrefix + message.text
}
}
}
return (content, parsedMedia)
@ -1942,7 +2287,11 @@ private final class NotificationServiceHandler {
var content = initialContent
if let interactionAuthorId = interactionAuthorId {
if inAppNotificationSettings.displayNameOnLockscreen, let peer = transaction.getPeer(interactionAuthorId) {
if inAppNotificationSettings.displayNameOnLockscreen, var peer = transaction.getPeer(interactionAuthorId) {
if let channel = peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = transaction.getPeer(linkedMonoforumId) {
peer = mainChannel
}
var foundLocalId: String?
transaction.enumerateDeviceContactImportInfoItems({ _, value in
if let value = value as? TelegramDeviceContactImportedData {
@ -2258,3 +2607,430 @@ final class NotificationService: UNNotificationServiceExtension {
}
}
}
typealias CMJImage = UIImage
// MARK: - Public Namespace
/// A lightweight utility for turning ordinary bitmap images into ``NSAdaptiveImageGlyph`` (Apple Genmoji) objects.
///
/// ## Overview
/// The public API is minimal a single call to generate a glyph and helper utilities for
/// de/serialising attributed strings.
///
/// ```swift
/// // Synchronous usage
/// let glyph = try Customoji.makeGlyph(
/// from: image,
/// description: "alt text",
/// cropToSquare: true
/// )
/// let attr = NSAttributedString(adaptiveImageGlyph: glyph, attributes: [:])
/// ```
///
/// ## Requirements
/// * iOS 18 / macOS 15
/// * Swift 5.10+
///
/// ## Topics
/// - Generating glyphs: ``makeGlyph(from:description:identifier:tileSizes:cropToSquare:heicQuality:)``
/// - Generating glyphs asynchronously: ``makeGlyphAsync(from:description:identifier:tileSizes:cropToSquare:heicQuality:)``
/// - Serialising: ``decompose(_:)`` / ``recompose(plain:ranges:blobs:)``
///
public struct Customoji {
// MARK: Library-scoped Errors
/// Errors that can be thrown by ``Customoji``.
public enum Error: Swift.Error, LocalizedError {
/// The input image is not square and ``makeGlyph(from:description:identifier:tileSizes:cropToSquare:heicQuality:)`` was called with `cropToSquare == false`.
case nonSquare
/// The longest side of the input image exceeds ``maxSide`` pixels (defaults to 4096).
case imageTooLarge
/// Failed to create an in-memory HEIC container via *Image I/O*.
case heicDestinationCreationFailed
/// Failed to finalise the HEIC container after writing all tiles.
case heicFinalizeFailed
/// Internal resize operation failed when generating a tile.
case imageScaleFailed
/// A `CGImage` representation could not be extracted from the source image.
case cgImageUnavailable
/// The `tileSizes` parameter was empty, not strictly ascending, contained duplicates, or exceeded the source size.
case invalidTileSizes
/// No tiles were generated normally unreachable unless all requested sizes were invalid.
case noTilesGenerated
/// The current platform is neither UIKit- nor AppKit-based (unlikely in practice).
case unsupportedPlatform
/// The `heicQuality` parameter was outside the 0.0 1.0 range.
case invalidHeicQuality
/// Cropping or scaling to a square failed.
case squareCropFailed
/// Textual description suitable for presenting to users.
public var errorDescription: String? {
switch self {
case .nonSquare: return "Input image must be square."
case .imageTooLarge:
return "Source image is too large to process safely."
case .heicDestinationCreationFailed:
return
"Failed to create an in-memory HEIC destination container."
case .heicFinalizeFailed: return "Failed to finalize HEIC encoding."
case .imageScaleFailed: return "Failed to rescale CGImage tile."
case .cgImageUnavailable:
return "Unable to obtain CGImage from the source image."
case .invalidTileSizes:
return
"Tile sizes must be unique, strictly ascending, and not exceed the source size."
case .noTilesGenerated:
return "No tiles were generated from the source image."
case .unsupportedPlatform:
return
"Unsupported platform when attempting to extract CGImage."
case .invalidHeicQuality:
return "HEIC quality must be between 0.0 and 1.0."
case .squareCropFailed:
return "Failed to create a square crop of the input image."
}
}
}
/// Default tile sizes (in pixels) officially used by Apple for Genmoji.
public static let defaultTileSizes = [40, 64, 96, 160, 320]
/// Maximum allowed side length (in pixels) to guard against excessive memory consumption.
private static let maxSide = 4_096
// MARK: - Synchronous Builder
#if swift(>=5.10)
@available(iOS 18.0, macCatalyst 18.0, macOS 15.0, *)
/// Generates an ``NSAdaptiveImageGlyph`` synchronously on the **current** thread.
///
/// - Parameters:
/// - image: Source image. Can be rectangular; see `cropToSquare`.
/// - description: A human-readable accessibility description (VoiceOver/Narrator).
/// - identifier: A globally unique content identifier. Defaults to a fresh UUID.
/// - tileSizes: Desired tile sizes, in pixels. Must be strictly ascending. Defaults to ``defaultTileSizes``.
/// - cropToSquare: When `true`, the central square area is cropped if the input image is not square.
/// - heicQuality: Lossy compression quality between `0.0` and `1.0`. Defaults to `0.8`.
/// - Throws: ``Customoji/Error`` if validation or encoding fails.
/// - Returns: A fully-formed glyph ready for attribution.
static func makeGlyph(
from image: CMJImage,
description: String,
identifier: String = UUID().uuidString,
tileSizes: [Int] = defaultTileSizes,
cropToSquare: Bool = false,
heicQuality: CGFloat = 0.8
) throws -> NSAdaptiveImageGlyph {
try validatePixelSide(of: image)
let cg = try extractCGImage(from: image)
return try coreMakeGlyph(
from: cg,
description: description,
identifier: identifier,
tileSizes: tileSizes,
cropToSquare: cropToSquare,
heicQuality: heicQuality
)
}
#endif
// MARK: - AttributedString Utilities
#if swift(>=5.10)
@available(iOS 18.0, macCatalyst 18.0, macOS 15.0, *)
/// Breaks an ``NSAttributedString`` that may contain adaptive-image glyphs into three parts.
///
/// This is handy when you need to **serialise** rich text for network transport or persistent
/// storage, because `NSAdaptiveImageGlyph` itself is not `Codable`.
///
/// ```swift
/// let (plain, ranges, blobs) = Customoji.decompose(attrString)
/// ```
///
/// - Returns: A tuple where:
/// - plain: UTF-16 plain text.
/// - ranges: An array mapping text ranges to glyph identifiers.
/// - blobs: A dictionary mapping identifier raw HEIC data.
@inlinable
public static func decompose(_ attr: NSAttributedString) -> (
plain: String, ranges: [(NSRange, String)], blobs: [String: Data]
) {
var ranges = [(NSRange, String)]()
var blobs = [String: Data]()
attr.enumerateAttribute(
.adaptiveImageGlyph,
in: NSRange(location: 0, length: attr.length)
) { value, range, _ in
guard let g = value as? NSAdaptiveImageGlyph else { return }
let id = g.contentIdentifier
ranges.append((range, id))
blobs[id] = blobs[id] ?? g.imageContent
}
return (attr.string, ranges, blobs)
}
@available(iOS 18.0, macCatalyst 18.0, macOS 15.0, *)
/// Reassembles an attributed string previously produced by ``decompose(_:)``.
///
/// - Parameters:
/// - plain: The plain UTF-16 text.
/// - ranges: An array of `(NSRange, identifier)` pairs.
/// - blobs: A dictionary of identifier HEIC data. *Must* contain every identifier referenced by `ranges`.
/// - Returns: A fully restored `NSAttributedString` with adaptive-image glyphs reinstated.
public static func recompose(
plain: String,
ranges: [(NSRange, String)],
blobs: [String: Data]
) -> NSAttributedString {
let out = NSMutableAttributedString(string: plain)
var cache = [String: NSAdaptiveImageGlyph]()
ranges.forEach { (range, id) in
if cache[id] == nil, let data = blobs[id] {
cache[id] = NSAdaptiveImageGlyph(imageContent: data)
}
if let glyph = cache[id] {
out.addAttribute(
.adaptiveImageGlyph,
value: glyph,
range: range
)
}
}
return out
}
#endif
// MARK: - Helper: Pixel-Side Validation
/// Ensures that the images **longer edge** does not exceed ``maxSide`` pixels, guarding against
/// excessive memory usage during HEIC encoding.
private static func validatePixelSide(of image: CMJImage) throws {
#if canImport(UIKit)
let scale = image.scale == 0 ? 1 : image.scale
let px = Int(max(image.size.width, image.size.height) * scale)
#elseif canImport(AppKit)
let px = Int(
max(image.size.width, image.size.height)
* CGFloat(NSScreen.main?.backingScaleFactor ?? 1)
)
#endif
guard px <= maxSide else { throw Error.imageTooLarge }
}
}
// =============================================================
// Below this line lies the internal implementation.
// Public-facing symbols have already been documented above.
// =============================================================
// MARK: - Core Builder
@available(iOS 18.0, macCatalyst 18.0, macOS 15.0, *)
extension Customoji {
@Sendable fileprivate static func coreMakeGlyph(
from original: CGImage,
description: String,
identifier: String,
tileSizes: [Int],
cropToSquare: Bool,
heicQuality: CGFloat
) throws -> NSAdaptiveImageGlyph {
let cg = try ensureSquare(original, cropIfNeeded: cropToSquare)
guard cg.width <= maxSide else { throw Error.imageTooLarge }
let validSizes = try validatedTileSizes(tileSizes, max: cg.width)
let data = try heicData(
from: cg,
id: identifier,
description: description,
tileSizes: validSizes,
quality: heicQuality
)
return NSAdaptiveImageGlyph(imageContent: data)
}
}
// MARK: - HEIC Encoder
@available(iOS 18.0, macCatalyst 18.0, macOS 15.0, *)
extension Customoji {
fileprivate static func heicData(
from cg: CGImage,
id: String,
description: String,
tileSizes: [Int],
quality: CGFloat
) throws -> Data {
guard (0...1).contains(quality) else { throw Error.invalidHeicQuality }
let destData = NSMutableData()
guard
let dest = CGImageDestinationCreateWithData(
destData,
UTType.heic.identifier as CFString,
tileSizes.count,
nil
)
else {
throw Error.heicDestinationCreationFailed
}
// Attach Genmoji metadata
let meta = CGImageMetadataCreateMutable()
CGImageMetadataSetValueWithPath(
meta,
nil,
"tiff:\(kCGImagePropertyTIFFDocumentName)" as CFString,
id as CFString
)
CGImageMetadataSetValueWithPath(
meta,
nil,
"dc:description" as CFString,
description as CFString
)
for (idx, side) in tileSizes.enumerated() {
if Task.isCancelled { throw CancellationError() }
guard let img = cg.scaled(to: side) else {
throw Error.imageScaleFailed
}
let opts =
[kCGImageDestinationLossyCompressionQuality: quality]
as CFDictionary
if idx == 0 {
CGImageDestinationAddImageAndMetadata(dest, img, meta, opts)
} else {
CGImageDestinationAddImage(dest, img, opts)
}
}
guard CGImageDestinationFinalize(dest) else {
throw Error.heicFinalizeFailed
}
return destData as Data
}
}
// MARK: - CGImage Helpers
extension CGImage {
/// Returns a copy whose longer edge equals `side` pixels. *Assumes the input is already square.*
fileprivate func scaled(to side: Int) -> CGImage? {
guard width != side else { return self }
guard let cs = CGColorSpace(name: CGColorSpace.sRGB) else { return nil }
let hasAlpha: Bool = {
switch alphaInfo {
case .none, .noneSkipFirst, .noneSkipLast: return false
default: return true
}
}()
let bitmapInfo: UInt32 =
hasAlpha
? CGImageAlphaInfo.premultipliedLast.rawValue
: CGImageAlphaInfo.noneSkipLast.rawValue
guard
let ctx = CGContext(
data: nil,
width: side,
height: side,
bitsPerComponent: 8,
bytesPerRow: 0,
space: cs,
bitmapInfo: bitmapInfo
)
else { return nil }
ctx.interpolationQuality = .high
ctx.draw(self, in: CGRect(x: 0, y: 0, width: side, height: side))
return ctx.makeImage()
}
}
// MARK: - Image Extraction Helpers
extension Customoji {
fileprivate static func extractCGImage(from image: CMJImage) throws
-> CGImage
{
#if canImport(UIKit)
if let cg = (image as UIImage).cgImage { return cg }
var rendered: CGImage?
let work = { rendered = renderCGImage(image) }
if Thread.isMainThread {
work()
} else {
DispatchQueue.main.sync(execute: work)
}
if let cg = rendered { return cg }
#elseif canImport(AppKit)
var rect = CGRect(origin: .zero, size: image.size)
if let cg = (image as NSImage).cgImage(
forProposedRect: &rect,
context: nil,
hints: nil
) {
return cg
}
if let tiff = (image as NSImage).tiffRepresentation,
let rep = NSBitmapImageRep(data: tiff), let cg = rep.cgImage
{
return cg
}
#endif
throw Error.cgImageUnavailable
}
#if canImport(UIKit)
private static func renderCGImage(_ image: UIImage) -> CGImage? {
precondition(Thread.isMainThread, "Must be on main thread")
let fmt = UIGraphicsImageRendererFormat()
fmt.scale = image.scale == 0 ? 1 : image.scale
fmt.opaque = false
return UIGraphicsImageRenderer(size: image.size, format: fmt).image
{ _ in image.draw(at: .zero) }.cgImage
}
#endif
}
// MARK: - Square Enforcement
extension Customoji {
fileprivate static func ensureSquare(_ cg: CGImage, cropIfNeeded: Bool)
throws -> CGImage
{
guard cg.width == cg.height else {
guard cropIfNeeded else { throw Error.nonSquare }
let side = min(cg.width, cg.height)
let rect = CGRect(
x: (cg.width - side) / 2,
y: (cg.height - side) / 2,
width: side,
height: side
)
if let cropped = cg.cropping(to: rect) { return cropped }
if let scaled = cg.scaled(to: side) { return scaled }
throw Error.squareCropFailed
}
return cg
}
}
// MARK: - Tile Size Validation
extension Customoji {
fileprivate static func validatedTileSizes(_ sizes: [Int], max: Int) throws
-> [Int]
{
guard !sizes.isEmpty else { throw Error.invalidTileSizes }
for (prev, curr) in zip(sizes, sizes.dropFirst()) where curr <= prev {
throw Error.invalidTileSizes
}
guard sizes.allSatisfy({ $0 > 0 && $0 <= max }) else {
throw Error.invalidTileSizes
}
return sizes
}
}

View file

@ -3,7 +3,6 @@ import TelegramUI
import BuildConfig
import ShareExtensionContext
import SwiftSignalKit
import Postbox
import TelegramCore
@objc(ShareRootController)
@ -56,10 +55,10 @@ class ShareRootController: UIViewController {
appGroupPath: appGroupUrl.path,
accountManager: accountManager,
appLockContext: appLockContext,
encryptionParameters: ValueBoxEncryptionParameters(
encryptionParameters: EngineValueBoxEncryptionParameters(
forceEncryptionIfNoSet: false,
key: ValueBoxEncryptionParameters.Key(data: encryptionParameters.0)!,
salt: ValueBoxEncryptionParameters.Salt(data: encryptionParameters.1)!
key: EngineValueBoxEncryptionParameters.Key(data: encryptionParameters.0)!,
salt: EngineValueBoxEncryptionParameters.Salt(data: encryptionParameters.1)!
),
applicationBindings: applicationBindings,
initialPresentationDataAndSettings: InitialPresentationDataAndSettings,
@ -69,6 +68,13 @@ class ShareRootController: UIViewController {
}), getExtensionContext: { [weak self] in
return self?.extensionContext
})
self.impl?.openUrl = { [weak self] url in
guard let self, let url = URL(string: url) else {
return
}
let _ = self.openURL(url)
}
}
self.impl?.loadView()
@ -93,4 +99,20 @@ class ShareRootController: UIViewController {
super.viewDidLayoutSubviews()
self.impl?.viewDidLayoutSubviews(view: self.view, traitCollection: self.traitCollection)
}
@objc func openURL(_ url: URL) -> Bool {
var responder: UIResponder? = self
while responder != nil {
if let application = responder as? UIApplication {
if #available(iOS 18.0, *) {
application.open(url, options: [:], completionHandler: nil)
return true
} else {
return application.perform(#selector(openURL(_:)), with: url) != nil
}
}
responder = responder?.next
}
return false
}
}

View file

@ -96,16 +96,23 @@ private func matchPhoneNumbers(_ lhs: String, _ rhs: String) -> Bool {
func matchingCloudContacts(postbox: Postbox, contacts: [MatchingDeviceContact]) -> Signal<[(String, TelegramUser)], NoError> {
return postbox.transaction { transaction -> [(String, TelegramUser)] in
var result: [(String, TelegramUser)] = []
var matchingIds = Set<EnginePeer.Id>()
outer: for peerId in transaction.getContactPeerIds() {
if let peer = transaction.getPeer(peerId) as? TelegramUser {
for contact in contacts {
if let contactPeerId = contact.peerId, contactPeerId == peerId {
result.append((contact.stableId, peer))
if !matchingIds.contains(peer.id) {
matchingIds.insert(peer.id)
result.append((contact.stableId, peer))
}
continue outer
} else if let peerPhoneNumber = peer.phone {
for contactPhoneNumber in contact.phoneNumbers {
if matchPhoneNumbers(contactPhoneNumber, peerPhoneNumber) {
result.append((contact.stableId, peer))
if !matchingIds.contains(peer.id) {
matchingIds.insert(peer.id)
result.append((contact.stableId, peer))
}
continue outer
}
}
@ -113,6 +120,15 @@ func matchingCloudContacts(postbox: Postbox, contacts: [MatchingDeviceContact])
}
}
}
for contact in contacts {
if let peerId = contact.peerId, let peer = transaction.getPeer(peerId) as? TelegramUser {
if !matchingIds.contains(peer.id) {
matchingIds.insert(peer.id)
result.append((contact.stableId, peer))
}
}
}
return result
}
}

View file

@ -70,9 +70,8 @@ class IntentHandler: INExtension {
}
}
@available(iOSApplicationExtension 10.0, iOS 10.0, *)
@objc(IntentHandler)
class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling, INStartAudioCallIntentHandling, INSearchCallHistoryIntentHandling {
class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessagesIntentHandling, INSetMessageAttributeIntentHandling, INStartCallIntentHandling, INSearchCallHistoryIntentHandling {
private let accountPromise = Promise<Account?>()
private let allAccounts = Promise<[(AccountRecordId, PeerId, Bool)]>()
@ -234,16 +233,31 @@ class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchFo
var personResolutionResult: INPersonResolutionResult {
switch self {
case let .success(person):
return .success(with: person)
case let .disambiguation(persons):
return .disambiguation(with: persons)
case .needsValue:
return .needsValue()
case .noResult:
return .unsupported()
case .skip:
return .notRequired()
case let .success(person):
return .success(with: person)
case let .disambiguation(persons):
return .disambiguation(with: persons)
case .needsValue:
return .needsValue()
case .noResult:
return .unsupported()
case .skip:
return .notRequired()
}
}
var contactResolutionResult: INStartCallContactResolutionResult {
switch self {
case let .success(person):
return .success(with: person)
case let .disambiguation(persons):
return .disambiguation(with: persons)
case .needsValue:
return .needsValue()
case .noResult:
return .unsupported()
case .skip:
return .notRequired()
}
}
}
@ -644,36 +658,34 @@ class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchFo
}
// MARK: - INStartAudioCallIntentHandling
public func resolveContacts(for intent: INStartAudioCallIntent, with completion: @escaping ([INPersonResolutionResult]) -> Void) {
public func resolveContacts(for intent: INStartCallIntent, with completion: @escaping ([INStartCallContactResolutionResult]) -> Void) {
if let appGroupUrl = self.appGroupUrl {
let rootPath = rootPathForBasePath(appGroupUrl.path)
if let data = try? Data(contentsOf: URL(fileURLWithPath: appLockStatePath(rootPath: rootPath))), let state = try? JSONDecoder().decode(LockState.self, from: data), isAppLocked(state: state) {
completion([INPersonResolutionResult.notRequired()])
completion([INStartCallContactResolutionResult.notRequired()])
return
}
}
guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else {
completion([INPersonResolutionResult.notRequired()])
completion([INStartCallContactResolutionResult.notRequired()])
return
}
self.resolve(persons: intent.contacts, with: { result in
completion(result.map { $0.personResolutionResult })
completion(result.map { $0.contactResolutionResult })
})
}
@available(iOSApplicationExtension 11.0, iOS 11.0, *)
public func resolveDestinationType(for intent: INStartAudioCallIntent, with completion: @escaping (INCallDestinationTypeResolutionResult) -> Void) {
public func resolveDestinationType(for intent: INStartCallIntent, with completion: @escaping (INCallDestinationTypeResolutionResult) -> Void) {
completion(.success(with: .normal))
}
public func handle(intent: INStartAudioCallIntent, completion: @escaping (INStartAudioCallIntentResponse) -> Void) {
public func handle(intent: INStartCallIntent, completion: @escaping (INStartCallIntentResponse) -> Void) {
if let appGroupUrl = self.appGroupUrl {
let rootPath = rootPathForBasePath(appGroupUrl.path)
if let data = try? Data(contentsOf: URL(fileURLWithPath: appLockStatePath(rootPath: rootPath))), let state = try? JSONDecoder().decode(LockState.self, from: data), isAppLocked(state: state) {
let userActivity = NSUserActivity(activityType: NSStringFromClass(INStartAudioCallIntent.self))
let response = INStartAudioCallIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity)
let userActivity = NSUserActivity(activityType: NSStringFromClass(INStartCallIntent.self))
let response = INStartCallIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity)
completion(response)
return
}
@ -699,13 +711,13 @@ class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchFo
return .single(peerId)
}
|> deliverOnMainQueue).start(next: { peerId in
let userActivity = NSUserActivity(activityType: NSStringFromClass(INStartAudioCallIntent.self))
let userActivity = NSUserActivity(activityType: NSStringFromClass(INStartCallIntent.self))
userActivity.userInfo = ["handle": "TGCA\(peerId.toInt64())"]
let response = INStartAudioCallIntentResponse(code: .continueInApp, userActivity: userActivity)
let response = INStartCallIntentResponse(code: .continueInApp, userActivity: userActivity)
completion(response)
}, error: { _ in
let userActivity = NSUserActivity(activityType: NSStringFromClass(INStartAudioCallIntent.self))
let response = INStartAudioCallIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity)
let userActivity = NSUserActivity(activityType: NSStringFromClass(INStartCallIntent.self))
let response = INStartCallIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity)
completion(response)
}))
}
@ -803,7 +815,7 @@ class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchFo
if let searchTerm = searchTerm {
if !searchTerm.isEmpty {
for renderedPeer in transaction.searchPeers(query: searchTerm) {
for renderedPeer in transaction.searchPeers(query: searchTerm, predicate: nil) {
if let peer = renderedPeer.peer, !(peer is TelegramSecretChat), !peer.isDeleted {
peers.append(peer)
}
@ -976,7 +988,7 @@ private final class WidgetIntentHandler {
if let searchTerm = searchTerm {
if !searchTerm.isEmpty {
for renderedPeer in transaction.searchPeers(query: searchTerm) {
for renderedPeer in transaction.searchPeers(query: searchTerm, predicate: nil) {
if let peer = renderedPeer.peer, !(peer is TelegramSecretChat), !peer.isDeleted {
peers.append(peer)
}
@ -1309,7 +1321,7 @@ private func mapPeersToFriends(accountId: AccountRecordId, accountPeerId: PeerId
var profileImage: INImage?
var isForum = false
if let peer = peer as? TelegramChannel, peer.flags.contains(.isForum) {
if let peer = peer as? TelegramChannel, peer.isForumOrMonoForum {
isForum = true
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 788 B

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Oval</title>
<g id="Oval" stroke="none" fill="none" fill-rule="nonzero">
<circle fill="#000000" cx="512" cy="512" r="410.5"></circle>
</g>
</svg>

After

Width:  |  Height:  |  Size: 364 B

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Plane</title>
<g id="Plane" stroke="none" fill="none" fill-rule="nonzero">
<path d="M287.315632,507.666819 C406.984718,455.528898 486.782853,421.15639 526.710034,404.549294 C640.710251,357.13266 664.39852,348.895883 679.838202,348.621 C683.234017,348.56408 690.826804,349.405665 695.745092,353.396516 C699.897998,356.766313 701.040629,361.31843 701.587414,364.513367 C702.1342,367.708304 702.815079,374.986453 702.273832,380.673387 C696.09612,445.583141 669.36526,603.101997 655.766116,675.802034 C650.011808,706.564145 638.681397,716.878524 627.712247,717.887922 C603.873746,720.081578 585.77187,702.133777 562.683116,686.998808 C526.553773,663.315568 506.142993,648.572678 471.073211,625.462211 C430.544009,598.754068 456.817404,584.074808 479.914878,560.08479 C485.959597,553.806488 590.992581,458.270869 593.025497,449.604291 C593.279747,448.520391 593.515704,444.480123 591.115452,442.346714 C588.715199,440.213304 585.172634,440.942847 582.61622,441.52306 C578.99258,442.345492 521.275488,480.49435 409.464943,555.969631 C393.082138,567.219329 378.243103,572.700559 364.947836,572.413323 C350.290871,572.096667 322.096751,564.126052 301.137321,557.312967 C275.429726,548.956441 254.997841,544.538286 256.777,530.34632 C257.703696,522.954266 267.883239,515.394432 287.315632,507.666819 Z" id="Path-3" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,122 @@
{
"fill" : "system-light",
"groups" : [
{
"blend-mode" : "normal",
"blur-material" : 1,
"layers" : [
{
"blend-mode-specializations" : [
{
"value" : "normal"
},
{
"appearance" : "dark",
"value" : "normal"
}
],
"fill-specializations" : [
{
"appearance" : "dark",
"value" : "automatic"
}
],
"glass" : true,
"image-name" : "Plane.svg",
"name" : "Plane",
"position-specializations" : [
{
"idiom" : "watchOS",
"value" : {
"scale" : 1.35,
"translation-in-points" : [
0,
0
]
}
}
]
},
{
"blend-mode-specializations" : [
{
"value" : "normal"
},
{
"appearance" : "dark",
"value" : "normal"
}
],
"fill-specializations" : [
{
"value" : {
"linear-gradient" : [
"display-p3:0.21569,0.68627,0.89020,1.00000",
"srgb:0.11373,0.57647,0.82353,1.00000"
]
}
},
{
"appearance" : "dark",
"value" : {
"automatic-gradient" : "srgb:0.00000,0.47843,1.00000,1.00000"
}
}
],
"glass" : true,
"hidden-specializations" : [
{
"value" : false
},
{
"idiom" : "watchOS",
"value" : false
}
],
"image-name" : "Oval.svg",
"name" : "Oval",
"position-specializations" : [
{
"idiom" : "watchOS",
"value" : {
"scale" : 2,
"translation-in-points" : [
0,
0
]
}
}
]
}
],
"lighting" : "combined",
"position-specializations" : [
{
"idiom" : "watchOS",
"value" : {
"scale" : 1,
"translation-in-points" : [
0,
0
]
}
}
],
"shadow" : {
"kind" : "layer-color",
"opacity" : 1
},
"specular" : true,
"translucency" : {
"enabled" : false,
"value" : 1
}
}
],
"supported-platforms" : {
"circles" : [
"watchOS"
],
"squares" : "shared"
}
}

View file

@ -5,8 +5,8 @@
"NSLocationAlwaysAndWhenInUseUsageDescription" = "When you choose to share your Live Location with friends in a chat, Telegram needs background access to your location to keep them updated for the duration of the live sharing.";
"NSLocationAlwaysUsageDescription" = "When you choose to share your live location with friends in a chat, Telegram needs background access to your location to keep them updated for the duration of the live sharing. You also need this to send locations from an Apple Watch.";
"NSCameraUsageDescription" = "We need this so that you can take and share photos and videos, as well as make video calls.";
"NSPhotoLibraryUsageDescription" = "We need this so that you can share photos and videos from your photo library.";
"NSPhotoLibraryAddUsageDescription" = "We need this so that you can save photos and videos to your photo library.";
"NSPhotoLibraryUsageDescription" = "We need this so that you can share photos and videos from your photo library and save the ones you capture.";
"NSPhotoLibraryAddUsageDescription" = "We need this so that you can save photos and videos to your photo library and save the ones you capture.";
"NSMicrophoneUsageDescription" = "We need this so that you can record and share voice messages and videos with sound.";
"NSSiriUsageDescription" = "You can use Siri to send messages.";
"NSFaceIDUsageDescription" = "You can use Face ID to unlock the app.";

File diff suppressed because it is too large Load diff

View file

@ -1,16 +1,6 @@
#import <UIKit/UIKit.h>
#import <dlfcn.h>
int main(int argc, char *argv[]) {
/*NSString *basePath = [[NSString stringWithUTF8String:argv[0]] stringByDeletingLastPathComponent];
void *Share = dlopen([[basePath stringByAppendingPathComponent:@"PlugIns/Share.appex/Share"] UTF8String], RTLD_LAZY);
void *NotificationContent = dlopen([[basePath stringByAppendingPathComponent:@"PlugIns/NotificationContent.appex/NotificationContent"] UTF8String], RTLD_LAZY);
sleep(1000);
void *NotificationService = dlopen([[basePath stringByAppendingPathComponent:@"PlugIns/NotificationService.appex/NotificationService"] UTF8String], RTLD_LAZY);
void *SiriIntents = dlopen([[basePath stringByAppendingPathComponent:@"PlugIns/SiriIntents.appex/SiriIntents"] UTF8String], RTLD_LAZY);
void *Widget = dlopen([[basePath stringByAppendingPathComponent:@"PlugIns/Widget.appex/Widget"] UTF8String], RTLD_LAZY);
1*/
@autoreleasepool {
return UIApplicationMain(argc, argv, @"Application", @"AppDelegate");
}

View file

@ -0,0 +1,92 @@
import XCTest
import Foundation
class UITests: XCTestCase {
private var app: XCUIApplication!
override func setUpWithError() throws {
continueAfterFailure = false
app = XCUIApplication()
app.launchArguments.append("--ui-test")
}
override func tearDownWithError() throws {
app = nil
}
/// Deletes a test account so the sign-up flow can be exercised again.
/// Launches the app with `--delete-test-account` which logs in and deletes the account.
private func deleteTestAccount(phone: String) {
let cleanupApp = XCUIApplication()
cleanupApp.launchArguments += ["--ui-test", "--delete-test-account", phone]
cleanupApp.launch()
let success = cleanupApp.windows["DeleteAccount.Success"]
XCTAssert(success.waitForExistence(timeout: 30), "test account cleanup did not complete in 30s")
cleanupApp.terminate()
}
func testLaunch() throws {
app.launch()
XCTAssert(app.wait(for: .runningForeground, timeout: 10.0))
}
func testSignUp() throws {
deleteTestAccount(phone: "9996625296")
app.launch()
// Welcome screen tap Start Messaging
let startButton = app.buttons["Auth.Welcome.StartButton"]
XCTAssert(startButton.waitForExistence(timeout: 5.0))
startButton.tap()
// Phone entry screen enter test phone number
let countryCodeField = app.textFields["Auth.PhoneEntry.CountryCodeField"]
XCTAssert(countryCodeField.waitForExistence(timeout: 10.0))
countryCodeField.tap()
for _ in 0..<10 {
countryCodeField.typeText(XCUIKeyboardKey.delete.rawValue)
}
countryCodeField.typeText("999")
let phoneNumberField = app.textFields["Auth.PhoneEntry.PhoneNumberField"]
phoneNumberField.tap()
phoneNumberField.typeText("6629999")
let continueButton = app.buttons["Auth.PhoneEntry.ContinueButton"]
XCTAssert(continueButton.waitForExistence(timeout: 3.0))
XCTAssert(continueButton.isEnabled)
continueButton.tap()
// Confirmation dialog tap Continue
let confirmButton = app.buttons["Auth.PhoneConfirm.ContinueButton"]
XCTAssert(confirmButton.waitForExistence(timeout: 5.0))
confirmButton.tap()
// Code entry screen enter verification code
let codeEntryTitle = app.staticTexts["Auth.CodeEntry.Title"]
XCTAssert(codeEntryTitle.waitForExistence(timeout: 15.0))
let codeField = app.textFields["Auth.CodeEntry.CodeField"]
XCTAssert(codeField.waitForExistence(timeout: 3.0))
codeField.typeText("22222")
// Set name screen enter name and submit
let firstNameField = app.textFields["Auth.SetName.FirstNameField"]
XCTAssert(firstNameField.waitForExistence(timeout: 15.0))
firstNameField.tap()
firstNameField.typeText("Test")
let lastNameField = app.textFields["Auth.SetName.LastNameField"]
lastNameField.tap()
lastNameField.typeText("User")
let signUpButton = app.buttons["Auth.SetName.ContinueButton"]
XCTAssert(signUpButton.waitForExistence(timeout: 3.0))
signUpButton.tap()
// Wait for post-signup UI to appear
sleep(10)
let description = app.debugDescription
XCTFail("UI DUMP:\n\(description)")
}
}

8
Telegram/WatchApp/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
**/.build/
**/DerivedData/
.DS_Store
**/xcuserdata/
# The repo root .gitignore ignores *.xcodeproj, but this committed snapshot needs its
# generated project (the Bazel embed build uses it directly). Re-include the project
# directory; xcuserdata inside stays excluded via the rule above.
!tgwatch.xcodeproj

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

19
Telegram/WatchApp/BUILD Normal file
View file

@ -0,0 +1,19 @@
# Committed snapshot of the tgwatch watch app (synced from the standalone tgwatch repo
# via tools/export-sources.sh). Built by //Telegram:TelegramWatchApp
# (apple_prebuilt_watchos_application) via xcodebuild. These files are the rule's tracked
# inputs, so the watch build re-runs only when the snapshot changes.
filegroup(
name = "sources",
srcs = glob(
["**"],
exclude = [
"**/.build/**",
"**/.swiftpm/**",
"**/xcuserdata/**",
"**/DerivedData/**",
"BUILD",
".gitignore",
],
),
visibility = ["//Telegram:__pkg__"],
)

View file

@ -0,0 +1,113 @@
// swift-tools-version:5.9
import PackageDescription
let package = Package(
name: "OpusKit",
platforms: [
.watchOS(.v10),
.macOS(.v14)
],
products: [
.library(name: "OpusKit", targets: ["OpusKit"]),
],
targets: [
.target(
name: "COgg",
path: "Sources/COgg",
sources: ["libogg/src"],
publicHeadersPath: "include",
cSettings: [
.headerSearchPath("libogg/include"),
]
),
// Vendored: libopus 1.5.2 (https://opus-codec.org).
// Exclude list is version-specific verify on upgrade.
// arm_celt_map.c and armcpu.c are intentionally kept; both are fully
// wrapped in `#ifdef OPUS_HAVE_RTCD` (never defined here) and compile
// to empty TUs. arm_silk_map.c is excluded because it unconditionally
// includes main_FIX.h from the (excluded) silk/fixed tree.
.target(
name: "COpus",
path: "Sources/COpus",
exclude: [
// NEON (ARM) SIMD variants disabled via -U__ARM_NEON__
"libopus/celt/arm/celt_neon_intr.c",
"libopus/celt/arm/pitch_neon_intr.c",
"libopus/silk/arm/biquad_alt_neon_intr.c",
"libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c",
"libopus/silk/arm/NSQ_del_dec_neon_intr.c",
"libopus/silk/arm/NSQ_neon.c",
// ARM dispatcher unconditionally includes silk/fixed headers (excluded)
"libopus/silk/arm/arm_silk_map.c",
// (silk/fixed/arm files already covered by the silk/fixed directory exclude below)
// ARM .s assembly (GAS/RVCT)
"libopus/celt/arm/celt_pitch_xcorr_arm.s",
"libopus/celt/arm/celt_pitch_xcorr_arm-gnu.S",
// ARM NE10 FFT (external dep) not used
"libopus/celt/arm/celt_mdct_ne10.c",
"libopus/celt/arm/celt_fft_ne10.c",
// x86 (SSE/AVX) intrinsic variants
"libopus/celt/x86/celt_lpc_sse4_1.c",
"libopus/celt/x86/pitch_sse.c",
"libopus/celt/x86/pitch_sse2.c",
"libopus/celt/x86/pitch_sse4_1.c",
"libopus/celt/x86/pitch_avx.c",
"libopus/celt/x86/vq_sse2.c",
"libopus/celt/x86/x86_celt_map.c",
"libopus/celt/x86/x86cpu.c",
"libopus/silk/x86/NSQ_del_dec_sse4_1.c",
"libopus/silk/x86/NSQ_del_dec_avx2.c",
"libopus/silk/x86/NSQ_sse4_1.c",
"libopus/silk/x86/VAD_sse4_1.c",
"libopus/silk/x86/VQ_WMat_EC_sse4_1.c",
"libopus/silk/x86/x86_silk_map.c",
"libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c",
"libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c",
"libopus/silk/float/x86/inner_product_FLP_avx2.c",
// libopus example / test programs
"libopus/src/opus_compare.c",
"libopus/src/opus_demo.c",
"libopus/src/repacketizer_demo.c",
"libopus/celt/opus_custom_demo.c",
"libopus/celt/tests",
"libopus/silk/tests",
// Fixed-point silk we're a float build (FIXED_POINT undefined)
"libopus/silk/fixed",
],
publicHeadersPath: "include",
cSettings: [
.headerSearchPath("libopus"),
.headerSearchPath("libopus/include"),
.headerSearchPath("libopus/celt"),
.headerSearchPath("libopus/silk"),
.headerSearchPath("libopus/silk/float"),
.headerSearchPath("libopus/src"),
.define("HAVE_CONFIG_H"),
.unsafeFlags(["-U__ARM_NEON__", "-U__SSE2__", "-U__SSE4_1__", "-U__AVX2__"]),
]
),
.target(
name: "COpusHelpers",
dependencies: ["COpus"],
path: "Sources/COpusHelpers",
publicHeadersPath: "include",
cSettings: [
.headerSearchPath("../COpus/include"),
]
),
.target(
name: "OpusKit",
dependencies: ["COgg", "COpus", "COpusHelpers"],
path: "Sources/OpusKit"
),
.testTarget(
name: "OpusKitTests",
dependencies: ["OpusKit"],
path: "Tests/OpusKitTests",
resources: [
.copy("Resources/voice_note.ogg"),
]
),
],
cLanguageStandard: .c11
)

View file

@ -0,0 +1,6 @@
#ifndef COgg_h
#define COgg_h
#include <ogg/ogg.h>
#endif

View file

@ -0,0 +1,5 @@
module COgg {
header "ogg/ogg.h"
header "ogg/os_types.h"
export *
}

View file

@ -0,0 +1,209 @@
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: toplevel libogg include
********************************************************************/
#ifndef _OGG_H
#define _OGG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <ogg/os_types.h>
typedef struct {
void *iov_base;
size_t iov_len;
} ogg_iovec_t;
typedef struct {
long endbyte;
int endbit;
unsigned char *buffer;
unsigned char *ptr;
long storage;
} oggpack_buffer;
/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
typedef struct {
unsigned char *header;
long header_len;
unsigned char *body;
long body_len;
} ogg_page;
/* ogg_stream_state contains the current encode/decode state of a logical
Ogg bitstream **********************************************************/
typedef struct {
unsigned char *body_data; /* bytes from packet bodies */
long body_storage; /* storage elements allocated */
long body_fill; /* elements stored; fill mark */
long body_returned; /* elements of fill returned */
int *lacing_vals; /* The values that will go to the segment table */
ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
this way, but it is simple coupled to the
lacing fifo */
long lacing_storage;
long lacing_fill;
long lacing_packet;
long lacing_returned;
unsigned char header[282]; /* working space for header encode */
int header_fill;
int e_o_s; /* set when we have buffered the last packet in the
logical bitstream */
int b_o_s; /* set after we've written the initial page
of a logical bitstream */
long serialno;
long pageno;
ogg_int64_t packetno; /* sequence number for decode; the framing
knows where there's a hole in the data,
but we need coupling so that the codec
(which is in a separate abstraction
layer) also knows about the gap */
ogg_int64_t granulepos;
} ogg_stream_state;
/* ogg_packet is used to encapsulate the data and metadata belonging
to a single raw Ogg/Vorbis packet *************************************/
typedef struct {
unsigned char *packet;
long bytes;
long b_o_s;
long e_o_s;
ogg_int64_t granulepos;
ogg_int64_t packetno; /* sequence number for decode; the framing
knows where there's a hole in the data,
but we need coupling so that the codec
(which is in a separate abstraction
layer) also knows about the gap */
} ogg_packet;
typedef struct {
unsigned char *data;
int storage;
int fill;
int returned;
int unsynced;
int headerbytes;
int bodybytes;
} ogg_sync_state;
/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
extern void oggpack_writeinit(oggpack_buffer *b);
extern int oggpack_writecheck(oggpack_buffer *b);
extern void oggpack_writetrunc(oggpack_buffer *b,long bits);
extern void oggpack_writealign(oggpack_buffer *b);
extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
extern void oggpack_reset(oggpack_buffer *b);
extern void oggpack_writeclear(oggpack_buffer *b);
extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
extern long oggpack_look(oggpack_buffer *b,int bits);
extern long oggpack_look1(oggpack_buffer *b);
extern void oggpack_adv(oggpack_buffer *b,int bits);
extern void oggpack_adv1(oggpack_buffer *b);
extern long oggpack_read(oggpack_buffer *b,int bits);
extern long oggpack_read1(oggpack_buffer *b);
extern long oggpack_bytes(oggpack_buffer *b);
extern long oggpack_bits(oggpack_buffer *b);
extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
extern void oggpackB_writeinit(oggpack_buffer *b);
extern int oggpackB_writecheck(oggpack_buffer *b);
extern void oggpackB_writetrunc(oggpack_buffer *b,long bits);
extern void oggpackB_writealign(oggpack_buffer *b);
extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
extern void oggpackB_reset(oggpack_buffer *b);
extern void oggpackB_writeclear(oggpack_buffer *b);
extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
extern long oggpackB_look(oggpack_buffer *b,int bits);
extern long oggpackB_look1(oggpack_buffer *b);
extern void oggpackB_adv(oggpack_buffer *b,int bits);
extern void oggpackB_adv1(oggpack_buffer *b);
extern long oggpackB_read(oggpack_buffer *b,int bits);
extern long oggpackB_read1(oggpack_buffer *b);
extern long oggpackB_bytes(oggpack_buffer *b);
extern long oggpackB_bits(oggpack_buffer *b);
extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
int count, long e_o_s, ogg_int64_t granulepos);
extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill);
extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill);
/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
extern int ogg_sync_init(ogg_sync_state *oy);
extern int ogg_sync_clear(ogg_sync_state *oy);
extern int ogg_sync_reset(ogg_sync_state *oy);
extern int ogg_sync_destroy(ogg_sync_state *oy);
extern int ogg_sync_check(ogg_sync_state *oy);
extern char *ogg_sync_buffer(ogg_sync_state *oy, long size);
extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);
/* Ogg BITSTREAM PRIMITIVES: general ***************************/
extern int ogg_stream_init(ogg_stream_state *os,int serialno);
extern int ogg_stream_clear(ogg_stream_state *os);
extern int ogg_stream_reset(ogg_stream_state *os);
extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
extern int ogg_stream_destroy(ogg_stream_state *os);
extern int ogg_stream_check(ogg_stream_state *os);
extern int ogg_stream_eos(ogg_stream_state *os);
extern void ogg_page_checksum_set(ogg_page *og);
extern int ogg_page_version(const ogg_page *og);
extern int ogg_page_continued(const ogg_page *og);
extern int ogg_page_bos(const ogg_page *og);
extern int ogg_page_eos(const ogg_page *og);
extern ogg_int64_t ogg_page_granulepos(const ogg_page *og);
extern int ogg_page_serialno(const ogg_page *og);
extern long ogg_page_pageno(const ogg_page *og);
extern int ogg_page_packets(const ogg_page *og);
extern void ogg_packet_clear(ogg_packet *op);
#ifdef __cplusplus
}
#endif
#endif /* _OGG_H */

View file

@ -0,0 +1,19 @@
#ifndef OGG_OS_TYPES_H
#define OGG_OS_TYPES_H
#include <stdint.h>
#include <stdlib.h>
typedef int16_t ogg_int16_t;
typedef uint16_t ogg_uint16_t;
typedef int32_t ogg_int32_t;
typedef uint32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
typedef uint64_t ogg_uint64_t;
#define _ogg_malloc malloc
#define _ogg_calloc calloc
#define _ogg_realloc realloc
#define _ogg_free free
#endif

View file

@ -0,0 +1,209 @@
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: toplevel libogg include
********************************************************************/
#ifndef _OGG_H
#define _OGG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <ogg/os_types.h>
typedef struct {
void *iov_base;
size_t iov_len;
} ogg_iovec_t;
typedef struct {
long endbyte;
int endbit;
unsigned char *buffer;
unsigned char *ptr;
long storage;
} oggpack_buffer;
/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
typedef struct {
unsigned char *header;
long header_len;
unsigned char *body;
long body_len;
} ogg_page;
/* ogg_stream_state contains the current encode/decode state of a logical
Ogg bitstream **********************************************************/
typedef struct {
unsigned char *body_data; /* bytes from packet bodies */
long body_storage; /* storage elements allocated */
long body_fill; /* elements stored; fill mark */
long body_returned; /* elements of fill returned */
int *lacing_vals; /* The values that will go to the segment table */
ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
this way, but it is simple coupled to the
lacing fifo */
long lacing_storage;
long lacing_fill;
long lacing_packet;
long lacing_returned;
unsigned char header[282]; /* working space for header encode */
int header_fill;
int e_o_s; /* set when we have buffered the last packet in the
logical bitstream */
int b_o_s; /* set after we've written the initial page
of a logical bitstream */
long serialno;
long pageno;
ogg_int64_t packetno; /* sequence number for decode; the framing
knows where there's a hole in the data,
but we need coupling so that the codec
(which is in a separate abstraction
layer) also knows about the gap */
ogg_int64_t granulepos;
} ogg_stream_state;
/* ogg_packet is used to encapsulate the data and metadata belonging
to a single raw Ogg/Vorbis packet *************************************/
typedef struct {
unsigned char *packet;
long bytes;
long b_o_s;
long e_o_s;
ogg_int64_t granulepos;
ogg_int64_t packetno; /* sequence number for decode; the framing
knows where there's a hole in the data,
but we need coupling so that the codec
(which is in a separate abstraction
layer) also knows about the gap */
} ogg_packet;
typedef struct {
unsigned char *data;
int storage;
int fill;
int returned;
int unsynced;
int headerbytes;
int bodybytes;
} ogg_sync_state;
/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
extern void oggpack_writeinit(oggpack_buffer *b);
extern int oggpack_writecheck(oggpack_buffer *b);
extern void oggpack_writetrunc(oggpack_buffer *b,long bits);
extern void oggpack_writealign(oggpack_buffer *b);
extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
extern void oggpack_reset(oggpack_buffer *b);
extern void oggpack_writeclear(oggpack_buffer *b);
extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
extern long oggpack_look(oggpack_buffer *b,int bits);
extern long oggpack_look1(oggpack_buffer *b);
extern void oggpack_adv(oggpack_buffer *b,int bits);
extern void oggpack_adv1(oggpack_buffer *b);
extern long oggpack_read(oggpack_buffer *b,int bits);
extern long oggpack_read1(oggpack_buffer *b);
extern long oggpack_bytes(oggpack_buffer *b);
extern long oggpack_bits(oggpack_buffer *b);
extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
extern void oggpackB_writeinit(oggpack_buffer *b);
extern int oggpackB_writecheck(oggpack_buffer *b);
extern void oggpackB_writetrunc(oggpack_buffer *b,long bits);
extern void oggpackB_writealign(oggpack_buffer *b);
extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
extern void oggpackB_reset(oggpack_buffer *b);
extern void oggpackB_writeclear(oggpack_buffer *b);
extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
extern long oggpackB_look(oggpack_buffer *b,int bits);
extern long oggpackB_look1(oggpack_buffer *b);
extern void oggpackB_adv(oggpack_buffer *b,int bits);
extern void oggpackB_adv1(oggpack_buffer *b);
extern long oggpackB_read(oggpack_buffer *b,int bits);
extern long oggpackB_read1(oggpack_buffer *b);
extern long oggpackB_bytes(oggpack_buffer *b);
extern long oggpackB_bits(oggpack_buffer *b);
extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
int count, long e_o_s, ogg_int64_t granulepos);
extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill);
extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill);
/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
extern int ogg_sync_init(ogg_sync_state *oy);
extern int ogg_sync_clear(ogg_sync_state *oy);
extern int ogg_sync_reset(ogg_sync_state *oy);
extern int ogg_sync_destroy(ogg_sync_state *oy);
extern int ogg_sync_check(ogg_sync_state *oy);
extern char *ogg_sync_buffer(ogg_sync_state *oy, long size);
extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);
/* Ogg BITSTREAM PRIMITIVES: general ***************************/
extern int ogg_stream_init(ogg_stream_state *os,int serialno);
extern int ogg_stream_clear(ogg_stream_state *os);
extern int ogg_stream_reset(ogg_stream_state *os);
extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
extern int ogg_stream_destroy(ogg_stream_state *os);
extern int ogg_stream_check(ogg_stream_state *os);
extern int ogg_stream_eos(ogg_stream_state *os);
extern void ogg_page_checksum_set(ogg_page *og);
extern int ogg_page_version(const ogg_page *og);
extern int ogg_page_continued(const ogg_page *og);
extern int ogg_page_bos(const ogg_page *og);
extern int ogg_page_eos(const ogg_page *og);
extern ogg_int64_t ogg_page_granulepos(const ogg_page *og);
extern int ogg_page_serialno(const ogg_page *og);
extern long ogg_page_pageno(const ogg_page *og);
extern int ogg_page_packets(const ogg_page *og);
extern void ogg_packet_clear(ogg_packet *op);
#ifdef __cplusplus
}
#endif
#endif /* _OGG_H */

View file

@ -0,0 +1,19 @@
#ifndef OGG_OS_TYPES_H
#define OGG_OS_TYPES_H
#include <stdint.h>
#include <stdlib.h>
typedef int16_t ogg_int16_t;
typedef uint16_t ogg_uint16_t;
typedef int32_t ogg_int32_t;
typedef uint32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
typedef uint64_t ogg_uint64_t;
#define _ogg_malloc malloc
#define _ogg_calloc calloc
#define _ogg_realloc realloc
#define _ogg_free free
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,19 @@
/* Hand-written config.h for Apple/SPM build (replaces autoconf-generated file). */
#ifndef OGG_CONFIG_H
#define OGG_CONFIG_H
/* Standard headers are available on all Apple platforms */
#define HAVE_DLFCN_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STDINT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRINGS_H 1
#define HAVE_STRING_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_UNISTD_H 1
/* Keep CRC enabled (do not define DISABLE_CRC) */
#endif

View file

@ -0,0 +1,278 @@
/********************************************************************
* *
* THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2018 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************/
#include <ogg/os_types.h>
static const ogg_uint32_t crc_lookup[8][256]={
{0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4},
{0x00000000,0xd219c1dc,0xa0f29e0f,0x72eb5fd3,0x452421a9,0x973de075,0xe5d6bfa6,0x37cf7e7a,
0x8a484352,0x5851828e,0x2abadd5d,0xf8a31c81,0xcf6c62fb,0x1d75a327,0x6f9efcf4,0xbd873d28,
0x10519b13,0xc2485acf,0xb0a3051c,0x62bac4c0,0x5575baba,0x876c7b66,0xf58724b5,0x279ee569,
0x9a19d841,0x4800199d,0x3aeb464e,0xe8f28792,0xdf3df9e8,0x0d243834,0x7fcf67e7,0xadd6a63b,
0x20a33626,0xf2baf7fa,0x8051a829,0x524869f5,0x6587178f,0xb79ed653,0xc5758980,0x176c485c,
0xaaeb7574,0x78f2b4a8,0x0a19eb7b,0xd8002aa7,0xefcf54dd,0x3dd69501,0x4f3dcad2,0x9d240b0e,
0x30f2ad35,0xe2eb6ce9,0x9000333a,0x4219f2e6,0x75d68c9c,0xa7cf4d40,0xd5241293,0x073dd34f,
0xbabaee67,0x68a32fbb,0x1a487068,0xc851b1b4,0xff9ecfce,0x2d870e12,0x5f6c51c1,0x8d75901d,
0x41466c4c,0x935fad90,0xe1b4f243,0x33ad339f,0x04624de5,0xd67b8c39,0xa490d3ea,0x76891236,
0xcb0e2f1e,0x1917eec2,0x6bfcb111,0xb9e570cd,0x8e2a0eb7,0x5c33cf6b,0x2ed890b8,0xfcc15164,
0x5117f75f,0x830e3683,0xf1e56950,0x23fca88c,0x1433d6f6,0xc62a172a,0xb4c148f9,0x66d88925,
0xdb5fb40d,0x094675d1,0x7bad2a02,0xa9b4ebde,0x9e7b95a4,0x4c625478,0x3e890bab,0xec90ca77,
0x61e55a6a,0xb3fc9bb6,0xc117c465,0x130e05b9,0x24c17bc3,0xf6d8ba1f,0x8433e5cc,0x562a2410,
0xebad1938,0x39b4d8e4,0x4b5f8737,0x994646eb,0xae893891,0x7c90f94d,0x0e7ba69e,0xdc626742,
0x71b4c179,0xa3ad00a5,0xd1465f76,0x035f9eaa,0x3490e0d0,0xe689210c,0x94627edf,0x467bbf03,
0xfbfc822b,0x29e543f7,0x5b0e1c24,0x8917ddf8,0xbed8a382,0x6cc1625e,0x1e2a3d8d,0xcc33fc51,
0x828cd898,0x50951944,0x227e4697,0xf067874b,0xc7a8f931,0x15b138ed,0x675a673e,0xb543a6e2,
0x08c49bca,0xdadd5a16,0xa83605c5,0x7a2fc419,0x4de0ba63,0x9ff97bbf,0xed12246c,0x3f0be5b0,
0x92dd438b,0x40c48257,0x322fdd84,0xe0361c58,0xd7f96222,0x05e0a3fe,0x770bfc2d,0xa5123df1,
0x189500d9,0xca8cc105,0xb8679ed6,0x6a7e5f0a,0x5db12170,0x8fa8e0ac,0xfd43bf7f,0x2f5a7ea3,
0xa22feebe,0x70362f62,0x02dd70b1,0xd0c4b16d,0xe70bcf17,0x35120ecb,0x47f95118,0x95e090c4,
0x2867adec,0xfa7e6c30,0x889533e3,0x5a8cf23f,0x6d438c45,0xbf5a4d99,0xcdb1124a,0x1fa8d396,
0xb27e75ad,0x6067b471,0x128ceba2,0xc0952a7e,0xf75a5404,0x254395d8,0x57a8ca0b,0x85b10bd7,
0x383636ff,0xea2ff723,0x98c4a8f0,0x4add692c,0x7d121756,0xaf0bd68a,0xdde08959,0x0ff94885,
0xc3cab4d4,0x11d37508,0x63382adb,0xb121eb07,0x86ee957d,0x54f754a1,0x261c0b72,0xf405caae,
0x4982f786,0x9b9b365a,0xe9706989,0x3b69a855,0x0ca6d62f,0xdebf17f3,0xac544820,0x7e4d89fc,
0xd39b2fc7,0x0182ee1b,0x7369b1c8,0xa1707014,0x96bf0e6e,0x44a6cfb2,0x364d9061,0xe45451bd,
0x59d36c95,0x8bcaad49,0xf921f29a,0x2b383346,0x1cf74d3c,0xceee8ce0,0xbc05d333,0x6e1c12ef,
0xe36982f2,0x3170432e,0x439b1cfd,0x9182dd21,0xa64da35b,0x74546287,0x06bf3d54,0xd4a6fc88,
0x6921c1a0,0xbb38007c,0xc9d35faf,0x1bca9e73,0x2c05e009,0xfe1c21d5,0x8cf77e06,0x5eeebfda,
0xf33819e1,0x2121d83d,0x53ca87ee,0x81d34632,0xb61c3848,0x6405f994,0x16eea647,0xc4f7679b,
0x79705ab3,0xab699b6f,0xd982c4bc,0x0b9b0560,0x3c547b1a,0xee4dbac6,0x9ca6e515,0x4ebf24c9},
{0x00000000,0x01d8ac87,0x03b1590e,0x0269f589,0x0762b21c,0x06ba1e9b,0x04d3eb12,0x050b4795,
0x0ec56438,0x0f1dc8bf,0x0d743d36,0x0cac91b1,0x09a7d624,0x087f7aa3,0x0a168f2a,0x0bce23ad,
0x1d8ac870,0x1c5264f7,0x1e3b917e,0x1fe33df9,0x1ae87a6c,0x1b30d6eb,0x19592362,0x18818fe5,
0x134fac48,0x129700cf,0x10fef546,0x112659c1,0x142d1e54,0x15f5b2d3,0x179c475a,0x1644ebdd,
0x3b1590e0,0x3acd3c67,0x38a4c9ee,0x397c6569,0x3c7722fc,0x3daf8e7b,0x3fc67bf2,0x3e1ed775,
0x35d0f4d8,0x3408585f,0x3661add6,0x37b90151,0x32b246c4,0x336aea43,0x31031fca,0x30dbb34d,
0x269f5890,0x2747f417,0x252e019e,0x24f6ad19,0x21fdea8c,0x2025460b,0x224cb382,0x23941f05,
0x285a3ca8,0x2982902f,0x2beb65a6,0x2a33c921,0x2f388eb4,0x2ee02233,0x2c89d7ba,0x2d517b3d,
0x762b21c0,0x77f38d47,0x759a78ce,0x7442d449,0x714993dc,0x70913f5b,0x72f8cad2,0x73206655,
0x78ee45f8,0x7936e97f,0x7b5f1cf6,0x7a87b071,0x7f8cf7e4,0x7e545b63,0x7c3daeea,0x7de5026d,
0x6ba1e9b0,0x6a794537,0x6810b0be,0x69c81c39,0x6cc35bac,0x6d1bf72b,0x6f7202a2,0x6eaaae25,
0x65648d88,0x64bc210f,0x66d5d486,0x670d7801,0x62063f94,0x63de9313,0x61b7669a,0x606fca1d,
0x4d3eb120,0x4ce61da7,0x4e8fe82e,0x4f5744a9,0x4a5c033c,0x4b84afbb,0x49ed5a32,0x4835f6b5,
0x43fbd518,0x4223799f,0x404a8c16,0x41922091,0x44996704,0x4541cb83,0x47283e0a,0x46f0928d,
0x50b47950,0x516cd5d7,0x5305205e,0x52dd8cd9,0x57d6cb4c,0x560e67cb,0x54679242,0x55bf3ec5,
0x5e711d68,0x5fa9b1ef,0x5dc04466,0x5c18e8e1,0x5913af74,0x58cb03f3,0x5aa2f67a,0x5b7a5afd,
0xec564380,0xed8eef07,0xefe71a8e,0xee3fb609,0xeb34f19c,0xeaec5d1b,0xe885a892,0xe95d0415,
0xe29327b8,0xe34b8b3f,0xe1227eb6,0xe0fad231,0xe5f195a4,0xe4293923,0xe640ccaa,0xe798602d,
0xf1dc8bf0,0xf0042777,0xf26dd2fe,0xf3b57e79,0xf6be39ec,0xf766956b,0xf50f60e2,0xf4d7cc65,
0xff19efc8,0xfec1434f,0xfca8b6c6,0xfd701a41,0xf87b5dd4,0xf9a3f153,0xfbca04da,0xfa12a85d,
0xd743d360,0xd69b7fe7,0xd4f28a6e,0xd52a26e9,0xd021617c,0xd1f9cdfb,0xd3903872,0xd24894f5,
0xd986b758,0xd85e1bdf,0xda37ee56,0xdbef42d1,0xdee40544,0xdf3ca9c3,0xdd555c4a,0xdc8df0cd,
0xcac91b10,0xcb11b797,0xc978421e,0xc8a0ee99,0xcdaba90c,0xcc73058b,0xce1af002,0xcfc25c85,
0xc40c7f28,0xc5d4d3af,0xc7bd2626,0xc6658aa1,0xc36ecd34,0xc2b661b3,0xc0df943a,0xc10738bd,
0x9a7d6240,0x9ba5cec7,0x99cc3b4e,0x981497c9,0x9d1fd05c,0x9cc77cdb,0x9eae8952,0x9f7625d5,
0x94b80678,0x9560aaff,0x97095f76,0x96d1f3f1,0x93dab464,0x920218e3,0x906bed6a,0x91b341ed,
0x87f7aa30,0x862f06b7,0x8446f33e,0x859e5fb9,0x8095182c,0x814db4ab,0x83244122,0x82fceda5,
0x8932ce08,0x88ea628f,0x8a839706,0x8b5b3b81,0x8e507c14,0x8f88d093,0x8de1251a,0x8c39899d,
0xa168f2a0,0xa0b05e27,0xa2d9abae,0xa3010729,0xa60a40bc,0xa7d2ec3b,0xa5bb19b2,0xa463b535,
0xafad9698,0xae753a1f,0xac1ccf96,0xadc46311,0xa8cf2484,0xa9178803,0xab7e7d8a,0xaaa6d10d,
0xbce23ad0,0xbd3a9657,0xbf5363de,0xbe8bcf59,0xbb8088cc,0xba58244b,0xb831d1c2,0xb9e97d45,
0xb2275ee8,0xb3fff26f,0xb19607e6,0xb04eab61,0xb545ecf4,0xb49d4073,0xb6f4b5fa,0xb72c197d},
{0x00000000,0xdc6d9ab7,0xbc1a28d9,0x6077b26e,0x7cf54c05,0xa098d6b2,0xc0ef64dc,0x1c82fe6b,
0xf9ea980a,0x258702bd,0x45f0b0d3,0x999d2a64,0x851fd40f,0x59724eb8,0x3905fcd6,0xe5686661,
0xf7142da3,0x2b79b714,0x4b0e057a,0x97639fcd,0x8be161a6,0x578cfb11,0x37fb497f,0xeb96d3c8,
0x0efeb5a9,0xd2932f1e,0xb2e49d70,0x6e8907c7,0x720bf9ac,0xae66631b,0xce11d175,0x127c4bc2,
0xeae946f1,0x3684dc46,0x56f36e28,0x8a9ef49f,0x961c0af4,0x4a719043,0x2a06222d,0xf66bb89a,
0x1303defb,0xcf6e444c,0xaf19f622,0x73746c95,0x6ff692fe,0xb39b0849,0xd3ecba27,0x0f812090,
0x1dfd6b52,0xc190f1e5,0xa1e7438b,0x7d8ad93c,0x61082757,0xbd65bde0,0xdd120f8e,0x017f9539,
0xe417f358,0x387a69ef,0x580ddb81,0x84604136,0x98e2bf5d,0x448f25ea,0x24f89784,0xf8950d33,
0xd1139055,0x0d7e0ae2,0x6d09b88c,0xb164223b,0xade6dc50,0x718b46e7,0x11fcf489,0xcd916e3e,
0x28f9085f,0xf49492e8,0x94e32086,0x488eba31,0x540c445a,0x8861deed,0xe8166c83,0x347bf634,
0x2607bdf6,0xfa6a2741,0x9a1d952f,0x46700f98,0x5af2f1f3,0x869f6b44,0xe6e8d92a,0x3a85439d,
0xdfed25fc,0x0380bf4b,0x63f70d25,0xbf9a9792,0xa31869f9,0x7f75f34e,0x1f024120,0xc36fdb97,
0x3bfad6a4,0xe7974c13,0x87e0fe7d,0x5b8d64ca,0x470f9aa1,0x9b620016,0xfb15b278,0x277828cf,
0xc2104eae,0x1e7dd419,0x7e0a6677,0xa267fcc0,0xbee502ab,0x6288981c,0x02ff2a72,0xde92b0c5,
0xcceefb07,0x108361b0,0x70f4d3de,0xac994969,0xb01bb702,0x6c762db5,0x0c019fdb,0xd06c056c,
0x3504630d,0xe969f9ba,0x891e4bd4,0x5573d163,0x49f12f08,0x959cb5bf,0xf5eb07d1,0x29869d66,
0xa6e63d1d,0x7a8ba7aa,0x1afc15c4,0xc6918f73,0xda137118,0x067eebaf,0x660959c1,0xba64c376,
0x5f0ca517,0x83613fa0,0xe3168dce,0x3f7b1779,0x23f9e912,0xff9473a5,0x9fe3c1cb,0x438e5b7c,
0x51f210be,0x8d9f8a09,0xede83867,0x3185a2d0,0x2d075cbb,0xf16ac60c,0x911d7462,0x4d70eed5,
0xa81888b4,0x74751203,0x1402a06d,0xc86f3ada,0xd4edc4b1,0x08805e06,0x68f7ec68,0xb49a76df,
0x4c0f7bec,0x9062e15b,0xf0155335,0x2c78c982,0x30fa37e9,0xec97ad5e,0x8ce01f30,0x508d8587,
0xb5e5e3e6,0x69887951,0x09ffcb3f,0xd5925188,0xc910afe3,0x157d3554,0x750a873a,0xa9671d8d,
0xbb1b564f,0x6776ccf8,0x07017e96,0xdb6ce421,0xc7ee1a4a,0x1b8380fd,0x7bf43293,0xa799a824,
0x42f1ce45,0x9e9c54f2,0xfeebe69c,0x22867c2b,0x3e048240,0xe26918f7,0x821eaa99,0x5e73302e,
0x77f5ad48,0xab9837ff,0xcbef8591,0x17821f26,0x0b00e14d,0xd76d7bfa,0xb71ac994,0x6b775323,
0x8e1f3542,0x5272aff5,0x32051d9b,0xee68872c,0xf2ea7947,0x2e87e3f0,0x4ef0519e,0x929dcb29,
0x80e180eb,0x5c8c1a5c,0x3cfba832,0xe0963285,0xfc14ccee,0x20795659,0x400ee437,0x9c637e80,
0x790b18e1,0xa5668256,0xc5113038,0x197caa8f,0x05fe54e4,0xd993ce53,0xb9e47c3d,0x6589e68a,
0x9d1cebb9,0x4171710e,0x2106c360,0xfd6b59d7,0xe1e9a7bc,0x3d843d0b,0x5df38f65,0x819e15d2,
0x64f673b3,0xb89be904,0xd8ec5b6a,0x0481c1dd,0x18033fb6,0xc46ea501,0xa419176f,0x78748dd8,
0x6a08c61a,0xb6655cad,0xd612eec3,0x0a7f7474,0x16fd8a1f,0xca9010a8,0xaae7a2c6,0x768a3871,
0x93e25e10,0x4f8fc4a7,0x2ff876c9,0xf395ec7e,0xef171215,0x337a88a2,0x530d3acc,0x8f60a07b},
{0x00000000,0x490d678d,0x921acf1a,0xdb17a897,0x20f48383,0x69f9e40e,0xb2ee4c99,0xfbe32b14,
0x41e90706,0x08e4608b,0xd3f3c81c,0x9afeaf91,0x611d8485,0x2810e308,0xf3074b9f,0xba0a2c12,
0x83d20e0c,0xcadf6981,0x11c8c116,0x58c5a69b,0xa3268d8f,0xea2bea02,0x313c4295,0x78312518,
0xc23b090a,0x8b366e87,0x5021c610,0x192ca19d,0xe2cf8a89,0xabc2ed04,0x70d54593,0x39d8221e,
0x036501af,0x4a686622,0x917fceb5,0xd872a938,0x2391822c,0x6a9ce5a1,0xb18b4d36,0xf8862abb,
0x428c06a9,0x0b816124,0xd096c9b3,0x999bae3e,0x6278852a,0x2b75e2a7,0xf0624a30,0xb96f2dbd,
0x80b70fa3,0xc9ba682e,0x12adc0b9,0x5ba0a734,0xa0438c20,0xe94eebad,0x3259433a,0x7b5424b7,
0xc15e08a5,0x88536f28,0x5344c7bf,0x1a49a032,0xe1aa8b26,0xa8a7ecab,0x73b0443c,0x3abd23b1,
0x06ca035e,0x4fc764d3,0x94d0cc44,0xddddabc9,0x263e80dd,0x6f33e750,0xb4244fc7,0xfd29284a,
0x47230458,0x0e2e63d5,0xd539cb42,0x9c34accf,0x67d787db,0x2edae056,0xf5cd48c1,0xbcc02f4c,
0x85180d52,0xcc156adf,0x1702c248,0x5e0fa5c5,0xa5ec8ed1,0xece1e95c,0x37f641cb,0x7efb2646,
0xc4f10a54,0x8dfc6dd9,0x56ebc54e,0x1fe6a2c3,0xe40589d7,0xad08ee5a,0x761f46cd,0x3f122140,
0x05af02f1,0x4ca2657c,0x97b5cdeb,0xdeb8aa66,0x255b8172,0x6c56e6ff,0xb7414e68,0xfe4c29e5,
0x444605f7,0x0d4b627a,0xd65ccaed,0x9f51ad60,0x64b28674,0x2dbfe1f9,0xf6a8496e,0xbfa52ee3,
0x867d0cfd,0xcf706b70,0x1467c3e7,0x5d6aa46a,0xa6898f7e,0xef84e8f3,0x34934064,0x7d9e27e9,
0xc7940bfb,0x8e996c76,0x558ec4e1,0x1c83a36c,0xe7608878,0xae6deff5,0x757a4762,0x3c7720ef,
0x0d9406bc,0x44996131,0x9f8ec9a6,0xd683ae2b,0x2d60853f,0x646de2b2,0xbf7a4a25,0xf6772da8,
0x4c7d01ba,0x05706637,0xde67cea0,0x976aa92d,0x6c898239,0x2584e5b4,0xfe934d23,0xb79e2aae,
0x8e4608b0,0xc74b6f3d,0x1c5cc7aa,0x5551a027,0xaeb28b33,0xe7bfecbe,0x3ca84429,0x75a523a4,
0xcfaf0fb6,0x86a2683b,0x5db5c0ac,0x14b8a721,0xef5b8c35,0xa656ebb8,0x7d41432f,0x344c24a2,
0x0ef10713,0x47fc609e,0x9cebc809,0xd5e6af84,0x2e058490,0x6708e31d,0xbc1f4b8a,0xf5122c07,
0x4f180015,0x06156798,0xdd02cf0f,0x940fa882,0x6fec8396,0x26e1e41b,0xfdf64c8c,0xb4fb2b01,
0x8d23091f,0xc42e6e92,0x1f39c605,0x5634a188,0xadd78a9c,0xe4daed11,0x3fcd4586,0x76c0220b,
0xccca0e19,0x85c76994,0x5ed0c103,0x17dda68e,0xec3e8d9a,0xa533ea17,0x7e244280,0x3729250d,
0x0b5e05e2,0x4253626f,0x9944caf8,0xd049ad75,0x2baa8661,0x62a7e1ec,0xb9b0497b,0xf0bd2ef6,
0x4ab702e4,0x03ba6569,0xd8adcdfe,0x91a0aa73,0x6a438167,0x234ee6ea,0xf8594e7d,0xb15429f0,
0x888c0bee,0xc1816c63,0x1a96c4f4,0x539ba379,0xa878886d,0xe175efe0,0x3a624777,0x736f20fa,
0xc9650ce8,0x80686b65,0x5b7fc3f2,0x1272a47f,0xe9918f6b,0xa09ce8e6,0x7b8b4071,0x328627fc,
0x083b044d,0x413663c0,0x9a21cb57,0xd32cacda,0x28cf87ce,0x61c2e043,0xbad548d4,0xf3d82f59,
0x49d2034b,0x00df64c6,0xdbc8cc51,0x92c5abdc,0x692680c8,0x202be745,0xfb3c4fd2,0xb231285f,
0x8be90a41,0xc2e46dcc,0x19f3c55b,0x50fea2d6,0xab1d89c2,0xe210ee4f,0x390746d8,0x700a2155,
0xca000d47,0x830d6aca,0x581ac25d,0x1117a5d0,0xeaf48ec4,0xa3f9e949,0x78ee41de,0x31e32653},
{0x00000000,0x1b280d78,0x36501af0,0x2d781788,0x6ca035e0,0x77883898,0x5af02f10,0x41d82268,
0xd9406bc0,0xc26866b8,0xef107130,0xf4387c48,0xb5e05e20,0xaec85358,0x83b044d0,0x989849a8,
0xb641ca37,0xad69c74f,0x8011d0c7,0x9b39ddbf,0xdae1ffd7,0xc1c9f2af,0xecb1e527,0xf799e85f,
0x6f01a1f7,0x7429ac8f,0x5951bb07,0x4279b67f,0x03a19417,0x1889996f,0x35f18ee7,0x2ed9839f,
0x684289d9,0x736a84a1,0x5e129329,0x453a9e51,0x04e2bc39,0x1fcab141,0x32b2a6c9,0x299aabb1,
0xb102e219,0xaa2aef61,0x8752f8e9,0x9c7af591,0xdda2d7f9,0xc68ada81,0xebf2cd09,0xf0dac071,
0xde0343ee,0xc52b4e96,0xe853591e,0xf37b5466,0xb2a3760e,0xa98b7b76,0x84f36cfe,0x9fdb6186,
0x0743282e,0x1c6b2556,0x311332de,0x2a3b3fa6,0x6be31dce,0x70cb10b6,0x5db3073e,0x469b0a46,
0xd08513b2,0xcbad1eca,0xe6d50942,0xfdfd043a,0xbc252652,0xa70d2b2a,0x8a753ca2,0x915d31da,
0x09c57872,0x12ed750a,0x3f956282,0x24bd6ffa,0x65654d92,0x7e4d40ea,0x53355762,0x481d5a1a,
0x66c4d985,0x7decd4fd,0x5094c375,0x4bbcce0d,0x0a64ec65,0x114ce11d,0x3c34f695,0x271cfbed,
0xbf84b245,0xa4acbf3d,0x89d4a8b5,0x92fca5cd,0xd32487a5,0xc80c8add,0xe5749d55,0xfe5c902d,
0xb8c79a6b,0xa3ef9713,0x8e97809b,0x95bf8de3,0xd467af8b,0xcf4fa2f3,0xe237b57b,0xf91fb803,
0x6187f1ab,0x7aaffcd3,0x57d7eb5b,0x4cffe623,0x0d27c44b,0x160fc933,0x3b77debb,0x205fd3c3,
0x0e86505c,0x15ae5d24,0x38d64aac,0x23fe47d4,0x622665bc,0x790e68c4,0x54767f4c,0x4f5e7234,
0xd7c63b9c,0xccee36e4,0xe196216c,0xfabe2c14,0xbb660e7c,0xa04e0304,0x8d36148c,0x961e19f4,
0xa5cb3ad3,0xbee337ab,0x939b2023,0x88b32d5b,0xc96b0f33,0xd243024b,0xff3b15c3,0xe41318bb,
0x7c8b5113,0x67a35c6b,0x4adb4be3,0x51f3469b,0x102b64f3,0x0b03698b,0x267b7e03,0x3d53737b,
0x138af0e4,0x08a2fd9c,0x25daea14,0x3ef2e76c,0x7f2ac504,0x6402c87c,0x497adff4,0x5252d28c,
0xcaca9b24,0xd1e2965c,0xfc9a81d4,0xe7b28cac,0xa66aaec4,0xbd42a3bc,0x903ab434,0x8b12b94c,
0xcd89b30a,0xd6a1be72,0xfbd9a9fa,0xe0f1a482,0xa12986ea,0xba018b92,0x97799c1a,0x8c519162,
0x14c9d8ca,0x0fe1d5b2,0x2299c23a,0x39b1cf42,0x7869ed2a,0x6341e052,0x4e39f7da,0x5511faa2,
0x7bc8793d,0x60e07445,0x4d9863cd,0x56b06eb5,0x17684cdd,0x0c4041a5,0x2138562d,0x3a105b55,
0xa28812fd,0xb9a01f85,0x94d8080d,0x8ff00575,0xce28271d,0xd5002a65,0xf8783ded,0xe3503095,
0x754e2961,0x6e662419,0x431e3391,0x58363ee9,0x19ee1c81,0x02c611f9,0x2fbe0671,0x34960b09,
0xac0e42a1,0xb7264fd9,0x9a5e5851,0x81765529,0xc0ae7741,0xdb867a39,0xf6fe6db1,0xedd660c9,
0xc30fe356,0xd827ee2e,0xf55ff9a6,0xee77f4de,0xafafd6b6,0xb487dbce,0x99ffcc46,0x82d7c13e,
0x1a4f8896,0x016785ee,0x2c1f9266,0x37379f1e,0x76efbd76,0x6dc7b00e,0x40bfa786,0x5b97aafe,
0x1d0ca0b8,0x0624adc0,0x2b5cba48,0x3074b730,0x71ac9558,0x6a849820,0x47fc8fa8,0x5cd482d0,
0xc44ccb78,0xdf64c600,0xf21cd188,0xe934dcf0,0xa8ecfe98,0xb3c4f3e0,0x9ebce468,0x8594e910,
0xab4d6a8f,0xb06567f7,0x9d1d707f,0x86357d07,0xc7ed5f6f,0xdcc55217,0xf1bd459f,0xea9548e7,
0x720d014f,0x69250c37,0x445d1bbf,0x5f7516c7,0x1ead34af,0x058539d7,0x28fd2e5f,0x33d52327},
{0x00000000,0x4f576811,0x9eaed022,0xd1f9b833,0x399cbdf3,0x76cbd5e2,0xa7326dd1,0xe86505c0,
0x73397be6,0x3c6e13f7,0xed97abc4,0xa2c0c3d5,0x4aa5c615,0x05f2ae04,0xd40b1637,0x9b5c7e26,
0xe672f7cc,0xa9259fdd,0x78dc27ee,0x378b4fff,0xdfee4a3f,0x90b9222e,0x41409a1d,0x0e17f20c,
0x954b8c2a,0xda1ce43b,0x0be55c08,0x44b23419,0xacd731d9,0xe38059c8,0x3279e1fb,0x7d2e89ea,
0xc824f22f,0x87739a3e,0x568a220d,0x19dd4a1c,0xf1b84fdc,0xbeef27cd,0x6f169ffe,0x2041f7ef,
0xbb1d89c9,0xf44ae1d8,0x25b359eb,0x6ae431fa,0x8281343a,0xcdd65c2b,0x1c2fe418,0x53788c09,
0x2e5605e3,0x61016df2,0xb0f8d5c1,0xffafbdd0,0x17cab810,0x589dd001,0x89646832,0xc6330023,
0x5d6f7e05,0x12381614,0xc3c1ae27,0x8c96c636,0x64f3c3f6,0x2ba4abe7,0xfa5d13d4,0xb50a7bc5,
0x9488f9e9,0xdbdf91f8,0x0a2629cb,0x457141da,0xad14441a,0xe2432c0b,0x33ba9438,0x7cedfc29,
0xe7b1820f,0xa8e6ea1e,0x791f522d,0x36483a3c,0xde2d3ffc,0x917a57ed,0x4083efde,0x0fd487cf,
0x72fa0e25,0x3dad6634,0xec54de07,0xa303b616,0x4b66b3d6,0x0431dbc7,0xd5c863f4,0x9a9f0be5,
0x01c375c3,0x4e941dd2,0x9f6da5e1,0xd03acdf0,0x385fc830,0x7708a021,0xa6f11812,0xe9a67003,
0x5cac0bc6,0x13fb63d7,0xc202dbe4,0x8d55b3f5,0x6530b635,0x2a67de24,0xfb9e6617,0xb4c90e06,
0x2f957020,0x60c21831,0xb13ba002,0xfe6cc813,0x1609cdd3,0x595ea5c2,0x88a71df1,0xc7f075e0,
0xbadefc0a,0xf589941b,0x24702c28,0x6b274439,0x834241f9,0xcc1529e8,0x1dec91db,0x52bbf9ca,
0xc9e787ec,0x86b0effd,0x574957ce,0x181e3fdf,0xf07b3a1f,0xbf2c520e,0x6ed5ea3d,0x2182822c,
0x2dd0ee65,0x62878674,0xb37e3e47,0xfc295656,0x144c5396,0x5b1b3b87,0x8ae283b4,0xc5b5eba5,
0x5ee99583,0x11befd92,0xc04745a1,0x8f102db0,0x67752870,0x28224061,0xf9dbf852,0xb68c9043,
0xcba219a9,0x84f571b8,0x550cc98b,0x1a5ba19a,0xf23ea45a,0xbd69cc4b,0x6c907478,0x23c71c69,
0xb89b624f,0xf7cc0a5e,0x2635b26d,0x6962da7c,0x8107dfbc,0xce50b7ad,0x1fa90f9e,0x50fe678f,
0xe5f41c4a,0xaaa3745b,0x7b5acc68,0x340da479,0xdc68a1b9,0x933fc9a8,0x42c6719b,0x0d91198a,
0x96cd67ac,0xd99a0fbd,0x0863b78e,0x4734df9f,0xaf51da5f,0xe006b24e,0x31ff0a7d,0x7ea8626c,
0x0386eb86,0x4cd18397,0x9d283ba4,0xd27f53b5,0x3a1a5675,0x754d3e64,0xa4b48657,0xebe3ee46,
0x70bf9060,0x3fe8f871,0xee114042,0xa1462853,0x49232d93,0x06744582,0xd78dfdb1,0x98da95a0,
0xb958178c,0xf60f7f9d,0x27f6c7ae,0x68a1afbf,0x80c4aa7f,0xcf93c26e,0x1e6a7a5d,0x513d124c,
0xca616c6a,0x8536047b,0x54cfbc48,0x1b98d459,0xf3fdd199,0xbcaab988,0x6d5301bb,0x220469aa,
0x5f2ae040,0x107d8851,0xc1843062,0x8ed35873,0x66b65db3,0x29e135a2,0xf8188d91,0xb74fe580,
0x2c139ba6,0x6344f3b7,0xb2bd4b84,0xfdea2395,0x158f2655,0x5ad84e44,0x8b21f677,0xc4769e66,
0x717ce5a3,0x3e2b8db2,0xefd23581,0xa0855d90,0x48e05850,0x07b73041,0xd64e8872,0x9919e063,
0x02459e45,0x4d12f654,0x9ceb4e67,0xd3bc2676,0x3bd923b6,0x748e4ba7,0xa577f394,0xea209b85,
0x970e126f,0xd8597a7e,0x09a0c24d,0x46f7aa5c,0xae92af9c,0xe1c5c78d,0x303c7fbe,0x7f6b17af,
0xe4376989,0xab600198,0x7a99b9ab,0x35ced1ba,0xddabd47a,0x92fcbc6b,0x43050458,0x0c526c49},
{0x00000000,0x5ba1dcca,0xb743b994,0xece2655e,0x6a466e9f,0x31e7b255,0xdd05d70b,0x86a40bc1,
0xd48cdd3e,0x8f2d01f4,0x63cf64aa,0x386eb860,0xbecab3a1,0xe56b6f6b,0x09890a35,0x5228d6ff,
0xadd8a7cb,0xf6797b01,0x1a9b1e5f,0x413ac295,0xc79ec954,0x9c3f159e,0x70dd70c0,0x2b7cac0a,
0x79547af5,0x22f5a63f,0xce17c361,0x95b61fab,0x1312146a,0x48b3c8a0,0xa451adfe,0xfff07134,
0x5f705221,0x04d18eeb,0xe833ebb5,0xb392377f,0x35363cbe,0x6e97e074,0x8275852a,0xd9d459e0,
0x8bfc8f1f,0xd05d53d5,0x3cbf368b,0x671eea41,0xe1bae180,0xba1b3d4a,0x56f95814,0x0d5884de,
0xf2a8f5ea,0xa9092920,0x45eb4c7e,0x1e4a90b4,0x98ee9b75,0xc34f47bf,0x2fad22e1,0x740cfe2b,
0x262428d4,0x7d85f41e,0x91679140,0xcac64d8a,0x4c62464b,0x17c39a81,0xfb21ffdf,0xa0802315,
0xbee0a442,0xe5417888,0x09a31dd6,0x5202c11c,0xd4a6cadd,0x8f071617,0x63e57349,0x3844af83,
0x6a6c797c,0x31cda5b6,0xdd2fc0e8,0x868e1c22,0x002a17e3,0x5b8bcb29,0xb769ae77,0xecc872bd,
0x13380389,0x4899df43,0xa47bba1d,0xffda66d7,0x797e6d16,0x22dfb1dc,0xce3dd482,0x959c0848,
0xc7b4deb7,0x9c15027d,0x70f76723,0x2b56bbe9,0xadf2b028,0xf6536ce2,0x1ab109bc,0x4110d576,
0xe190f663,0xba312aa9,0x56d34ff7,0x0d72933d,0x8bd698fc,0xd0774436,0x3c952168,0x6734fda2,
0x351c2b5d,0x6ebdf797,0x825f92c9,0xd9fe4e03,0x5f5a45c2,0x04fb9908,0xe819fc56,0xb3b8209c,
0x4c4851a8,0x17e98d62,0xfb0be83c,0xa0aa34f6,0x260e3f37,0x7dafe3fd,0x914d86a3,0xcaec5a69,
0x98c48c96,0xc365505c,0x2f873502,0x7426e9c8,0xf282e209,0xa9233ec3,0x45c15b9d,0x1e608757,
0x79005533,0x22a189f9,0xce43eca7,0x95e2306d,0x13463bac,0x48e7e766,0xa4058238,0xffa45ef2,
0xad8c880d,0xf62d54c7,0x1acf3199,0x416eed53,0xc7cae692,0x9c6b3a58,0x70895f06,0x2b2883cc,
0xd4d8f2f8,0x8f792e32,0x639b4b6c,0x383a97a6,0xbe9e9c67,0xe53f40ad,0x09dd25f3,0x527cf939,
0x00542fc6,0x5bf5f30c,0xb7179652,0xecb64a98,0x6a124159,0x31b39d93,0xdd51f8cd,0x86f02407,
0x26700712,0x7dd1dbd8,0x9133be86,0xca92624c,0x4c36698d,0x1797b547,0xfb75d019,0xa0d40cd3,
0xf2fcda2c,0xa95d06e6,0x45bf63b8,0x1e1ebf72,0x98bab4b3,0xc31b6879,0x2ff90d27,0x7458d1ed,
0x8ba8a0d9,0xd0097c13,0x3ceb194d,0x674ac587,0xe1eece46,0xba4f128c,0x56ad77d2,0x0d0cab18,
0x5f247de7,0x0485a12d,0xe867c473,0xb3c618b9,0x35621378,0x6ec3cfb2,0x8221aaec,0xd9807626,
0xc7e0f171,0x9c412dbb,0x70a348e5,0x2b02942f,0xada69fee,0xf6074324,0x1ae5267a,0x4144fab0,
0x136c2c4f,0x48cdf085,0xa42f95db,0xff8e4911,0x792a42d0,0x228b9e1a,0xce69fb44,0x95c8278e,
0x6a3856ba,0x31998a70,0xdd7bef2e,0x86da33e4,0x007e3825,0x5bdfe4ef,0xb73d81b1,0xec9c5d7b,
0xbeb48b84,0xe515574e,0x09f73210,0x5256eeda,0xd4f2e51b,0x8f5339d1,0x63b15c8f,0x38108045,
0x9890a350,0xc3317f9a,0x2fd31ac4,0x7472c60e,0xf2d6cdcf,0xa9771105,0x4595745b,0x1e34a891,
0x4c1c7e6e,0x17bda2a4,0xfb5fc7fa,0xa0fe1b30,0x265a10f1,0x7dfbcc3b,0x9119a965,0xcab875af,
0x3548049b,0x6ee9d851,0x820bbd0f,0xd9aa61c5,0x5f0e6a04,0x04afb6ce,0xe84dd390,0xb3ec0f5a,
0xe1c4d9a5,0xba65056f,0x56876031,0x0d26bcfb,0x8b82b73a,0xd0236bf0,0x3cc10eae,0x6760d264}};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,7 @@
#ifndef COpus_h
#define COpus_h
#include <opus.h>
#include <opus_multistream.h>
#endif

View file

@ -0,0 +1,7 @@
module COpus {
header "opus.h"
header "opus_defines.h"
header "opus_multistream.h"
header "opus_types.h"
export *
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,830 @@
/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited
Written by Jean-Marc Valin and Koen Vos */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file opus_defines.h
* @brief Opus reference implementation constants
*/
#ifndef OPUS_DEFINES_H
#define OPUS_DEFINES_H
#include "opus_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup opus_errorcodes Error codes
* @{
*/
/** No error @hideinitializer*/
#define OPUS_OK 0
/** One or more invalid/out of range arguments @hideinitializer*/
#define OPUS_BAD_ARG -1
/** Not enough bytes allocated in the buffer @hideinitializer*/
#define OPUS_BUFFER_TOO_SMALL -2
/** An internal error was detected @hideinitializer*/
#define OPUS_INTERNAL_ERROR -3
/** The compressed data passed is corrupted @hideinitializer*/
#define OPUS_INVALID_PACKET -4
/** Invalid/unsupported request number @hideinitializer*/
#define OPUS_UNIMPLEMENTED -5
/** An encoder or decoder structure is invalid or already freed @hideinitializer*/
#define OPUS_INVALID_STATE -6
/** Memory allocation has failed @hideinitializer*/
#define OPUS_ALLOC_FAIL -7
/**@}*/
/** @cond OPUS_INTERNAL_DOC */
/**Export control for opus functions */
#ifndef OPUS_EXPORT
# if defined(_WIN32)
# if defined(OPUS_BUILD) && defined(DLL_EXPORT)
# define OPUS_EXPORT __declspec(dllexport)
# else
# define OPUS_EXPORT
# endif
# elif defined(__GNUC__) && defined(OPUS_BUILD)
# define OPUS_EXPORT __attribute__ ((visibility ("default")))
# else
# define OPUS_EXPORT
# endif
#endif
# if !defined(OPUS_GNUC_PREREQ)
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
# define OPUS_GNUC_PREREQ(_maj,_min) \
((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
# else
# define OPUS_GNUC_PREREQ(_maj,_min) 0
# endif
# endif
#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
# if OPUS_GNUC_PREREQ(3,0)
# define OPUS_RESTRICT __restrict__
# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
# define OPUS_RESTRICT __restrict
# else
# define OPUS_RESTRICT
# endif
#else
# define OPUS_RESTRICT restrict
#endif
#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
# if OPUS_GNUC_PREREQ(2,7)
# define OPUS_INLINE __inline__
# elif (defined(_MSC_VER))
# define OPUS_INLINE __inline
# else
# define OPUS_INLINE
# endif
#else
# define OPUS_INLINE inline
#endif
/**Warning attributes for opus functions
* NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out
* some paranoid null checks. */
#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)
# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
#else
# define OPUS_WARN_UNUSED_RESULT
#endif
#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4)
# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x)))
#else
# define OPUS_ARG_NONNULL(_x)
#endif
/** These are the actual Encoder CTL ID numbers.
* They should not be used directly by applications.
* In general, SETs should be even and GETs should be odd.*/
#define OPUS_SET_APPLICATION_REQUEST 4000
#define OPUS_GET_APPLICATION_REQUEST 4001
#define OPUS_SET_BITRATE_REQUEST 4002
#define OPUS_GET_BITRATE_REQUEST 4003
#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004
#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005
#define OPUS_SET_VBR_REQUEST 4006
#define OPUS_GET_VBR_REQUEST 4007
#define OPUS_SET_BANDWIDTH_REQUEST 4008
#define OPUS_GET_BANDWIDTH_REQUEST 4009
#define OPUS_SET_COMPLEXITY_REQUEST 4010
#define OPUS_GET_COMPLEXITY_REQUEST 4011
#define OPUS_SET_INBAND_FEC_REQUEST 4012
#define OPUS_GET_INBAND_FEC_REQUEST 4013
#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014
#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015
#define OPUS_SET_DTX_REQUEST 4016
#define OPUS_GET_DTX_REQUEST 4017
#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020
#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021
#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022
#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023
#define OPUS_SET_SIGNAL_REQUEST 4024
#define OPUS_GET_SIGNAL_REQUEST 4025
#define OPUS_GET_LOOKAHEAD_REQUEST 4027
/* #define OPUS_RESET_STATE 4028 */
#define OPUS_GET_SAMPLE_RATE_REQUEST 4029
#define OPUS_GET_FINAL_RANGE_REQUEST 4031
#define OPUS_GET_PITCH_REQUEST 4033
#define OPUS_SET_GAIN_REQUEST 4034
#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */
#define OPUS_SET_LSB_DEPTH_REQUEST 4036
#define OPUS_GET_LSB_DEPTH_REQUEST 4037
#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039
#define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040
#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041
#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042
#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043
/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
#define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046
#define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047
#define OPUS_GET_IN_DTX_REQUEST 4049
#define OPUS_SET_DRED_DURATION_REQUEST 4050
#define OPUS_GET_DRED_DURATION_REQUEST 4051
#define OPUS_SET_DNN_BLOB_REQUEST 4052
/*#define OPUS_GET_DNN_BLOB_REQUEST 4053 */
/** Defines for the presence of extended APIs. */
#define OPUS_HAVE_OPUS_PROJECTION_H
/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
#ifdef DISABLE_PTR_CHECK
/* Disable checks to prevent ubsan from complaining about NULL checks
in test_opus_api. */
#define __opus_check_int_ptr(ptr) (ptr)
#define __opus_check_uint_ptr(ptr) (ptr)
#define __opus_check_uint8_ptr(ptr) (ptr)
#define __opus_check_val16_ptr(ptr) (ptr)
#define __opus_check_void_ptr(ptr) (ptr)
#else
#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))
#define __opus_check_uint8_ptr(ptr) ((ptr) + ((ptr) - (opus_uint8*)(ptr)))
#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr)))
#define __opus_check_void_ptr(x) ((void)((void *)0 == (x)), (x))
#endif
/** @endcond */
/** @defgroup opus_ctlvalues Pre-defined values for CTL interface
* @see opus_genericctls, opus_encoderctls
* @{
*/
/* Values for the various encoder CTLs */
#define OPUS_AUTO -1000 /**<Auto/default setting @hideinitializer*/
#define OPUS_BITRATE_MAX -1 /**<Maximum bitrate @hideinitializer*/
/** Best for most VoIP/videoconference applications where listening quality and intelligibility matter most
* @hideinitializer */
#define OPUS_APPLICATION_VOIP 2048
/** Best for broadcast/high-fidelity application where the decoded audio should be as close as possible to the input
* @hideinitializer */
#define OPUS_APPLICATION_AUDIO 2049
/** Only use when lowest-achievable latency is what matters most. Voice-optimized modes cannot be used.
* @hideinitializer */
#define OPUS_APPLICATION_RESTRICTED_LOWDELAY 2051
#define OPUS_SIGNAL_VOICE 3001 /**< Signal being encoded is voice */
#define OPUS_SIGNAL_MUSIC 3002 /**< Signal being encoded is music */
#define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4 kHz bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6 kHz bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8 kHz bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_SUPERWIDEBAND 1104 /**<12 kHz bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_FULLBAND 1105 /**<20 kHz bandpass @hideinitializer*/
#define OPUS_FRAMESIZE_ARG 5000 /**< Select frame size from the argument (default) */
#define OPUS_FRAMESIZE_2_5_MS 5001 /**< Use 2.5 ms frames */
#define OPUS_FRAMESIZE_5_MS 5002 /**< Use 5 ms frames */
#define OPUS_FRAMESIZE_10_MS 5003 /**< Use 10 ms frames */
#define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */
#define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */
#define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */
#define OPUS_FRAMESIZE_80_MS 5007 /**< Use 80 ms frames */
#define OPUS_FRAMESIZE_100_MS 5008 /**< Use 100 ms frames */
#define OPUS_FRAMESIZE_120_MS 5009 /**< Use 120 ms frames */
/**@}*/
/** @defgroup opus_encoderctls Encoder related CTLs
*
* These are convenience macros for use with the \c opus_encode_ctl
* interface. They are used to generate the appropriate series of
* arguments for that call, passing the correct type, size and so
* on as expected for each particular request.
*
* Some usage examples:
*
* @code
* int ret;
* ret = opus_encoder_ctl(enc_ctx, OPUS_SET_BANDWIDTH(OPUS_AUTO));
* if (ret != OPUS_OK) return ret;
*
* opus_int32 rate;
* opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&rate));
*
* opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);
* @endcode
*
* @see opus_genericctls, opus_encoder
* @{
*/
/** Configures the encoder's computational complexity.
* The supported range is 0-10 inclusive with 10 representing the highest complexity.
* @see OPUS_GET_COMPLEXITY
* @param[in] x <tt>opus_int32</tt>: Allowed values: 0-10, inclusive.
*
* @hideinitializer */
#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x)
/** Gets the encoder's complexity configuration.
* @see OPUS_SET_COMPLEXITY
* @param[out] x <tt>opus_int32 *</tt>: Returns a value in the range 0-10,
* inclusive.
* @hideinitializer */
#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x)
/** Configures the bitrate in the encoder.
* Rates from 500 to 512000 bits per second are meaningful, as well as the
* special values #OPUS_AUTO and #OPUS_BITRATE_MAX.
* The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much
* rate as it can, which is useful for controlling the rate by adjusting the
* output buffer size.
* @see OPUS_GET_BITRATE
* @param[in] x <tt>opus_int32</tt>: Bitrate in bits per second. The default
* is determined based on the number of
* channels and the input sampling rate.
* @hideinitializer */
#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x)
/** Gets the encoder's bitrate configuration.
* @see OPUS_SET_BITRATE
* @param[out] x <tt>opus_int32 *</tt>: Returns the bitrate in bits per second.
* The default is determined based on the
* number of channels and the input
* sampling rate.
* @hideinitializer */
#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x)
/** Enables or disables variable bitrate (VBR) in the encoder.
* The configured bitrate may not be met exactly because frames must
* be an integer number of bytes in length.
* @see OPUS_GET_VBR
* @see OPUS_SET_VBR_CONSTRAINT
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Hard CBR. For LPC/hybrid modes at very low bit-rate, this can
* cause noticeable quality degradation.</dd>
* <dt>1</dt><dd>VBR (default). The exact type of VBR is controlled by
* #OPUS_SET_VBR_CONSTRAINT.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x)
/** Determine if variable bitrate (VBR) is enabled in the encoder.
* @see OPUS_SET_VBR
* @see OPUS_GET_VBR_CONSTRAINT
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Hard CBR.</dd>
* <dt>1</dt><dd>VBR (default). The exact type of VBR may be retrieved via
* #OPUS_GET_VBR_CONSTRAINT.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x)
/** Enables or disables constrained VBR in the encoder.
* This setting is ignored when the encoder is in CBR mode.
* @warning Only the MDCT mode of Opus currently heeds the constraint.
* Speech mode ignores it completely, hybrid mode may fail to obey it
* if the LPC layer uses more bitrate than the constraint would have
* permitted.
* @see OPUS_GET_VBR_CONSTRAINT
* @see OPUS_SET_VBR
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Unconstrained VBR.</dd>
* <dt>1</dt><dd>Constrained VBR (default). This creates a maximum of one
* frame of buffering delay assuming a transport with a
* serialization speed of the nominal bitrate.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x)
/** Determine if constrained VBR is enabled in the encoder.
* @see OPUS_SET_VBR_CONSTRAINT
* @see OPUS_GET_VBR
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Unconstrained VBR.</dd>
* <dt>1</dt><dd>Constrained VBR (default).</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x)
/** Configures mono/stereo forcing in the encoder.
* This can force the encoder to produce packets encoded as either mono or
* stereo, regardless of the format of the input audio. This is useful when
* the caller knows that the input signal is currently a mono source embedded
* in a stereo stream.
* @see OPUS_GET_FORCE_CHANNELS
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>
* <dt>1</dt> <dd>Forced mono</dd>
* <dt>2</dt> <dd>Forced stereo</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x)
/** Gets the encoder's forced channel configuration.
* @see OPUS_SET_FORCE_CHANNELS
* @param[out] x <tt>opus_int32 *</tt>:
* <dl>
* <dt>#OPUS_AUTO</dt><dd>Not forced (default)</dd>
* <dt>1</dt> <dd>Forced mono</dd>
* <dt>2</dt> <dd>Forced stereo</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x)
/** Configures the maximum bandpass that the encoder will select automatically.
* Applications should normally use this instead of #OPUS_SET_BANDWIDTH
* (leaving that set to the default, #OPUS_AUTO). This allows the
* application to set an upper bound based on the type of input it is
* providing, but still gives the encoder the freedom to reduce the bandpass
* when the bitrate becomes too low, for better overall quality.
* @see OPUS_GET_MAX_BANDWIDTH
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
* <dt>OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
* <dt>OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
* <dt>OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
* <dt>OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured maximum allowed bandpass.
* @see OPUS_SET_MAX_BANDWIDTH
* @param[out] x <tt>opus_int32 *</tt>: Allowed values:
* <dl>
* <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband (default)</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
/** Sets the encoder's bandpass to a specific value.
* This prevents the encoder from automatically selecting the bandpass based
* on the available bitrate. If an application knows the bandpass of the input
* audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH
* instead, which still gives the encoder the freedom to reduce the bandpass
* when the bitrate becomes too low, for better overall quality.
* @see OPUS_GET_BANDWIDTH
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
* <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x)
/** Configures the type of signal being encoded.
* This is a hint which helps the encoder's mode selection.
* @see OPUS_GET_SIGNAL
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
* <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>
* <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured signal type.
* @see OPUS_SET_SIGNAL
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
* <dt>#OPUS_SIGNAL_VOICE</dt><dd>Bias thresholds towards choosing LPC or Hybrid modes.</dd>
* <dt>#OPUS_SIGNAL_MUSIC</dt><dd>Bias thresholds towards choosing MDCT modes.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's intended application.
* The initial value is a mandatory argument to the encoder_create function.
* @see OPUS_GET_APPLICATION
* @param[in] x <tt>opus_int32</tt>: Returns one of the following values:
* <dl>
* <dt>#OPUS_APPLICATION_VOIP</dt>
* <dd>Process signal for improved speech intelligibility.</dd>
* <dt>#OPUS_APPLICATION_AUDIO</dt>
* <dd>Favor faithfulness to the original input.</dd>
* <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
* <dd>Configure the minimum possible coding delay by disabling certain modes
* of operation.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured application.
* @see OPUS_SET_APPLICATION
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>#OPUS_APPLICATION_VOIP</dt>
* <dd>Process signal for improved speech intelligibility.</dd>
* <dt>#OPUS_APPLICATION_AUDIO</dt>
* <dd>Favor faithfulness to the original input.</dd>
* <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
* <dd>Configure the minimum possible coding delay by disabling certain modes
* of operation.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x)
/** Gets the total samples of delay added by the entire codec.
* This can be queried by the encoder and then the provided number of samples can be
* skipped on from the start of the decoder's output to provide time aligned input
* and output. From the perspective of a decoding application the real data begins this many
* samples late.
*
* The decoder contribution to this delay is identical for all decoders, but the
* encoder portion of the delay may vary from implementation to implementation,
* version to version, or even depend on the encoder's initial configuration.
* Applications needing delay compensation should call this CTL rather than
* hard-coding a value.
* @param[out] x <tt>opus_int32 *</tt>: Number of lookahead samples
* @hideinitializer */
#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's use of inband forward error correction (FEC).
* @note This is only applicable to the LPC layer
* @see OPUS_GET_INBAND_FEC
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Disable inband FEC (default).</dd>
* <dt>1</dt><dd>Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.</dd>
* <dt>2</dt><dd>Inband FEC enabled, but does not necessarily switch to SILK if we have music.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x)
/** Gets encoder's configured use of inband forward error correction.
* @see OPUS_SET_INBAND_FEC
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Inband FEC disabled (default).</dd>
* <dt>1</dt><dd>Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.</dd>
* <dt>2</dt><dd>Inband FEC enabled, but does not necessarily switch to SILK if we have music.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's expected packet loss percentage.
* Higher values trigger progressively more loss resistant behavior in the encoder
* at the expense of quality at a given bitrate in the absence of packet loss, but
* greater quality under loss.
* @see OPUS_GET_PACKET_LOSS_PERC
* @param[in] x <tt>opus_int32</tt>: Loss percentage in the range 0-100, inclusive (default: 0).
* @hideinitializer */
#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured packet loss percentage.
* @see OPUS_SET_PACKET_LOSS_PERC
* @param[out] x <tt>opus_int32 *</tt>: Returns the configured loss percentage
* in the range 0-100, inclusive (default: 0).
* @hideinitializer */
#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's use of discontinuous transmission (DTX).
* @note This is only applicable to the LPC layer
* @see OPUS_GET_DTX
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Disable DTX (default).</dd>
* <dt>1</dt><dd>Enabled DTX.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x)
/** Gets encoder's configured use of discontinuous transmission.
* @see OPUS_SET_DTX
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>DTX disabled (default).</dd>
* <dt>1</dt><dd>DTX enabled.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x)
/** Configures the depth of signal being encoded.
*
* This is a hint which helps the encoder identify silence and near-silence.
* It represents the number of significant bits of linear intensity below
* which the signal contains ignorable quantization or other noise.
*
* For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting
* for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate
* for 16-bit linear pcm input with opus_encode_float().
*
* When using opus_encode() instead of opus_encode_float(), or when libopus
* is compiled for fixed-point, the encoder uses the minimum of the value
* set here and the value 16.
*
* @see OPUS_GET_LSB_DEPTH
* @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24
* (default: 24).
* @hideinitializer */
#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured signal depth.
* @see OPUS_SET_LSB_DEPTH
* @param[out] x <tt>opus_int32 *</tt>: Input precision in bits, between 8 and
* 24 (default: 24).
* @hideinitializer */
#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's use of variable duration frames.
* When variable duration is enabled, the encoder is free to use a shorter frame
* size than the one requested in the opus_encode*() call.
* It is then the user's responsibility
* to verify how much audio was encoded by checking the ToC byte of the encoded
* packet. The part of the audio that was not encoded needs to be resent to the
* encoder for the next call. Do not use this option unless you <b>really</b>
* know what you are doing.
* @see OPUS_GET_EXPERT_FRAME_DURATION
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
* <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_80_MS</dt><dd>Use 80 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_100_MS</dt><dd>Use 100 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_120_MS</dt><dd>Use 120 ms frames.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured use of variable duration frames.
* @see OPUS_SET_EXPERT_FRAME_DURATION
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
* <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_80_MS</dt><dd>Use 80 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_100_MS</dt><dd>Use 100 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_120_MS</dt><dd>Use 120 ms frames.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x)
/** If set to 1, disables almost all use of prediction, making frames almost
* completely independent. This reduces quality.
* @see OPUS_GET_PREDICTION_DISABLED
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Enable prediction (default).</dd>
* <dt>1</dt><dd>Disable prediction.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured prediction status.
* @see OPUS_SET_PREDICTION_DISABLED
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Prediction enabled (default).</dd>
* <dt>1</dt><dd>Prediction disabled.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x)
/** If non-zero, enables Deep Redundancy (DRED) and use the specified maximum number of 10-ms redundant frames
* @hideinitializer */
#define OPUS_SET_DRED_DURATION(x) OPUS_SET_DRED_DURATION_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured Deep Redundancy (DRED) maximum number of frames.
* @hideinitializer */
#define OPUS_GET_DRED_DURATION(x) OPUS_GET_DRED_DURATION_REQUEST, __opus_check_int_ptr(x)
/** Provide external DNN weights from binary object (only when explicitly built without the weights)
* @hideinitializer */
#define OPUS_SET_DNN_BLOB(data, len) OPUS_SET_DNN_BLOB_REQUEST, __opus_check_void_ptr(data), __opus_check_int(len)
/**@}*/
/** @defgroup opus_genericctls Generic CTLs
*
* These macros are used with the \c opus_decoder_ctl and
* \c opus_encoder_ctl calls to generate a particular
* request.
*
* When called on an \c OpusDecoder they apply to that
* particular decoder instance. When called on an
* \c OpusEncoder they apply to the corresponding setting
* on that encoder instance, if present.
*
* Some usage examples:
*
* @code
* int ret;
* opus_int32 pitch;
* ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch));
* if (ret == OPUS_OK) return ret;
*
* opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE);
* opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE);
*
* opus_int32 enc_bw, dec_bw;
* opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw));
* opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw));
* if (enc_bw != dec_bw) {
* printf("packet bandwidth mismatch!\n");
* }
* @endcode
*
* @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls
* @{
*/
/** Resets the codec state to be equivalent to a freshly initialized state.
* This should be called when switching streams in order to prevent
* the back to back decoding from giving different results from
* one at a time decoding.
* @hideinitializer */
#define OPUS_RESET_STATE 4028
/** Gets the final state of the codec's entropy coder.
* This is used for testing purposes,
* The encoder and decoder state should be identical after coding a payload
* (assuming no data corruption or software bugs)
*
* @param[out] x <tt>opus_uint32 *</tt>: Entropy coder state
*
* @hideinitializer */
#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x)
/** Gets the encoder's configured bandpass or the decoder's last bandpass.
* @see OPUS_SET_BANDWIDTH
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>#OPUS_AUTO</dt> <dd>(default)</dd>
* <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_MEDIUMBAND</dt> <dd>6 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_SUPERWIDEBAND</dt><dd>12 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_FULLBAND</dt> <dd>20 kHz passband</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
/** Gets the sampling rate the encoder or decoder was initialized with.
* This simply returns the <code>Fs</code> value passed to opus_encoder_init()
* or opus_decoder_init().
* @param[out] x <tt>opus_int32 *</tt>: Sampling rate of encoder or decoder.
* @hideinitializer
*/
#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x)
/** If set to 1, disables the use of phase inversion for intensity stereo,
* improving the quality of mono downmixes, but slightly reducing normal
* stereo quality. Disabling phase inversion in the decoder does not comply
* with RFC 6716, although it does not cause any interoperability issue and
* is expected to become part of the Opus standard once RFC 6716 is updated
* by draft-ietf-codec-opus-update.
* @see OPUS_GET_PHASE_INVERSION_DISABLED
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Enable phase inversion (default).</dd>
* <dt>1</dt><dd>Disable phase inversion.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_PHASE_INVERSION_DISABLED(x) OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int(x)
/** Gets the encoder's configured phase inversion status.
* @see OPUS_SET_PHASE_INVERSION_DISABLED
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Stereo phase inversion enabled (default).</dd>
* <dt>1</dt><dd>Stereo phase inversion disabled.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_PHASE_INVERSION_DISABLED(x) OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int_ptr(x)
/** Gets the DTX state of the encoder.
* Returns whether the last encoded frame was either a comfort noise update
* during DTX or not encoded because of DTX.
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>The encoder is not in DTX.</dd>
* <dt>1</dt><dd>The encoder is in DTX.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_IN_DTX(x) OPUS_GET_IN_DTX_REQUEST, __opus_check_int_ptr(x)
/**@}*/
/** @defgroup opus_decoderctls Decoder related CTLs
* @see opus_genericctls, opus_encoderctls, opus_decoder
* @{
*/
/** Configures decoder gain adjustment.
* Scales the decoded output by a factor specified in Q8 dB units.
* This has a maximum range of -32768 to 32767 inclusive, and returns
* OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment.
* This setting survives decoder reset.
*
* gain = pow(10, x/(20.0*256))
*
* @param[in] x <tt>opus_int32</tt>: Amount to scale PCM signal by in Q8 dB units.
* @hideinitializer */
#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x)
/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN
*
* @param[out] x <tt>opus_int32 *</tt>: Amount to scale PCM signal by in Q8 dB units.
* @hideinitializer */
#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x)
/** Gets the duration (in samples) of the last packet successfully decoded or concealed.
* @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate).
* @hideinitializer */
#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x)
/** Gets the pitch of the last decoded frame, if available.
* This can be used for any post-processing algorithm requiring the use of pitch,
* e.g. time stretching/shortening. If the last frame was not voiced, or if the
* pitch was not coded in the frame, then zero is returned.
*
* This CTL is only implemented for decoder instances.
*
* @param[out] x <tt>opus_int32 *</tt>: pitch period at 48 kHz (or 0 if not available)
*
* @hideinitializer */
#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x)
/**@}*/
/** @defgroup opus_libinfo Opus library information functions
* @{
*/
/** Converts an opus error code into a human readable string.
*
* @param[in] error <tt>int</tt>: Error number
* @returns Error string
*/
OPUS_EXPORT const char *opus_strerror(int error);
/** Gets the libopus version string.
*
* Applications may look for the substring "-fixed" in the version string to
* determine whether they have a fixed-point or floating-point build at
* runtime.
*
* @returns Version string
*/
OPUS_EXPORT const char *opus_get_version_string(void);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* OPUS_DEFINES_H */

View file

@ -0,0 +1,660 @@
/* Copyright (c) 2011 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file opus_multistream.h
* @brief Opus reference implementation multistream API
*/
#ifndef OPUS_MULTISTREAM_H
#define OPUS_MULTISTREAM_H
#include "opus.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @cond OPUS_INTERNAL_DOC */
/** Macros to trigger compilation errors when the wrong types are provided to a
* CTL. */
/**@{*/
#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr)))
#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr)))
/**@}*/
/** These are the actual encoder and decoder CTL ID numbers.
* They should not be used directly by applications.
* In general, SETs should be even and GETs should be odd.*/
/**@{*/
#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120
#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122
/**@}*/
/** @endcond */
/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs
*
* These are convenience macros that are specific to the
* opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl()
* interface.
* The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and
* @ref opus_decoderctls may be applied to a multistream encoder or decoder as
* well.
* In addition, you may retrieve the encoder or decoder state for an specific
* stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or
* #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually.
*/
/**@{*/
/** Gets the encoder state for an individual stream of a multistream encoder.
* @param[in] x <tt>opus_int32</tt>: The index of the stream whose encoder you
* wish to retrieve.
* This must be non-negative and less than
* the <code>streams</code> parameter used
* to initialize the encoder.
* @param[out] y <tt>OpusEncoder**</tt>: Returns a pointer to the given
* encoder state.
* @retval OPUS_BAD_ARG The index of the requested stream was out of range.
* @hideinitializer
*/
#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y)
/** Gets the decoder state for an individual stream of a multistream decoder.
* @param[in] x <tt>opus_int32</tt>: The index of the stream whose decoder you
* wish to retrieve.
* This must be non-negative and less than
* the <code>streams</code> parameter used
* to initialize the decoder.
* @param[out] y <tt>OpusDecoder**</tt>: Returns a pointer to the given
* decoder state.
* @retval OPUS_BAD_ARG The index of the requested stream was out of range.
* @hideinitializer
*/
#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y)
/**@}*/
/** @defgroup opus_multistream Opus Multistream API
* @{
*
* The multistream API allows individual Opus streams to be combined into a
* single packet, enabling support for up to 255 channels. Unlike an
* elementary Opus stream, the encoder and decoder must negotiate the channel
* configuration before the decoder can successfully interpret the data in the
* packets produced by the encoder. Some basic information, such as packet
* duration, can be computed without any special negotiation.
*
* The format for multistream Opus packets is defined in
* <a href="https://tools.ietf.org/html/rfc7845">RFC 7845</a>
* and is based on the self-delimited Opus framing described in Appendix B of
* <a href="https://tools.ietf.org/html/rfc6716">RFC 6716</a>.
* Normal Opus packets are just a degenerate case of multistream Opus packets,
* and can be encoded or decoded with the multistream API by setting
* <code>streams</code> to <code>1</code> when initializing the encoder or
* decoder.
*
* Multistream Opus streams can contain up to 255 elementary Opus streams.
* These may be either "uncoupled" or "coupled", indicating that the decoder
* is configured to decode them to either 1 or 2 channels, respectively.
* The streams are ordered so that all coupled streams appear at the
* beginning.
*
* A <code>mapping</code> table defines which decoded channel <code>i</code>
* should be used for each input/output (I/O) channel <code>j</code>. This table is
* typically provided as an unsigned char array.
* Let <code>i = mapping[j]</code> be the index for I/O channel <code>j</code>.
* If <code>i < 2*coupled_streams</code>, then I/O channel <code>j</code> is
* encoded as the left channel of stream <code>(i/2)</code> if <code>i</code>
* is even, or as the right channel of stream <code>(i/2)</code> if
* <code>i</code> is odd. Otherwise, I/O channel <code>j</code> is encoded as
* mono in stream <code>(i - coupled_streams)</code>, unless it has the special
* value 255, in which case it is omitted from the encoding entirely (the
* decoder will reproduce it as silence). Each value <code>i</code> must either
* be the special value 255 or be less than <code>streams + coupled_streams</code>.
*
* The output channels specified by the encoder
* should use the
* <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9">Vorbis
* channel ordering</a>. A decoder may wish to apply an additional permutation
* to the mapping the encoder used to achieve a different output channel
* order (e.g. for outputting in WAV order).
*
* Each multistream packet contains an Opus packet for each stream, and all of
* the Opus packets in a single multistream packet must have the same
* duration. Therefore the duration of a multistream packet can be extracted
* from the TOC sequence of the first stream, which is located at the
* beginning of the packet, just like an elementary Opus stream:
*
* @code
* int nb_samples;
* int nb_frames;
* nb_frames = opus_packet_get_nb_frames(data, len);
* if (nb_frames < 1)
* return nb_frames;
* nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames;
* @endcode
*
* The general encoding and decoding process proceeds exactly the same as in
* the normal @ref opus_encoder and @ref opus_decoder APIs.
* See their documentation for an overview of how to use the corresponding
* multistream functions.
*/
/** Opus multistream encoder state.
* This contains the complete state of a multistream Opus encoder.
* It is position independent and can be freely copied.
* @see opus_multistream_encoder_create
* @see opus_multistream_encoder_init
*/
typedef struct OpusMSEncoder OpusMSEncoder;
/** Opus multistream decoder state.
* This contains the complete state of a multistream Opus decoder.
* It is position independent and can be freely copied.
* @see opus_multistream_decoder_create
* @see opus_multistream_decoder_init
*/
typedef struct OpusMSDecoder OpusMSDecoder;
/**\name Multistream encoder functions */
/**@{*/
/** Gets the size of an OpusMSEncoder structure.
* @param streams <tt>int</tt>: The total number of streams to encode from the
* input.
* This must be no more than 255.
* @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
* to encode.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* encoded channels (<code>streams +
* coupled_streams</code>) must be no
* more than 255.
* @returns The size in bytes on success, or a negative error code
* (see @ref opus_errorcodes) on error.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size(
int streams,
int coupled_streams
);
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size(
int channels,
int mapping_family
);
/** Allocates and initializes a multistream encoder state.
* Call opus_multistream_encoder_destroy() to release
* this object when finished.
* @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param channels <tt>int</tt>: Number of channels in the input signal.
* This must be at most 255.
* It may be greater than the number of
* coded channels (<code>streams +
* coupled_streams</code>).
* @param streams <tt>int</tt>: The total number of streams to encode from the
* input.
* This must be no more than the number of channels.
* @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
* to encode.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* encoded channels (<code>streams +
* coupled_streams</code>) must be no
* more than the number of input channels.
* @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
* encoded channels to input channels, as described in
* @ref opus_multistream. As an extra constraint, the
* multistream encoder does not allow encoding coupled
* streams for which one channel is unused since this
* is never a good idea.
* @param application <tt>int</tt>: The target encoder application.
* This must be one of the following:
* <dl>
* <dt>#OPUS_APPLICATION_VOIP</dt>
* <dd>Process signal for improved speech intelligibility.</dd>
* <dt>#OPUS_APPLICATION_AUDIO</dt>
* <dd>Favor faithfulness to the original input.</dd>
* <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
* <dd>Configure the minimum possible coding delay by disabling certain modes
* of operation.</dd>
* </dl>
* @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
* code (see @ref opus_errorcodes) on
* failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create(
opus_int32 Fs,
int channels,
int streams,
int coupled_streams,
const unsigned char *mapping,
int application,
int *error
) OPUS_ARG_NONNULL(5);
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create(
opus_int32 Fs,
int channels,
int mapping_family,
int *streams,
int *coupled_streams,
unsigned char *mapping,
int application,
int *error
) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6);
/** Initialize a previously allocated multistream encoder state.
* The memory pointed to by \a st must be at least the size returned by
* opus_multistream_encoder_get_size().
* This is intended for applications which use their own allocator instead of
* malloc.
* To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
* @see opus_multistream_encoder_create
* @see opus_multistream_encoder_get_size
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
* @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param channels <tt>int</tt>: Number of channels in the input signal.
* This must be at most 255.
* It may be greater than the number of
* coded channels (<code>streams +
* coupled_streams</code>).
* @param streams <tt>int</tt>: The total number of streams to encode from the
* input.
* This must be no more than the number of channels.
* @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
* to encode.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* encoded channels (<code>streams +
* coupled_streams</code>) must be no
* more than the number of input channels.
* @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
* encoded channels to input channels, as described in
* @ref opus_multistream. As an extra constraint, the
* multistream encoder does not allow encoding coupled
* streams for which one channel is unused since this
* is never a good idea.
* @param application <tt>int</tt>: The target encoder application.
* This must be one of the following:
* <dl>
* <dt>#OPUS_APPLICATION_VOIP</dt>
* <dd>Process signal for improved speech intelligibility.</dd>
* <dt>#OPUS_APPLICATION_AUDIO</dt>
* <dd>Favor faithfulness to the original input.</dd>
* <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
* <dd>Configure the minimum possible coding delay by disabling certain modes
* of operation.</dd>
* </dl>
* @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
* on failure.
*/
OPUS_EXPORT int opus_multistream_encoder_init(
OpusMSEncoder *st,
opus_int32 Fs,
int channels,
int streams,
int coupled_streams,
const unsigned char *mapping,
int application
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
OPUS_EXPORT int opus_multistream_surround_encoder_init(
OpusMSEncoder *st,
opus_int32 Fs,
int channels,
int mapping_family,
int *streams,
int *coupled_streams,
unsigned char *mapping,
int application
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6) OPUS_ARG_NONNULL(7);
/** Encodes a multistream Opus frame.
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
* @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
* samples.
* This must contain
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: Number of samples per channel in the input
* signal.
* This must be an Opus frame size for the
* encoder's sampling rate.
* For example, at 48 kHz the permitted values
* are 120, 240, 480, 960, 1920, and 2880.
* Passing in a duration of less than 10 ms
* (480 samples at 48 kHz) will prevent the
* encoder from using the LPC or hybrid modes.
* @param[out] data <tt>unsigned char*</tt>: Output payload.
* This must contain storage for at
* least \a max_data_bytes.
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
* memory for the output
* payload. This may be
* used to impose an upper limit on
* the instant bitrate, but should
* not be used as the only bitrate
* control. Use #OPUS_SET_BITRATE to
* control the bitrate.
* @returns The length of the encoded packet (in bytes) on success or a
* negative error code (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode(
OpusMSEncoder *st,
const opus_int16 *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Encodes a multistream Opus frame from floating point input.
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
* @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
* samples with a normal range of
* +/-1.0.
* Samples with a range beyond +/-1.0
* are supported but will be clipped by
* decoders using the integer API and
* should only be used if it is known
* that the far end supports extended
* dynamic range.
* This must contain
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: Number of samples per channel in the input
* signal.
* This must be an Opus frame size for the
* encoder's sampling rate.
* For example, at 48 kHz the permitted values
* are 120, 240, 480, 960, 1920, and 2880.
* Passing in a duration of less than 10 ms
* (480 samples at 48 kHz) will prevent the
* encoder from using the LPC or hybrid modes.
* @param[out] data <tt>unsigned char*</tt>: Output payload.
* This must contain storage for at
* least \a max_data_bytes.
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
* memory for the output
* payload. This may be
* used to impose an upper limit on
* the instant bitrate, but should
* not be used as the only bitrate
* control. Use #OPUS_SET_BITRATE to
* control the bitrate.
* @returns The length of the encoded packet (in bytes) on success or a
* negative error code (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float(
OpusMSEncoder *st,
const float *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
/** Frees an <code>OpusMSEncoder</code> allocated by
* opus_multistream_encoder_create().
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to be freed.
*/
OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st);
/** Perform a CTL function on a multistream Opus encoder.
*
* Generally the request and subsequent arguments are generated by a
* convenience macro.
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
* @param request This and all remaining parameters should be replaced by one
* of the convenience macros in @ref opus_genericctls,
* @ref opus_encoderctls, or @ref opus_multistream_ctls.
* @see opus_genericctls
* @see opus_encoderctls
* @see opus_multistream_ctls
*/
OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
/**@}*/
/**\name Multistream decoder functions */
/**@{*/
/** Gets the size of an <code>OpusMSDecoder</code> structure.
* @param streams <tt>int</tt>: The total number of streams coded in the
* input.
* This must be no more than 255.
* @param coupled_streams <tt>int</tt>: Number streams to decode as coupled
* (2 channel) streams.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* coded channels (<code>streams +
* coupled_streams</code>) must be no
* more than 255.
* @returns The size in bytes on success, or a negative error code
* (see @ref opus_errorcodes) on error.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size(
int streams,
int coupled_streams
);
/** Allocates and initializes a multistream decoder state.
* Call opus_multistream_decoder_destroy() to release
* this object when finished.
* @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param channels <tt>int</tt>: Number of channels to output.
* This must be at most 255.
* It may be different from the number of coded
* channels (<code>streams +
* coupled_streams</code>).
* @param streams <tt>int</tt>: The total number of streams coded in the
* input.
* This must be no more than 255.
* @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
* (2 channel) streams.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* coded channels (<code>streams +
* coupled_streams</code>) must be no
* more than 255.
* @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
* coded channels to output channels, as described in
* @ref opus_multistream.
* @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
* code (see @ref opus_errorcodes) on
* failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create(
opus_int32 Fs,
int channels,
int streams,
int coupled_streams,
const unsigned char *mapping,
int *error
) OPUS_ARG_NONNULL(5);
/** Intialize a previously allocated decoder state object.
* The memory pointed to by \a st must be at least the size returned by
* opus_multistream_encoder_get_size().
* This is intended for applications which use their own allocator instead of
* malloc.
* To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
* @see opus_multistream_decoder_create
* @see opus_multistream_deocder_get_size
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
* @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
* This must be one of 8000, 12000, 16000,
* 24000, or 48000.
* @param channels <tt>int</tt>: Number of channels to output.
* This must be at most 255.
* It may be different from the number of coded
* channels (<code>streams +
* coupled_streams</code>).
* @param streams <tt>int</tt>: The total number of streams coded in the
* input.
* This must be no more than 255.
* @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
* (2 channel) streams.
* This must be no larger than the total
* number of streams.
* Additionally, The total number of
* coded channels (<code>streams +
* coupled_streams</code>) must be no
* more than 255.
* @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
* coded channels to output channels, as described in
* @ref opus_multistream.
* @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
* on failure.
*/
OPUS_EXPORT int opus_multistream_decoder_init(
OpusMSDecoder *st,
opus_int32 Fs,
int channels,
int streams,
int coupled_streams,
const unsigned char *mapping
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
/** Decode a multistream Opus packet.
* @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
* @param[in] data <tt>const unsigned char*</tt>: Input payload.
* Use a <code>NULL</code>
* pointer to indicate packet
* loss.
* @param len <tt>opus_int32</tt>: Number of bytes in payload.
* @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
* samples.
* This must contain room for
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: The number of samples per channel of
* available space in \a pcm.
* If this is less than the maximum packet duration
* (120 ms; 5760 for 48kHz), this function will not be capable
* of decoding some packets. In the case of PLC (data==NULL)
* or FEC (decode_fec=1), then frame_size needs to be exactly
* the duration of audio that is missing, otherwise the
* decoder will not be in the optimal state to decode the
* next incoming packet. For the PLC and FEC cases, frame_size
* <b>must</b> be a multiple of 2.5 ms.
* @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
* forward error correction data be decoded.
* If no such data is available, the frame is
* decoded as if it were lost.
* @returns Number of samples decoded on success or a negative error code
* (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(
OpusMSDecoder *st,
const unsigned char *data,
opus_int32 len,
opus_int16 *pcm,
int frame_size,
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Decode a multistream Opus packet with floating point output.
* @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
* @param[in] data <tt>const unsigned char*</tt>: Input payload.
* Use a <code>NULL</code>
* pointer to indicate packet
* loss.
* @param len <tt>opus_int32</tt>: Number of bytes in payload.
* @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
* samples.
* This must contain room for
* <code>frame_size*channels</code>
* samples.
* @param frame_size <tt>int</tt>: The number of samples per channel of
* available space in \a pcm.
* If this is less than the maximum packet duration
* (120 ms; 5760 for 48kHz), this function will not be capable
* of decoding some packets. In the case of PLC (data==NULL)
* or FEC (decode_fec=1), then frame_size needs to be exactly
* the duration of audio that is missing, otherwise the
* decoder will not be in the optimal state to decode the
* next incoming packet. For the PLC and FEC cases, frame_size
* <b>must</b> be a multiple of 2.5 ms.
* @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
* forward error correction data be decoded.
* If no such data is available, the frame is
* decoded as if it were lost.
* @returns Number of samples decoded on success or a negative error code
* (see @ref opus_errorcodes) on failure.
*/
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float(
OpusMSDecoder *st,
const unsigned char *data,
opus_int32 len,
float *pcm,
int frame_size,
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Perform a CTL function on a multistream Opus decoder.
*
* Generally the request and subsequent arguments are generated by a
* convenience macro.
* @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
* @param request This and all remaining parameters should be replaced by one
* of the convenience macros in @ref opus_genericctls,
* @ref opus_decoderctls, or @ref opus_multistream_ctls.
* @see opus_genericctls
* @see opus_decoderctls
* @see opus_multistream_ctls
*/
OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
/** Frees an <code>OpusMSDecoder</code> allocated by
* opus_multistream_decoder_create().
* @param st <tt>OpusMSDecoder</tt>: Multistream decoder state to be freed.
*/
OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st);
/**@}*/
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* OPUS_MULTISTREAM_H */

View file

@ -0,0 +1,166 @@
/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */
/* Modified by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* opus_types.h based on ogg_types.h from libogg */
/**
@file opus_types.h
@brief Opus reference implementation types
*/
#ifndef OPUS_TYPES_H
#define OPUS_TYPES_H
#define opus_int int /* used for counters etc; at least 16 bits */
#define opus_int64 long long
#define opus_int8 signed char
#define opus_uint unsigned int /* used for counters etc; at least 16 bits */
#define opus_uint64 unsigned long long
#define opus_uint8 unsigned char
/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */
#if (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
#include <stdint.h>
# undef opus_int64
# undef opus_int8
# undef opus_uint64
# undef opus_uint8
typedef int8_t opus_int8;
typedef uint8_t opus_uint8;
typedef int16_t opus_int16;
typedef uint16_t opus_uint16;
typedef int32_t opus_int32;
typedef uint32_t opus_uint32;
typedef int64_t opus_int64;
typedef uint64_t opus_uint64;
#elif defined(_WIN32)
# if defined(__CYGWIN__)
# include <_G_config.h>
typedef _G_int32_t opus_int32;
typedef _G_uint32_t opus_uint32;
typedef _G_int16 opus_int16;
typedef _G_uint16 opus_uint16;
# elif defined(__MINGW32__)
typedef short opus_int16;
typedef unsigned short opus_uint16;
typedef int opus_int32;
typedef unsigned int opus_uint32;
# elif defined(__MWERKS__)
typedef int opus_int32;
typedef unsigned int opus_uint32;
typedef short opus_int16;
typedef unsigned short opus_uint16;
# else
/* MSVC/Borland */
typedef __int32 opus_int32;
typedef unsigned __int32 opus_uint32;
typedef __int16 opus_int16;
typedef unsigned __int16 opus_uint16;
# endif
#elif defined(__MACOS__)
# include <sys/types.h>
typedef SInt16 opus_int16;
typedef UInt16 opus_uint16;
typedef SInt32 opus_int32;
typedef UInt32 opus_uint32;
#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
# include <sys/types.h>
typedef int16_t opus_int16;
typedef u_int16_t opus_uint16;
typedef int32_t opus_int32;
typedef u_int32_t opus_uint32;
#elif defined(__BEOS__)
/* Be */
# include <inttypes.h>
typedef int16 opus_int16;
typedef u_int16 opus_uint16;
typedef int32_t opus_int32;
typedef u_int32_t opus_uint32;
#elif defined (__EMX__)
/* OS/2 GCC */
typedef short opus_int16;
typedef unsigned short opus_uint16;
typedef int opus_int32;
typedef unsigned int opus_uint32;
#elif defined (DJGPP)
/* DJGPP */
typedef short opus_int16;
typedef unsigned short opus_uint16;
typedef int opus_int32;
typedef unsigned int opus_uint32;
#elif defined(R5900)
/* PS2 EE */
typedef int opus_int32;
typedef unsigned opus_uint32;
typedef short opus_int16;
typedef unsigned short opus_uint16;
#elif defined(__SYMBIAN32__)
/* Symbian GCC */
typedef signed short opus_int16;
typedef unsigned short opus_uint16;
typedef signed int opus_int32;
typedef unsigned int opus_uint32;
#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
typedef short opus_int16;
typedef unsigned short opus_uint16;
typedef long opus_int32;
typedef unsigned long opus_uint32;
#elif defined(CONFIG_TI_C6X)
typedef short opus_int16;
typedef unsigned short opus_uint16;
typedef int opus_int32;
typedef unsigned int opus_uint32;
#else
/* Give up, take a reasonable guess */
typedef short opus_int16;
typedef unsigned short opus_uint16;
typedef int opus_int32;
typedef unsigned int opus_uint32;
#endif
#endif /* OPUS_TYPES_H */

View file

@ -0,0 +1,182 @@
/*Copyright (c) 2003-2004, Mark Borgerding
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.*/
#ifndef KISS_FFT_GUTS_H
#define KISS_FFT_GUTS_H
#define MIN(a,b) ((a)<(b) ? (a):(b))
#define MAX(a,b) ((a)>(b) ? (a):(b))
/* kiss_fft.h
defines kiss_fft_scalar as either short or a float type
and defines
typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
#include "kiss_fft.h"
/*
Explanation of macros dealing with complex math:
C_MUL(m,a,b) : m = a*b
C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
C_SUB( res, a,b) : res = a - b
C_SUBFROM( res , a) : res -= a
C_ADDTO( res , a) : res += a
* */
#ifdef FIXED_POINT
#include "arch.h"
#define SAMP_MAX 2147483647
#define TWID_MAX 32767
#define TRIG_UPSCALE 1
#define SAMP_MIN -SAMP_MAX
# define S_MUL(a,b) MULT16_32_Q15(b, a)
# define C_MUL(m,a,b) \
do{ (m).r = SUB32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
(m).i = ADD32_ovflw(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)
# define C_MULC(m,a,b) \
do{ (m).r = ADD32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
(m).i = SUB32_ovflw(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)
# define C_MULBYSCALAR( c, s ) \
do{ (c).r = S_MUL( (c).r , s ) ;\
(c).i = S_MUL( (c).i , s ) ; }while(0)
# define DIVSCALAR(x,k) \
(x) = S_MUL( x, (TWID_MAX-((k)>>1))/(k)+1 )
# define C_FIXDIV(c,div) \
do { DIVSCALAR( (c).r , div); \
DIVSCALAR( (c).i , div); }while (0)
#define C_ADD( res, a,b)\
do {(res).r=ADD32_ovflw((a).r,(b).r); (res).i=ADD32_ovflw((a).i,(b).i); \
}while(0)
#define C_SUB( res, a,b)\
do {(res).r=SUB32_ovflw((a).r,(b).r); (res).i=SUB32_ovflw((a).i,(b).i); \
}while(0)
#define C_ADDTO( res , a)\
do {(res).r = ADD32_ovflw((res).r, (a).r); (res).i = ADD32_ovflw((res).i,(a).i);\
}while(0)
#define C_SUBFROM( res , a)\
do {(res).r = ADD32_ovflw((res).r,(a).r); (res).i = SUB32_ovflw((res).i,(a).i); \
}while(0)
#if defined(OPUS_ARM_INLINE_ASM)
#include "arm/kiss_fft_armv4.h"
#endif
#if defined(OPUS_ARM_INLINE_EDSP)
#include "arm/kiss_fft_armv5e.h"
#endif
#if defined(MIPSr1_ASM)
#include "mips/kiss_fft_mipsr1.h"
#endif
#else /* not FIXED_POINT*/
# define S_MUL(a,b) ( (a)*(b) )
#define C_MUL(m,a,b) \
do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
(m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
#define C_MULC(m,a,b) \
do{ (m).r = (a).r*(b).r + (a).i*(b).i;\
(m).i = (a).i*(b).r - (a).r*(b).i; }while(0)
#define C_MUL4(m,a,b) C_MUL(m,a,b)
# define C_FIXDIV(c,div) /* NOOP */
# define C_MULBYSCALAR( c, s ) \
do{ (c).r *= (s);\
(c).i *= (s); }while(0)
#endif
#ifndef CHECK_OVERFLOW_OP
# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
#endif
#ifndef C_ADD
#define C_ADD( res, a,b)\
do { \
CHECK_OVERFLOW_OP((a).r,+,(b).r)\
CHECK_OVERFLOW_OP((a).i,+,(b).i)\
(res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
}while(0)
#define C_SUB( res, a,b)\
do { \
CHECK_OVERFLOW_OP((a).r,-,(b).r)\
CHECK_OVERFLOW_OP((a).i,-,(b).i)\
(res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
}while(0)
#define C_ADDTO( res , a)\
do { \
CHECK_OVERFLOW_OP((res).r,+,(a).r)\
CHECK_OVERFLOW_OP((res).i,+,(a).i)\
(res).r += (a).r; (res).i += (a).i;\
}while(0)
#define C_SUBFROM( res , a)\
do {\
CHECK_OVERFLOW_OP((res).r,-,(a).r)\
CHECK_OVERFLOW_OP((res).i,-,(a).i)\
(res).r -= (a).r; (res).i -= (a).i; \
}while(0)
#endif /* C_ADD defined */
#ifdef FIXED_POINT
/*# define KISS_FFT_COS(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase))))
# define KISS_FFT_SIN(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))*/
# define KISS_FFT_COS(phase) floor(.5+TWID_MAX*cos (phase))
# define KISS_FFT_SIN(phase) floor(.5+TWID_MAX*sin (phase))
# define HALF_OF(x) ((x)>>1)
#elif defined(USE_SIMD)
# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
# define HALF_OF(x) ((x)*_mm_set1_ps(.5f))
#else
# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
# define HALF_OF(x) ((x)*.5f)
#endif
#define kf_cexp(x,phase) \
do{ \
(x)->r = KISS_FFT_COS(phase);\
(x)->i = KISS_FFT_SIN(phase);\
}while(0)
#define kf_cexp2(x,phase) \
do{ \
(x)->r = TRIG_UPSCALE*celt_cos_norm((phase));\
(x)->i = TRIG_UPSCALE*celt_cos_norm((phase)-32768);\
}while(0)
#endif /* KISS_FFT_GUTS_H */

View file

@ -0,0 +1,291 @@
/* Copyright (c) 2003-2008 Jean-Marc Valin
Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Written by Jean-Marc Valin */
/**
@file arch.h
@brief Various architecture definitions for CELT
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARCH_H
#define ARCH_H
#include "opus_types.h"
#include "opus_defines.h"
# if !defined(__GNUC_PREREQ)
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
# define __GNUC_PREREQ(_maj,_min) \
((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
# else
# define __GNUC_PREREQ(_maj,_min) 0
# endif
# endif
#if OPUS_GNUC_PREREQ(3, 0)
#define opus_likely(x) (__builtin_expect(!!(x), 1))
#define opus_unlikely(x) (__builtin_expect(!!(x), 0))
#else
#define opus_likely(x) (!!(x))
#define opus_unlikely(x) (!!(x))
#endif
#define CELT_SIG_SCALE 32768.f
#define CELT_FATAL(str) celt_fatal(str, __FILE__, __LINE__);
#if defined(ENABLE_ASSERTIONS) || defined(ENABLE_HARDENING)
#ifdef __GNUC__
__attribute__((noreturn))
#endif
void celt_fatal(const char *str, const char *file, int line);
#if defined(CELT_C) && !defined(OVERRIDE_celt_fatal)
#include <stdio.h>
#include <stdlib.h>
#ifdef __GNUC__
__attribute__((noreturn))
#endif
void celt_fatal(const char *str, const char *file, int line)
{
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
#if defined(_MSC_VER)
_set_abort_behavior( 0, _WRITE_ABORT_MSG);
#endif
abort();
}
#endif
#define celt_assert(cond) {if (!(cond)) {CELT_FATAL("assertion failed: " #cond);}}
#define celt_assert2(cond, message) {if (!(cond)) {CELT_FATAL("assertion failed: " #cond "\n" message);}}
#define MUST_SUCCEED(call) celt_assert((call) == OPUS_OK)
#else
#define celt_assert(cond)
#define celt_assert2(cond, message)
#define MUST_SUCCEED(call) do {if((call) != OPUS_OK) {RESTORE_STACK; return OPUS_INTERNAL_ERROR;} } while (0)
#endif
#if defined(ENABLE_ASSERTIONS)
#define celt_sig_assert(cond) {if (!(cond)) {CELT_FATAL("signal assertion failed: " #cond);}}
#else
#define celt_sig_assert(cond)
#endif
#define IMUL32(a,b) ((a)*(b))
#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 16-bit value. */
#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 32-bit value. */
#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
#define IMIN(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum int value. */
#define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */
#define UADD32(a,b) ((a)+(b))
#define USUB32(a,b) ((a)-(b))
/* Set this if opus_int64 is a native type of the CPU. */
/* Assume that all LP64 architectures have fast 64-bit types; also x86_64
(which can be ILP32 for x32) and Win64 (which is LLP64). */
#if defined(__x86_64__) || defined(__LP64__) || defined(_WIN64)
#define OPUS_FAST_INT64 1
#else
#define OPUS_FAST_INT64 0
#endif
#define PRINT_MIPS(file)
#ifdef FIXED_POINT
typedef opus_int16 opus_val16;
typedef opus_int32 opus_val32;
typedef opus_int64 opus_val64;
typedef opus_val32 celt_sig;
typedef opus_val16 celt_norm;
typedef opus_val32 celt_ener;
#define celt_isnan(x) 0
#define Q15ONE 32767
#define SIG_SHIFT 12
/* Safe saturation value for 32-bit signals. Should be less than
2^31*(1-0.85) to avoid blowing up on DC at deemphasis.*/
#define SIG_SAT (300000000)
#define NORM_SCALING 16384
#define DB_SHIFT 10
#define EPSILON 1
#define VERY_SMALL 0
#define VERY_LARGE16 ((opus_val16)32767)
#define Q15_ONE ((opus_val16)32767)
#define SCALEIN(a) (a)
#define SCALEOUT(a) (a)
#define ABS16(x) ((x) < 0 ? (-(x)) : (x))
#define ABS32(x) ((x) < 0 ? (-(x)) : (x))
static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x;
}
#ifdef FIXED_DEBUG
#include "fixed_debug.h"
#else
#include "fixed_generic.h"
#ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR
#include "arm/fixed_arm64.h"
#elif defined (OPUS_ARM_INLINE_EDSP)
#include "arm/fixed_armv5e.h"
#elif defined (OPUS_ARM_INLINE_ASM)
#include "arm/fixed_armv4.h"
#elif defined (BFIN_ASM)
#include "fixed_bfin.h"
#elif defined (TI_C5X_ASM)
#include "fixed_c5x.h"
#elif defined (TI_C6X_ASM)
#include "fixed_c6x.h"
#endif
#endif
#else /* FIXED_POINT */
typedef float opus_val16;
typedef float opus_val32;
typedef float opus_val64;
typedef float celt_sig;
typedef float celt_norm;
typedef float celt_ener;
#ifdef FLOAT_APPROX
/* This code should reliably detect NaN/inf even when -ffast-math is used.
Assumes IEEE 754 format. */
static OPUS_INLINE int celt_isnan(float x)
{
union {float f; opus_uint32 i;} in;
in.f = x;
return ((in.i>>23)&0xFF)==0xFF && (in.i&0x007FFFFF)!=0;
}
#else
#ifdef __FAST_MATH__
#error Cannot build libopus with -ffast-math unless FLOAT_APPROX is defined. This could result in crashes on extreme (e.g. NaN) input
#endif
#define celt_isnan(x) ((x)!=(x))
#endif
#define Q15ONE 1.0f
#define NORM_SCALING 1.f
#define EPSILON 1e-15f
#define VERY_SMALL 1e-30f
#define VERY_LARGE16 1e15f
#define Q15_ONE ((opus_val16)1.f)
/* This appears to be the same speed as C99's fabsf() but it's more portable. */
#define ABS16(x) ((float)fabs(x))
#define ABS32(x) ((float)fabs(x))
#define QCONST16(x,bits) (x)
#define QCONST32(x,bits) (x)
#define NEG16(x) (-(x))
#define NEG32(x) (-(x))
#define NEG32_ovflw(x) (-(x))
#define EXTRACT16(x) (x)
#define EXTEND32(x) (x)
#define SHR16(a,shift) (a)
#define SHL16(a,shift) (a)
#define SHR32(a,shift) (a)
#define SHL32(a,shift) (a)
#define PSHR32(a,shift) (a)
#define VSHR32(a,shift) (a)
#define PSHR(a,shift) (a)
#define SHR(a,shift) (a)
#define SHL(a,shift) (a)
#define SATURATE(x,a) (x)
#define SATURATE16(x) (x)
#define ROUND16(a,shift) (a)
#define SROUND16(a,shift) (a)
#define HALF16(x) (.5f*(x))
#define HALF32(x) (.5f*(x))
#define ADD16(a,b) ((a)+(b))
#define SUB16(a,b) ((a)-(b))
#define ADD32(a,b) ((a)+(b))
#define SUB32(a,b) ((a)-(b))
#define ADD32_ovflw(a,b) ((a)+(b))
#define SUB32_ovflw(a,b) ((a)-(b))
#define MULT16_16_16(a,b) ((a)*(b))
#define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b))
#define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b))
#define MULT16_32_Q15(a,b) ((a)*(b))
#define MULT16_32_Q16(a,b) ((a)*(b))
#define MULT32_32_Q31(a,b) ((a)*(b))
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
#define MAC16_32_Q16(c,a,b) ((c)+(a)*(b))
#define MULT16_16_Q11_32(a,b) ((a)*(b))
#define MULT16_16_Q11(a,b) ((a)*(b))
#define MULT16_16_Q13(a,b) ((a)*(b))
#define MULT16_16_Q14(a,b) ((a)*(b))
#define MULT16_16_Q15(a,b) ((a)*(b))
#define MULT16_16_P15(a,b) ((a)*(b))
#define MULT16_16_P13(a,b) ((a)*(b))
#define MULT16_16_P14(a,b) ((a)*(b))
#define MULT16_32_P16(a,b) ((a)*(b))
#define DIV32_16(a,b) (((opus_val32)(a))/(opus_val16)(b))
#define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b))
#define SCALEIN(a) ((a)*CELT_SIG_SCALE)
#define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE))
#define SIG2WORD16(x) (x)
#endif /* !FIXED_POINT */
#ifndef GLOBAL_STACK_SIZE
#ifdef FIXED_POINT
#define GLOBAL_STACK_SIZE 120000
#else
#define GLOBAL_STACK_SIZE 120000
#endif
#endif
#endif /* ARCH_H */

View file

@ -0,0 +1,353 @@
#!/usr/bin/perl
# Copyright (C) 2002-2013 Xiph.org Foundation
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
my $bigend; # little/big endian
my $nxstack;
my $apple = 0;
my $symprefix = "";
$nxstack = 0;
eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
if $running_under_some_shell;
while ($ARGV[0] =~ /^-/) {
$_ = shift;
last if /^--$/;
if (/^-n$/) {
$nflag++;
next;
}
if (/^--apple$/) {
$apple = 1;
$symprefix = "_";
next;
}
die "I don't recognize this switch: $_\\n";
}
$printit++ unless $nflag;
$\ = "\n"; # automatically add newline on print
$n=0;
$thumb = 0; # ARM mode by default, not Thumb.
@proc_stack = ();
printf (" .syntax unified\n");
LINE:
while (<>) {
# For ADRLs we need to add a new line after the substituted one.
$addPadding = 0;
# First, we do not dare to touch *anything* inside double quotes, do we?
# Second, if you want a dollar character in the string,
# insert two of them -- that's how ARM C and assembler treat strings.
s/^([A-Za-z_]\w*)[ \t]+DCB[ \t]*\"/$1: .ascii \"/ && do { s/\$\$/\$/g; next };
s/\bDCB\b[ \t]*\"/.ascii \"/ && do { s/\$\$/\$/g; next };
s/^(\S+)\s+RN\s+(\S+)/$1 .req r$2/ && do { s/\$\$/\$/g; next };
# If there's nothing on a line but a comment, don't try to apply any further
# substitutions (this is a cheap hack to avoid mucking up the license header)
s/^([ \t]*);/$1@/ && do { s/\$\$/\$/g; next };
# If substituted -- leave immediately !
s/@/,:/;
s/;/@/;
while ( /@.*'/ ) {
s/(@.*)'/$1/g;
}
s/\{FALSE\}/0/g;
s/\{TRUE\}/1/g;
s/\{(\w\w\w\w+)\}/$1/g;
s/\bINCLUDE[ \t]*([^ \t\n]+)/.include \"$1\"/;
s/\bGET[ \t]*([^ \t\n]+)/.include \"${ my $x=$1; $x =~ s|\.s|-gnu.S|; \$x }\"/;
s/\bIMPORT\b/.extern/;
s/\bEXPORT\b\s*/.global $symprefix/;
s/^(\s+)\[/$1IF/;
s/^(\s+)\|/$1ELSE/;
s/^(\s+)\]/$1ENDIF/;
s/IF *:DEF:/ .ifdef/;
s/IF *:LNOT: *:DEF:/ .ifndef/;
s/ELSE/ .else/;
s/ENDIF/ .endif/;
if( /\bIF\b/ ) {
s/\bIF\b/ .if/;
s/=/==/;
}
if ( $n == 2) {
s/\$/\\/g;
}
if ($n == 1) {
s/\$//g;
s/label//g;
$n = 2;
}
if ( /MACRO/ ) {
s/MACRO *\n/.macro/;
$n=1;
}
if ( /\bMEND\b/ ) {
s/\bMEND\b/.endm/;
$n=0;
}
# ".rdata" doesn't work in 'as' version 2.13.2, as it is ".rodata" there.
#
if ( /\bAREA\b/ ) {
my $align;
$align = "2";
if ( /ALIGN=(\d+)/ ) {
$align = $1;
}
if ( /CODE/ ) {
$nxstack = 1;
}
s/^(.+)CODE(.+)READONLY(.*)/ .text/;
s/^(.+)DATA(.+)READONLY(.*)/ .section .rdata/;
s/^(.+)\|\|\.data\|\|(.+)/ .data/;
s/^(.+)\|\|\.bss\|\|(.+)/ .bss/;
s/$/; .p2align $align/;
# Enable NEON instructions but don't produce a binary that requires
# ARMv7. RVCT does not have equivalent directives, so we just do this
# for all CODE areas.
if ( /.text/ ) {
# Separating .arch, .fpu, etc., by semicolons does not work (gas
# thinks the semicolon is part of the arch name, even when there's
# whitespace separating them). Sadly this means our line numbers
# won't match the original source file (we could use the .line
# directive, which is documented to be obsolete, but then gdb will
# show the wrong line in the translated source file).
s/$/; .arch armv7-a\n .fpu neon\n .object_arch armv4t/ unless ($apple);
}
}
s/\|\|\.constdata\$(\d+)\|\|/.L_CONST$1/; # ||.constdata$3||
s/\|\|\.bss\$(\d+)\|\|/.L_BSS$1/; # ||.bss$2||
s/\|\|\.data\$(\d+)\|\|/.L_DATA$1/; # ||.data$2||
s/\|\|([a-zA-Z0-9_]+)\@([a-zA-Z0-9_]+)\|\|/@ $&/;
s/^(\s+)\%(\s)/ .space $1/;
s/\|(.+)\.(\d+)\|/\.$1_$2/; # |L80.123| -> .L80_123
s/\bCODE32\b/.code 32/ && do {$thumb = 0};
s/\bCODE16\b/.code 16/ && do {$thumb = 1};
if (/\bPROC\b/)
{
my $prefix;
my $proc;
/^([A-Za-z_\.]\w+)\b/;
$proc = $1;
$prefix = "";
if ($proc)
{
$prefix = $prefix.sprintf("\t.type\t%s, %%function", $proc) unless ($apple);
# Make sure we $prefix isn't empty here (for the $apple case).
# We handle mangling the label here, make sure it doesn't match
# the label handling below (if $prefix would be empty).
$prefix = $prefix."; ";
push(@proc_stack, $proc);
s/^[A-Za-z_\.]\w+/$symprefix$&:/;
}
$prefix = $prefix."\t.thumb_func; " if ($thumb);
s/\bPROC\b/@ $&/;
$_ = $prefix.$_;
}
s/^(\s*)(S|Q|SH|U|UQ|UH)ASX\b/$1$2ADDSUBX/;
s/^(\s*)(S|Q|SH|U|UQ|UH)SAX\b/$1$2SUBADDX/;
if (/\bENDP\b/)
{
my $proc;
s/\bENDP\b/@ $&/;
$proc = pop(@proc_stack);
$_ = "\t.size $proc, .-$proc".$_ if ($proc && !$apple);
}
s/\bSUBT\b/@ $&/;
s/\bDATA\b/@ $&/; # DATA directive is deprecated -- Asm guide, p.7-25
s/\bKEEP\b/@ $&/;
s/\bEXPORTAS\b/@ $&/;
s/\|\|(.)+\bEQU\b/@ $&/;
s/\|\|([\w\$]+)\|\|/$1/;
s/\bENTRY\b/@ $&/;
s/\bASSERT\b/@ $&/;
s/\bGBLL\b/@ $&/;
s/\bGBLA\b/@ $&/;
s/^\W+OPT\b/@ $&/;
s/:OR:/|/g;
s/:SHL:/<</g;
s/:SHR:/>>/g;
s/:AND:/&/g;
s/:LAND:/&&/g;
s/CPSR/cpsr/;
s/SPSR/spsr/;
s/ALIGN$/.balign 4/;
s/ALIGN\s+([0-9x]+)$/.balign $1/;
s/psr_cxsf/psr_all/;
s/LTORG/.ltorg/;
s/^([A-Za-z_]\w*)[ \t]+EQU/ .set $1,/;
s/^([A-Za-z_]\w*)[ \t]+SETL/ .set $1,/;
s/^([A-Za-z_]\w*)[ \t]+SETA/ .set $1,/;
s/^([A-Za-z_]\w*)[ \t]+\*/ .set $1,/;
# {PC} + 0xdeadfeed --> . + 0xdeadfeed
s/\{PC\} \+/ \. +/;
# Single hex constant on the line !
#
# >>> NOTE <<<
# Double-precision floats in gcc are always mixed-endian, which means
# bytes in two words are little-endian, but words are big-endian.
# So, 0x0000deadfeed0000 would be stored as 0x0000dead at low address
# and 0xfeed0000 at high address.
#
s/\bDCFD\b[ \t]+0x([a-fA-F0-9]{8})([a-fA-F0-9]{8})/.long 0x$1, 0x$2/;
# Only decimal constants on the line, no hex !
s/\bDCFD\b[ \t]+([0-9\.\-]+)/.double $1/;
# Single hex constant on the line !
# s/\bDCFS\b[ \t]+0x([a-f0-9]{8})([a-f0-9]{8})/.long 0x$1, 0x$2/;
# Only decimal constants on the line, no hex !
# s/\bDCFS\b[ \t]+([0-9\.\-]+)/.double $1/;
s/\bDCFS[ \t]+0x/.word 0x/;
s/\bDCFS\b/.float/;
s/^([A-Za-z_]\w*)[ \t]+DCD/$1 .word/;
s/\bDCD\b/.word/;
s/^([A-Za-z_]\w*)[ \t]+DCW/$1 .short/;
s/\bDCW\b/.short/;
s/^([A-Za-z_]\w*)[ \t]+DCB/$1 .byte/;
s/\bDCB\b/.byte/;
s/^([A-Za-z_]\w*)[ \t]+\%/.comm $1,/;
s/^[A-Za-z_\.]\w+/$&:/;
s/^(\d+)/$1:/;
s/\%(\d+)/$1b_or_f/;
s/\%[Bb](\d+)/$1b/;
s/\%[Ff](\d+)/$1f/;
s/\%[Ff][Tt](\d+)/$1f/;
s/&([\dA-Fa-f]+)/0x$1/;
if ( /\b2_[01]+\b/ ) {
s/\b2_([01]+)\b/conv$1&&&&/g;
while ( /[01][01][01][01]&&&&/ ) {
s/0000&&&&/&&&&0/g;
s/0001&&&&/&&&&1/g;
s/0010&&&&/&&&&2/g;
s/0011&&&&/&&&&3/g;
s/0100&&&&/&&&&4/g;
s/0101&&&&/&&&&5/g;
s/0110&&&&/&&&&6/g;
s/0111&&&&/&&&&7/g;
s/1000&&&&/&&&&8/g;
s/1001&&&&/&&&&9/g;
s/1010&&&&/&&&&A/g;
s/1011&&&&/&&&&B/g;
s/1100&&&&/&&&&C/g;
s/1101&&&&/&&&&D/g;
s/1110&&&&/&&&&E/g;
s/1111&&&&/&&&&F/g;
}
s/000&&&&/&&&&0/g;
s/001&&&&/&&&&1/g;
s/010&&&&/&&&&2/g;
s/011&&&&/&&&&3/g;
s/100&&&&/&&&&4/g;
s/101&&&&/&&&&5/g;
s/110&&&&/&&&&6/g;
s/111&&&&/&&&&7/g;
s/00&&&&/&&&&0/g;
s/01&&&&/&&&&1/g;
s/10&&&&/&&&&2/g;
s/11&&&&/&&&&3/g;
s/0&&&&/&&&&0/g;
s/1&&&&/&&&&1/g;
s/conv&&&&/0x/g;
}
if ( /commandline/)
{
if( /-bigend/)
{
$bigend=1;
}
}
if ( /\bDCDU\b/ )
{
my $cmd=$_;
my $value;
my $prefix;
my $w1;
my $w2;
my $w3;
my $w4;
s/\s+DCDU\b/@ $&/;
$cmd =~ /\bDCDU\b\s+0x(\d+)/;
$value = $1;
$value =~ /(\w\w)(\w\w)(\w\w)(\w\w)/;
$w1 = $1;
$w2 = $2;
$w3 = $3;
$w4 = $4;
if( $bigend ne "")
{
# big endian
$prefix = "\t.byte\t0x".$w1.";".
"\t.byte\t0x".$w2.";".
"\t.byte\t0x".$w3.";".
"\t.byte\t0x".$w4."; ";
}
else
{
# little endian
$prefix = "\t.byte\t0x".$w4.";".
"\t.byte\t0x".$w3.";".
"\t.byte\t0x".$w2.";".
"\t.byte\t0x".$w1."; ";
}
$_=$prefix.$_;
}
if ( /\badrl\b/i )
{
s/\badrl\s+(\w+)\s*,\s*(\w+)/ldr $1,=$2/i;
$addPadding = 1;
}
s/\bEND\b/@ END/;
} continue {
printf ("%s", $_) if $printit;
if ($addPadding != 0)
{
printf (" mov r0,r0\n");
$addPadding = 0;
}
}
#If we had a code section, mark that this object doesn't need an executable
# stack.
if ($nxstack && !$apple) {
printf (" .section\t.note.GNU-stack,\"\",\%\%progbits\n");
}

View file

@ -0,0 +1,171 @@
/* Copyright (c) 2010 Xiph.Org Foundation
* Copyright (c) 2013 Parrot */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pitch.h"
#include "kiss_fft.h"
#include "mdct.h"
#if defined(OPUS_HAVE_RTCD)
# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y, int N) = {
celt_inner_prod_c, /* ARMv4 */
celt_inner_prod_c, /* EDSP */
celt_inner_prod_c, /* Media */
celt_inner_prod_neon,/* NEON */
celt_inner_prod_neon /* DOTPROD */
};
void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
int N, opus_val32 *xy1, opus_val32 *xy2) = {
dual_inner_prod_c, /* ARMv4 */
dual_inner_prod_c, /* EDSP */
dual_inner_prod_c, /* Media */
dual_inner_prod_neon,/* NEON */
dual_inner_prod_neon /* DOTPROD */
};
# endif
# if defined(FIXED_POINT)
# if ((defined(OPUS_ARM_MAY_HAVE_NEON) && !defined(OPUS_ARM_PRESUME_NEON)) || \
(defined(OPUS_ARM_MAY_HAVE_MEDIA) && !defined(OPUS_ARM_PRESUME_MEDIA)) || \
(defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP)))
opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
const opus_val16 *, opus_val32 *, int, int, int) = {
celt_pitch_xcorr_c, /* ARMv4 */
MAY_HAVE_EDSP(celt_pitch_xcorr), /* EDSP */
MAY_HAVE_MEDIA(celt_pitch_xcorr), /* Media */
MAY_HAVE_NEON(celt_pitch_xcorr), /* NEON */
MAY_HAVE_NEON(celt_pitch_xcorr) /* DOTPROD */
};
# endif
# else /* !FIXED_POINT */
# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
void (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
const opus_val16 *, opus_val32 *, int, int, int) = {
celt_pitch_xcorr_c, /* ARMv4 */
celt_pitch_xcorr_c, /* EDSP */
celt_pitch_xcorr_c, /* Media */
celt_pitch_xcorr_float_neon, /* Neon */
celt_pitch_xcorr_float_neon /* DOTPROD */
};
# endif
# endif /* FIXED_POINT */
#if defined(FIXED_POINT) && defined(OPUS_HAVE_RTCD) && \
defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
const opus_val16 *x,
const opus_val16 *y,
opus_val32 sum[4],
int len
) = {
xcorr_kernel_c, /* ARMv4 */
xcorr_kernel_c, /* EDSP */
xcorr_kernel_c, /* Media */
xcorr_kernel_neon_fixed, /* Neon */
xcorr_kernel_neon_fixed /* DOTPROD */
};
#endif
# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
# if defined(HAVE_ARM_NE10)
# if defined(CUSTOM_MODES)
int (*const OPUS_FFT_ALLOC_ARCH_IMPL[OPUS_ARCHMASK+1])(kiss_fft_state *st) = {
opus_fft_alloc_arch_c, /* ARMv4 */
opus_fft_alloc_arch_c, /* EDSP */
opus_fft_alloc_arch_c, /* Media */
opus_fft_alloc_arm_neon, /* Neon with NE10 library support */
opus_fft_alloc_arm_neon /* DOTPROD with NE10 library support */
};
void (*const OPUS_FFT_FREE_ARCH_IMPL[OPUS_ARCHMASK+1])(kiss_fft_state *st) = {
opus_fft_free_arch_c, /* ARMv4 */
opus_fft_free_arch_c, /* EDSP */
opus_fft_free_arch_c, /* Media */
opus_fft_free_arm_neon, /* Neon with NE10 */
opus_fft_free_arm_neon /* DOTPROD with NE10 */
};
# endif /* CUSTOM_MODES */
void (*const OPUS_FFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
const kiss_fft_cpx *fin,
kiss_fft_cpx *fout) = {
opus_fft_c, /* ARMv4 */
opus_fft_c, /* EDSP */
opus_fft_c, /* Media */
opus_fft_neon, /* Neon with NE10 */
opus_fft_neon /* DOTPROD with NE10 */
};
void (*const OPUS_IFFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
const kiss_fft_cpx *fin,
kiss_fft_cpx *fout) = {
opus_ifft_c, /* ARMv4 */
opus_ifft_c, /* EDSP */
opus_ifft_c, /* Media */
opus_ifft_neon, /* Neon with NE10 */
opus_ifft_neon /* DOTPROD with NE10 */
};
void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(const mdct_lookup *l,
kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 *window,
int overlap, int shift,
int stride, int arch) = {
clt_mdct_forward_c, /* ARMv4 */
clt_mdct_forward_c, /* EDSP */
clt_mdct_forward_c, /* Media */
clt_mdct_forward_neon, /* Neon with NE10 */
clt_mdct_forward_neon /* DOTPROD with NE10 */
};
void (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])(const mdct_lookup *l,
kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 *window,
int overlap, int shift,
int stride, int arch) = {
clt_mdct_backward_c, /* ARMv4 */
clt_mdct_backward_c, /* EDSP */
clt_mdct_backward_c, /* Media */
clt_mdct_backward_neon, /* Neon with NE10 */
clt_mdct_backward_neon /* DOTPROD with NE10 */
};
# endif /* HAVE_ARM_NE10 */
# endif /* OPUS_ARM_MAY_HAVE_NEON_INTR */
#endif /* OPUS_HAVE_RTCD */

View file

@ -0,0 +1,291 @@
/* Copyright (c) 2010 Xiph.Org Foundation
* Copyright (c) 2013 Parrot */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Original code from libtheora modified to suit to Opus */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef OPUS_HAVE_RTCD
#include "armcpu.h"
#include "cpu_support.h"
#include "os_support.h"
#include "opus_types.h"
#include "arch.h"
#define OPUS_CPU_ARM_V4_FLAG (1<<OPUS_ARCH_ARM_V4)
#define OPUS_CPU_ARM_EDSP_FLAG (1<<OPUS_ARCH_ARM_EDSP)
#define OPUS_CPU_ARM_MEDIA_FLAG (1<<OPUS_ARCH_ARM_MEDIA)
#define OPUS_CPU_ARM_NEON_FLAG (1<<OPUS_ARCH_ARM_NEON)
#define OPUS_CPU_ARM_DOTPROD_FLAG (1<<OPUS_ARCH_ARM_DOTPROD)
#if defined(_MSC_VER)
/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/
# define WIN32_LEAN_AND_MEAN
# define WIN32_EXTRA_LEAN
# include <windows.h>
static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){
opus_uint32 flags;
flags=0;
/* MSVC has no OPUS_INLINE __asm support for ARM, but it does let you __emit
* instructions via their assembled hex code.
* All of these instructions should be essentially nops. */
# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_MEDIA) \
|| defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
__try{
/*PLD [r13]*/
__emit(0xF5DDF000);
flags|=OPUS_CPU_ARM_EDSP_FLAG;
}
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
/*Ignore exception.*/
}
# if defined(OPUS_ARM_MAY_HAVE_MEDIA) \
|| defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
__try{
/*SHADD8 r3,r3,r3*/
__emit(0xE6333F93);
flags|=OPUS_CPU_ARM_MEDIA_FLAG;
}
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
/*Ignore exception.*/
}
# if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
__try{
/*VORR q0,q0,q0*/
__emit(0xF2200150);
flags|=OPUS_CPU_ARM_NEON_FLAG;
}
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
/*Ignore exception.*/
}
# endif
# endif
# endif
return flags;
}
#elif defined(__linux__)
/* Linux based */
#include <stdio.h>
static opus_uint32 opus_cpu_capabilities(void)
{
opus_uint32 flags = 0;
FILE *cpuinfo;
/* Reading /proc/self/auxv would be easier, but that doesn't work reliably on
* Android */
cpuinfo = fopen("/proc/cpuinfo", "r");
if(cpuinfo != NULL)
{
/* 512 should be enough for anybody (it's even enough for all the flags that
* x86 has accumulated... so far). */
char buf[512];
while(fgets(buf, 512, cpuinfo) != NULL)
{
# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_MEDIA) \
|| defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
/* Search for edsp and neon flag */
if(memcmp(buf, "Features", 8) == 0)
{
char *p;
p = strstr(buf, " edsp");
if(p != NULL && (p[5] == ' ' || p[5] == '\n'))
flags |= OPUS_CPU_ARM_EDSP_FLAG;
# if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
p = strstr(buf, " neon");
if(p != NULL && (p[5] == ' ' || p[5] == '\n'))
flags |= OPUS_CPU_ARM_NEON_FLAG;
p = strstr(buf, " asimd");
if(p != NULL && (p[6] == ' ' || p[6] == '\n'))
flags |= OPUS_CPU_ARM_NEON_FLAG | OPUS_CPU_ARM_MEDIA_FLAG | OPUS_CPU_ARM_EDSP_FLAG;
# endif
# if defined(OPUS_ARM_MAY_HAVE_DOTPROD)
p = strstr(buf, " asimddp");
if(p != NULL && (p[8] == ' ' || p[8] == '\n'))
flags |= OPUS_CPU_ARM_DOTPROD_FLAG;
# endif
}
# endif
# if defined(OPUS_ARM_MAY_HAVE_MEDIA) \
|| defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
/* Search for media capabilities (>= ARMv6) */
if(memcmp(buf, "CPU architecture:", 17) == 0)
{
int version;
version = atoi(buf+17);
if(version >= 6)
flags |= OPUS_CPU_ARM_MEDIA_FLAG;
}
# endif
}
#if defined(OPUS_ARM_PRESUME_AARCH64_NEON_INTR)
flags |= OPUS_CPU_ARM_EDSP_FLAG | OPUS_CPU_ARM_MEDIA_FLAG | OPUS_CPU_ARM_NEON_FLAG;
# if defined(OPUS_ARM_PRESUME_DOTPROD)
flags |= OPUS_CPU_ARM_DOTPROD_FLAG;
# endif
#endif
fclose(cpuinfo);
}
return flags;
}
#elif defined(__APPLE__)
#include <sys/types.h>
#include <sys/sysctl.h>
static opus_uint32 opus_cpu_capabilities(void)
{
opus_uint32 flags = 0;
#if defined(OPUS_ARM_MAY_HAVE_DOTPROD)
size_t size = sizeof(uint32_t);
uint32_t value = 0;
if (!sysctlbyname("hw.optional.arm.FEAT_DotProd", &value, &size, NULL, 0) && value)
{
flags |= OPUS_CPU_ARM_DOTPROD_FLAG;
}
#endif
#if defined(OPUS_ARM_PRESUME_AARCH64_NEON_INTR)
flags |= OPUS_CPU_ARM_EDSP_FLAG | OPUS_CPU_ARM_MEDIA_FLAG | OPUS_CPU_ARM_NEON_FLAG;
# if defined(OPUS_ARM_PRESUME_DOTPROD)
flags |= OPUS_CPU_ARM_DOTPROD_FLAG;
# endif
#endif
return flags;
}
#elif defined(__FreeBSD__)
#include <sys/auxv.h>
static opus_uint32 opus_cpu_capabilities(void)
{
long hwcap = 0;
opus_uint32 flags = 0;
# if defined(OPUS_ARM_MAY_HAVE_MEDIA) \
|| defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
/* FreeBSD requires armv6+, which always supports media instructions */
flags |= OPUS_CPU_ARM_MEDIA_FLAG;
# endif
elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap);
# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_MEDIA) \
|| defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
# ifdef HWCAP_EDSP
if (hwcap & HWCAP_EDSP)
flags |= OPUS_CPU_ARM_EDSP_FLAG;
# endif
# if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
# ifdef HWCAP_NEON
if (hwcap & HWCAP_NEON)
flags |= OPUS_CPU_ARM_NEON_FLAG;
# elif defined(HWCAP_ASIMD)
if (hwcap & HWCAP_ASIMD)
flags |= OPUS_CPU_ARM_NEON_FLAG | OPUS_CPU_ARM_MEDIA_FLAG | OPUS_CPU_ARM_EDSP_FLAG;
# endif
# endif
# if defined(OPUS_ARM_MAY_HAVE_DOTPROD) && defined(HWCAP_ASIMDDP)
if (hwcap & HWCAP_ASIMDDP)
flags |= OPUS_CPU_ARM_DOTPROD_FLAG;
# endif
# endif
#if defined(OPUS_ARM_PRESUME_AARCH64_NEON_INTR)
flags |= OPUS_CPU_ARM_EDSP_FLAG | OPUS_CPU_ARM_MEDIA_FLAG | OPUS_CPU_ARM_NEON_FLAG;
# if defined(OPUS_ARM_PRESUME_DOTPROD)
flags |= OPUS_CPU_ARM_DOTPROD_FLAG;
# endif
#endif
return (flags);
}
#else
/* The feature registers which can tell us what the processor supports are
* accessible in priveleged modes only, so we can't have a general user-space
* detection method like on x86.*/
# error "Configured to use ARM asm but no CPU detection method available for " \
"your platform. Reconfigure with --disable-rtcd (or send patches)."
#endif
static int opus_select_arch_impl(void)
{
opus_uint32 flags = opus_cpu_capabilities();
int arch = 0;
if(!(flags & OPUS_CPU_ARM_EDSP_FLAG)) {
/* Asserts ensure arch values are sequential */
celt_assert(arch == OPUS_ARCH_ARM_V4);
return arch;
}
arch++;
if(!(flags & OPUS_CPU_ARM_MEDIA_FLAG)) {
celt_assert(arch == OPUS_ARCH_ARM_EDSP);
return arch;
}
arch++;
if(!(flags & OPUS_CPU_ARM_NEON_FLAG)) {
celt_assert(arch == OPUS_ARCH_ARM_MEDIA);
return arch;
}
arch++;
if(!(flags & OPUS_CPU_ARM_DOTPROD_FLAG)) {
celt_assert(arch == OPUS_ARCH_ARM_NEON);
return arch;
}
arch++;
celt_assert(arch == OPUS_ARCH_ARM_DOTPROD);
return arch;
}
int opus_select_arch(void) {
int arch = opus_select_arch_impl();
#ifdef FUZZING
arch = rand()%(arch+1);
#endif
return arch;
}
#endif

View file

@ -0,0 +1,90 @@
/* Copyright (c) 2010 Xiph.Org Foundation
* Copyright (c) 2013 Parrot */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(ARMCPU_H)
# define ARMCPU_H
# if defined(OPUS_ARM_MAY_HAVE_EDSP)
# define MAY_HAVE_EDSP(name) name ## _edsp
# else
# define MAY_HAVE_EDSP(name) name ## _c
# endif
# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
# define MAY_HAVE_MEDIA(name) name ## _media
# else
# define MAY_HAVE_MEDIA(name) MAY_HAVE_EDSP(name)
# endif
# if defined(OPUS_ARM_MAY_HAVE_NEON)
# define MAY_HAVE_NEON(name) name ## _neon
# else
# define MAY_HAVE_NEON(name) MAY_HAVE_MEDIA(name)
# endif
# if defined(OPUS_ARM_MAY_HAVE_DOTPROD)
# define MAY_HAVE_DOTPROD(name) name ## _dotprod
# else
# define MAY_HAVE_DOTPROD(name) MAY_HAVE_NEON(name)
# endif
# if defined(OPUS_ARM_PRESUME_EDSP)
# define PRESUME_EDSP(name) name ## _edsp
# else
# define PRESUME_EDSP(name) name ## _c
# endif
# if defined(OPUS_ARM_PRESUME_MEDIA)
# define PRESUME_MEDIA(name) name ## _media
# else
# define PRESUME_MEDIA(name) PRESUME_EDSP(name)
# endif
# if defined(OPUS_ARM_PRESUME_NEON)
# define PRESUME_NEON(name) name ## _neon
# else
# define PRESUME_NEON(name) PRESUME_MEDIA(name)
# endif
# if defined(OPUS_ARM_PRESUME_DOTPROD)
# define PRESUME_DOTPROD(name) name ## _dotprod
# else
# define PRESUME_DOTPROD(name) PRESUME_NEON(name)
# endif
# if defined(OPUS_HAVE_RTCD)
int opus_select_arch(void);
#define OPUS_ARCH_ARM_V4 (0)
#define OPUS_ARCH_ARM_EDSP (1)
#define OPUS_ARCH_ARM_MEDIA (2)
#define OPUS_ARCH_ARM_NEON (3)
#define OPUS_ARCH_ARM_DOTPROD (4)
# endif
#endif

View file

@ -0,0 +1,37 @@
/* Copyright (C) 2013 Mozilla Corporation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
; Set the following to 1 if we have EDSP instructions
; (LDRD/STRD, etc., ARMv5E and later).
OPUS_ARM_MAY_HAVE_EDSP * @OPUS_ARM_MAY_HAVE_EDSP@
; Set the following to 1 if we have ARMv6 media instructions.
OPUS_ARM_MAY_HAVE_MEDIA * @OPUS_ARM_MAY_HAVE_MEDIA@
; Set the following to 1 if we have NEON (some ARMv7)
OPUS_ARM_MAY_HAVE_NEON * @OPUS_ARM_MAY_HAVE_NEON@
END

View file

@ -0,0 +1,173 @@
/* Copyright (c) 2015 Xiph.Org Foundation
Written by Viswanath Puttagunta */
/**
@file celt_fft_ne10.c
@brief ARM Neon optimizations for fft using NE10 library
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SKIP_CONFIG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif
#include <NE10_dsp.h>
#include "os_support.h"
#include "kiss_fft.h"
#include "stack_alloc.h"
#if !defined(FIXED_POINT)
# define NE10_FFT_ALLOC_C2C_TYPE_NEON ne10_fft_alloc_c2c_float32_neon
# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_float32_t
# define NE10_FFT_STATE_TYPE_T ne10_fft_state_float32_t
# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_float32
# define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_float32_t
# define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_float32_neon
#else
# define NE10_FFT_ALLOC_C2C_TYPE_NEON(nfft) ne10_fft_alloc_c2c_int32_neon(nfft)
# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_int32_t
# define NE10_FFT_STATE_TYPE_T ne10_fft_state_int32_t
# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32
# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32
# define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_int32_t
# define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_int32_neon
#endif
#if defined(CUSTOM_MODES)
/* nfft lengths in NE10 that support scaled fft */
# define NE10_FFTSCALED_SUPPORT_MAX 4
static const int ne10_fft_scaled_support[NE10_FFTSCALED_SUPPORT_MAX] = {
480, 240, 120, 60
};
int opus_fft_alloc_arm_neon(kiss_fft_state *st)
{
int i;
size_t memneeded = sizeof(struct arch_fft_state);
st->arch_fft = (arch_fft_state *)opus_alloc(memneeded);
if (!st->arch_fft)
return -1;
for (i = 0; i < NE10_FFTSCALED_SUPPORT_MAX; i++) {
if(st->nfft == ne10_fft_scaled_support[i])
break;
}
if (i == NE10_FFTSCALED_SUPPORT_MAX) {
/* This nfft length (scaled fft) is not supported in NE10 */
st->arch_fft->is_supported = 0;
st->arch_fft->priv = NULL;
}
else {
st->arch_fft->is_supported = 1;
st->arch_fft->priv = (void *)NE10_FFT_ALLOC_C2C_TYPE_NEON(st->nfft);
if (st->arch_fft->priv == NULL) {
return -1;
}
}
return 0;
}
void opus_fft_free_arm_neon(kiss_fft_state *st)
{
NE10_FFT_CFG_TYPE_T cfg;
if (!st->arch_fft)
return;
cfg = (NE10_FFT_CFG_TYPE_T)st->arch_fft->priv;
if (cfg)
NE10_FFT_DESTROY_C2C_TYPE(cfg);
opus_free(st->arch_fft);
}
#endif
void opus_fft_neon(const kiss_fft_state *st,
const kiss_fft_cpx *fin,
kiss_fft_cpx *fout)
{
NE10_FFT_STATE_TYPE_T state;
NE10_FFT_CFG_TYPE_T cfg = &state;
VARDECL(NE10_FFT_CPX_TYPE_T, buffer);
SAVE_STACK;
ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);
if (!st->arch_fft->is_supported) {
/* This nfft length (scaled fft) not supported in NE10 */
opus_fft_c(st, fin, fout);
}
else {
memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));
state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];
#if !defined(FIXED_POINT)
state.is_forward_scaled = 1;
NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
(NE10_FFT_CPX_TYPE_T *)fin,
cfg, 0);
#else
NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
(NE10_FFT_CPX_TYPE_T *)fin,
cfg, 0, 1);
#endif
}
RESTORE_STACK;
}
void opus_ifft_neon(const kiss_fft_state *st,
const kiss_fft_cpx *fin,
kiss_fft_cpx *fout)
{
NE10_FFT_STATE_TYPE_T state;
NE10_FFT_CFG_TYPE_T cfg = &state;
VARDECL(NE10_FFT_CPX_TYPE_T, buffer);
SAVE_STACK;
ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);
if (!st->arch_fft->is_supported) {
/* This nfft length (scaled fft) not supported in NE10 */
opus_ifft_c(st, fin, fout);
}
else {
memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));
state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];
#if !defined(FIXED_POINT)
state.is_backward_scaled = 0;
NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
(NE10_FFT_CPX_TYPE_T *)fin,
cfg, 1);
#else
NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
(NE10_FFT_CPX_TYPE_T *)fin,
cfg, 1, 0);
#endif
}
RESTORE_STACK;
}

View file

@ -0,0 +1,258 @@
/* Copyright (c) 2015 Xiph.Org Foundation
Written by Viswanath Puttagunta */
/**
@file celt_mdct_ne10.c
@brief ARM Neon optimizations for mdct using NE10 library
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SKIP_CONFIG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif
#include "kiss_fft.h"
#include "_kiss_fft_guts.h"
#include "mdct.h"
#include "stack_alloc.h"
void clt_mdct_forward_neon(const mdct_lookup *l,
kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 *window,
int overlap, int shift, int stride, int arch)
{
int i;
int N, N2, N4;
VARDECL(kiss_fft_scalar, f);
VARDECL(kiss_fft_cpx, f2);
const kiss_fft_state *st = l->kfft[shift];
const kiss_twiddle_scalar *trig;
SAVE_STACK;
N = l->n;
trig = l->trig;
for (i=0;i<shift;i++)
{
N >>= 1;
trig += N;
}
N2 = N>>1;
N4 = N>>2;
ALLOC(f, N2, kiss_fft_scalar);
ALLOC(f2, N4, kiss_fft_cpx);
/* Consider the input to be composed of four blocks: [a, b, c, d] */
/* Window, shuffle, fold */
{
/* Temp pointers to make it really clear to the compiler what we're doing */
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
kiss_fft_scalar * OPUS_RESTRICT yp = f;
const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
for(i=0;i<((overlap+3)>>2);i++)
{
/* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
*yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);
*yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]);
xp1+=2;
xp2-=2;
wp1+=2;
wp2-=2;
}
wp1 = window;
wp2 = window+overlap-1;
for(;i<N4-((overlap+3)>>2);i++)
{
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
*yp++ = *xp2;
*yp++ = *xp1;
xp1+=2;
xp2-=2;
}
for(;i<N4;i++)
{
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
*yp++ = -MULT16_32_Q15(*wp1, xp1[-N2]) + MULT16_32_Q15(*wp2, *xp2);
*yp++ = MULT16_32_Q15(*wp2, *xp1) + MULT16_32_Q15(*wp1, xp2[N2]);
xp1+=2;
xp2-=2;
wp1+=2;
wp2-=2;
}
}
/* Pre-rotation */
{
kiss_fft_scalar * OPUS_RESTRICT yp = f;
const kiss_twiddle_scalar *t = &trig[0];
for(i=0;i<N4;i++)
{
kiss_fft_cpx yc;
kiss_twiddle_scalar t0, t1;
kiss_fft_scalar re, im, yr, yi;
t0 = t[i];
t1 = t[N4+i];
re = *yp++;
im = *yp++;
yr = S_MUL(re,t0) - S_MUL(im,t1);
yi = S_MUL(im,t0) + S_MUL(re,t1);
yc.r = yr;
yc.i = yi;
f2[i] = yc;
}
}
opus_fft(st, f2, (kiss_fft_cpx *)f, arch);
/* Post-rotate */
{
/* Temp pointers to make it really clear to the compiler what we're doing */
const kiss_fft_cpx * OPUS_RESTRICT fp = (kiss_fft_cpx *)f;
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
const kiss_twiddle_scalar *t = &trig[0];
/* Temp pointers to make it really clear to the compiler what we're doing */
for(i=0;i<N4;i++)
{
kiss_fft_scalar yr, yi;
yr = S_MUL(fp->i,t[N4+i]) - S_MUL(fp->r,t[i]);
yi = S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]);
*yp1 = yr;
*yp2 = yi;
fp++;
yp1 += 2*stride;
yp2 -= 2*stride;
}
}
RESTORE_STACK;
}
void clt_mdct_backward_neon(const mdct_lookup *l,
kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 * OPUS_RESTRICT window,
int overlap, int shift, int stride, int arch)
{
int i;
int N, N2, N4;
VARDECL(kiss_fft_scalar, f);
const kiss_twiddle_scalar *trig;
const kiss_fft_state *st = l->kfft[shift];
N = l->n;
trig = l->trig;
for (i=0;i<shift;i++)
{
N >>= 1;
trig += N;
}
N2 = N>>1;
N4 = N>>2;
ALLOC(f, N2, kiss_fft_scalar);
/* Pre-rotate */
{
/* Temp pointers to make it really clear to the compiler what we're doing */
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
kiss_fft_scalar * OPUS_RESTRICT yp = f;
const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];
for(i=0;i<N4;i++)
{
kiss_fft_scalar yr, yi;
yr = S_MUL(*xp2, t[i]) + S_MUL(*xp1, t[N4+i]);
yi = S_MUL(*xp1, t[i]) - S_MUL(*xp2, t[N4+i]);
yp[2*i] = yr;
yp[2*i+1] = yi;
xp1+=2*stride;
xp2-=2*stride;
}
}
opus_ifft(st, (kiss_fft_cpx *)f, (kiss_fft_cpx*)(out+(overlap>>1)), arch);
/* Post-rotate and de-shuffle from both ends of the buffer at once to make
it in-place. */
{
kiss_fft_scalar * yp0 = out+(overlap>>1);
kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2;
const kiss_twiddle_scalar *t = &trig[0];
/* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
middle pair will be computed twice. */
for(i=0;i<(N4+1)>>1;i++)
{
kiss_fft_scalar re, im, yr, yi;
kiss_twiddle_scalar t0, t1;
re = yp0[0];
im = yp0[1];
t0 = t[i];
t1 = t[N4+i];
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
yr = S_MUL(re,t0) + S_MUL(im,t1);
yi = S_MUL(re,t1) - S_MUL(im,t0);
re = yp1[0];
im = yp1[1];
yp0[0] = yr;
yp1[1] = yi;
t0 = t[(N4-i-1)];
t1 = t[(N2-i-1)];
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
yr = S_MUL(re,t0) + S_MUL(im,t1);
yi = S_MUL(re,t1) - S_MUL(im,t0);
yp1[0] = yr;
yp0[1] = yi;
yp0 += 2;
yp1 -= 2;
}
}
/* Mirror on both sides for TDAC */
{
kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
const opus_val16 * OPUS_RESTRICT wp1 = window;
const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
for(i = 0; i < overlap/2; i++)
{
kiss_fft_scalar x1, x2;
x1 = *xp1;
x2 = *yp1;
*yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);
*xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);
wp1++;
wp2--;
}
}
RESTORE_STACK;
}

View file

@ -0,0 +1,272 @@
/* Copyright (c) 2014-2015 Xiph.Org Foundation
Written by Viswanath Puttagunta */
/**
@file celt_neon_intr.c
@brief ARM Neon Intrinsic optimizations for celt
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <arm_neon.h>
#include "../pitch.h"
#if defined(FIXED_POINT)
#include <string.h>
void xcorr_kernel_neon_fixed(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)
{
int j;
int32x4_t a = vld1q_s32(sum);
/* Load y[0...3] */
/* This requires len>0 to always be valid (which we assert in the C code). */
int16x4_t y0 = vld1_s16(y);
y += 4;
/* This loop loads one y value more than we actually need.
Therefore we have to stop as soon as there are 8 or fewer samples left
(instead of 7), to avoid reading past the end of the array. */
for (j = 0; j + 8 < len; j += 8)
{
/* Load x[0...7] */
int16x8_t xx = vld1q_s16(x);
int16x4_t x0 = vget_low_s16(xx);
int16x4_t x4 = vget_high_s16(xx);
/* Load y[4...11] */
int16x8_t yy = vld1q_s16(y);
int16x4_t y4 = vget_low_s16(yy);
int16x4_t y8 = vget_high_s16(yy);
int32x4_t a0 = vmlal_lane_s16(a, y0, x0, 0);
int32x4_t a1 = vmlal_lane_s16(a0, y4, x4, 0);
int16x4_t y1 = vext_s16(y0, y4, 1);
int16x4_t y5 = vext_s16(y4, y8, 1);
int32x4_t a2 = vmlal_lane_s16(a1, y1, x0, 1);
int32x4_t a3 = vmlal_lane_s16(a2, y5, x4, 1);
int16x4_t y2 = vext_s16(y0, y4, 2);
int16x4_t y6 = vext_s16(y4, y8, 2);
int32x4_t a4 = vmlal_lane_s16(a3, y2, x0, 2);
int32x4_t a5 = vmlal_lane_s16(a4, y6, x4, 2);
int16x4_t y3 = vext_s16(y0, y4, 3);
int16x4_t y7 = vext_s16(y4, y8, 3);
int32x4_t a6 = vmlal_lane_s16(a5, y3, x0, 3);
int32x4_t a7 = vmlal_lane_s16(a6, y7, x4, 3);
y0 = y8;
a = a7;
x += 8;
y += 8;
}
if (j + 4 < len) {
/* Load x[0...3] */
int16x4_t x0 = vld1_s16(x);
/* Load y[4...7] */
int16x4_t y4 = vld1_s16(y);
int32x4_t a0 = vmlal_lane_s16(a, y0, x0, 0);
int16x4_t y1 = vext_s16(y0, y4, 1);
int32x4_t a1 = vmlal_lane_s16(a0, y1, x0, 1);
int16x4_t y2 = vext_s16(y0, y4, 2);
int32x4_t a2 = vmlal_lane_s16(a1, y2, x0, 2);
int16x4_t y3 = vext_s16(y0, y4, 3);
int32x4_t a3 = vmlal_lane_s16(a2, y3, x0, 3);
y0 = y4;
a = a3;
x += 4;
y += 4;
j += 4;
}
if (j + 2 < len) {
/* Load x[0...1] */
int16x4x2_t xx = vld2_dup_s16(x);
int16x4_t x0 = xx.val[0];
int16x4_t x1 = xx.val[1];
/* Load y[4...5].
We would like to use vld1_dup_s32(), but casting the pointer would
break strict aliasing rules and potentially have alignment issues.
Fortunately the compiler seems capable of translating this memcpy()
and vdup_n_s32() into the equivalent vld1_dup_s32().*/
int32_t yy;
memcpy(&yy, y, sizeof(yy));
int16x4_t y4 = vreinterpret_s16_s32(vdup_n_s32(yy));
int32x4_t a0 = vmlal_s16(a, y0, x0);
int16x4_t y1 = vext_s16(y0, y4, 1);
/* Replace bottom copy of {y[5], y[4]} in y4 with {y[3], y[2]} from y0,
using VSRI instead of VEXT, since it's a data-processing
instruction. */
y0 = vreinterpret_s16_s64(vsri_n_s64(vreinterpret_s64_s16(y4),
vreinterpret_s64_s16(y0), 32));
int32x4_t a1 = vmlal_s16(a0, y1, x1);
a = a1;
x += 2;
y += 2;
j += 2;
}
if (j + 1 < len) {
/* Load next x. */
int16x4_t x0 = vld1_dup_s16(x);
int32x4_t a0 = vmlal_s16(a, y0, x0);
/* Load last y. */
int16x4_t y4 = vld1_dup_s16(y);
y0 = vreinterpret_s16_s64(vsri_n_s64(vreinterpret_s64_s16(y4),
vreinterpret_s64_s16(y0), 16));
a = a0;
x++;
}
/* Load last x. */
int16x4_t x0 = vld1_dup_s16(x);
int32x4_t a0 = vmlal_s16(a, y0, x0);
vst1q_s32(sum, a0);
}
#else
#if defined(__ARM_FEATURE_FMA) && defined(__ARM_ARCH_ISA_A64)
/* If we can, force the compiler to use an FMA instruction rather than break
* vmlaq_f32() into fmul/fadd. */
#ifdef vmlaq_lane_f32
#undef vmlaq_lane_f32
#endif
#define vmlaq_lane_f32(a,b,c,lane) vfmaq_lane_f32(a,b,c,lane)
#endif
/*
* Function: xcorr_kernel_neon_float
* ---------------------------------
* Computes 4 correlation values and stores them in sum[4]
*/
static void xcorr_kernel_neon_float(const float32_t *x, const float32_t *y,
float32_t sum[4], int len) {
float32x4_t YY[3];
float32x4_t YEXT[3];
float32x4_t XX[2];
float32x2_t XX_2;
float32x4_t SUMM;
const float32_t *xi = x;
const float32_t *yi = y;
celt_assert(len>0);
YY[0] = vld1q_f32(yi);
SUMM = vdupq_n_f32(0);
/* Consume 8 elements in x vector and 12 elements in y
* vector. However, the 12'th element never really gets
* touched in this loop. So, if len == 8, then we only
* must access y[0] to y[10]. y[11] must not be accessed
* hence make sure len > 8 and not len >= 8
*/
while (len > 8) {
yi += 4;
YY[1] = vld1q_f32(yi);
yi += 4;
YY[2] = vld1q_f32(yi);
XX[0] = vld1q_f32(xi);
xi += 4;
XX[1] = vld1q_f32(xi);
xi += 4;
SUMM = vmlaq_lane_f32(SUMM, YY[0], vget_low_f32(XX[0]), 0);
YEXT[0] = vextq_f32(YY[0], YY[1], 1);
SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[0]), 1);
YEXT[1] = vextq_f32(YY[0], YY[1], 2);
SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[0]), 0);
YEXT[2] = vextq_f32(YY[0], YY[1], 3);
SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[0]), 1);
SUMM = vmlaq_lane_f32(SUMM, YY[1], vget_low_f32(XX[1]), 0);
YEXT[0] = vextq_f32(YY[1], YY[2], 1);
SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[1]), 1);
YEXT[1] = vextq_f32(YY[1], YY[2], 2);
SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[1]), 0);
YEXT[2] = vextq_f32(YY[1], YY[2], 3);
SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[1]), 1);
YY[0] = YY[2];
len -= 8;
}
/* Consume 4 elements in x vector and 8 elements in y
* vector. However, the 8'th element in y never really gets
* touched in this loop. So, if len == 4, then we only
* must access y[0] to y[6]. y[7] must not be accessed
* hence make sure len>4 and not len>=4
*/
if (len > 4) {
yi += 4;
YY[1] = vld1q_f32(yi);
XX[0] = vld1q_f32(xi);
xi += 4;
SUMM = vmlaq_lane_f32(SUMM, YY[0], vget_low_f32(XX[0]), 0);
YEXT[0] = vextq_f32(YY[0], YY[1], 1);
SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[0]), 1);
YEXT[1] = vextq_f32(YY[0], YY[1], 2);
SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[0]), 0);
YEXT[2] = vextq_f32(YY[0], YY[1], 3);
SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[0]), 1);
YY[0] = YY[1];
len -= 4;
}
while (--len > 0) {
XX_2 = vld1_dup_f32(xi++);
SUMM = vmlaq_lane_f32(SUMM, YY[0], XX_2, 0);
YY[0]= vld1q_f32(++yi);
}
XX_2 = vld1_dup_f32(xi);
SUMM = vmlaq_lane_f32(SUMM, YY[0], XX_2, 0);
vst1q_f32(sum, SUMM);
}
void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch, int arch) {
int i;
(void)arch;
celt_assert(max_pitch > 0);
celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
for (i = 0; i < (max_pitch-3); i += 4) {
xcorr_kernel_neon_float((const float32_t *)_x, (const float32_t *)_y+i,
(float32_t *)xcorr+i, len);
}
/* In case max_pitch isn't a multiple of 4, do non-unrolled version. */
for (; i < max_pitch; i++) {
xcorr[i] = celt_inner_prod_neon(_x, _y+i, len);
}
}
#endif

View file

@ -0,0 +1,555 @@
.syntax unified
@ Copyright (c) 2007-2008 CSIRO
@ Copyright (c) 2007-2009 Xiph.Org Foundation
@ Copyright (c) 2013 Parrot
@ Written by Aurélien Zanelli
@
@ Redistribution and use in source and binary forms, with or without
@ modification, are permitted provided that the following conditions
@ are met:
@
@ - Redistributions of source code must retain the above copyright
@ notice, this list of conditions and the following disclaimer.
@
@ - Redistributions in binary form must reproduce the above copyright
@ notice, this list of conditions and the following disclaimer in the
@ documentation and/or other materials provided with the distribution.
@
@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
@ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
@ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
@ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
@ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.text; .p2align 2; .arch armv7-a
.fpu neon
.object_arch armv4t
.include "celt/arm/armopts-gnu.S"
.if OPUS_ARM_MAY_HAVE_EDSP
.global celt_pitch_xcorr_edsp
.endif
.if OPUS_ARM_MAY_HAVE_NEON
.global celt_pitch_xcorr_neon
.endif
.if OPUS_ARM_MAY_HAVE_NEON
@ Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3
.type xcorr_kernel_neon, %function; xcorr_kernel_neon: @ PROC
xcorr_kernel_neon_start:
@ input:
@ r3 = int len
@ r4 = opus_val16 *x
@ r5 = opus_val16 *y
@ q0 = opus_val32 sum[4]
@ output:
@ q0 = opus_val32 sum[4]
@ preserved: r0-r3, r6-r11, d2, q4-q7, q9-q15
@ internal usage:
@ r12 = int j
@ d3 = y_3|y_2|y_1|y_0
@ q2 = y_B|y_A|y_9|y_8|y_7|y_6|y_5|y_4
@ q3 = x_7|x_6|x_5|x_4|x_3|x_2|x_1|x_0
@ q8 = scratch
@
@ Load y[0...3]
@ This requires len>0 to always be valid (which we assert in the C code).
VLD1.16 {d5}, [r5]!
SUBS r12, r3, #8
BLE xcorr_kernel_neon_process4
@ Process 8 samples at a time.
@ This loop loads one y value more than we actually need. Therefore we have to
@ stop as soon as there are 8 or fewer samples left (instead of 7), to avoid
@ reading past the end of the array.
xcorr_kernel_neon_process8:
@ This loop has 19 total instructions (10 cycles to issue, minimum), with
@ - 2 cycles of ARM insrtuctions,
@ - 10 cycles of load/store/byte permute instructions, and
@ - 9 cycles of data processing instructions.
@ On a Cortex A8, we dual-issue the maximum amount (9 cycles) between the
@ latter two categories, meaning the whole loop should run in 10 cycles per
@ iteration, barring cache misses.
@
@ Load x[0...7]
VLD1.16 {d6, d7}, [r4]!
@ Unlike VMOV, VAND is a data processsing instruction (and doesn't get
@ assembled to VMOV, like VORR would), so it dual-issues with the prior VLD1.
VAND d3, d5, d5
SUBS r12, r12, #8
@ Load y[4...11]
VLD1.16 {d4, d5}, [r5]!
VMLAL.S16 q0, d3, d6[0]
VEXT.16 d16, d3, d4, #1
VMLAL.S16 q0, d4, d7[0]
VEXT.16 d17, d4, d5, #1
VMLAL.S16 q0, d16, d6[1]
VEXT.16 d16, d3, d4, #2
VMLAL.S16 q0, d17, d7[1]
VEXT.16 d17, d4, d5, #2
VMLAL.S16 q0, d16, d6[2]
VEXT.16 d16, d3, d4, #3
VMLAL.S16 q0, d17, d7[2]
VEXT.16 d17, d4, d5, #3
VMLAL.S16 q0, d16, d6[3]
VMLAL.S16 q0, d17, d7[3]
BGT xcorr_kernel_neon_process8
@ Process 4 samples here if we have > 4 left (still reading one extra y value).
xcorr_kernel_neon_process4:
ADDS r12, r12, #4
BLE xcorr_kernel_neon_process2
@ Load x[0...3]
VLD1.16 d6, [r4]!
@ Use VAND since it's a data processing instruction again.
VAND d4, d5, d5
SUB r12, r12, #4
@ Load y[4...7]
VLD1.16 d5, [r5]!
VMLAL.S16 q0, d4, d6[0]
VEXT.16 d16, d4, d5, #1
VMLAL.S16 q0, d16, d6[1]
VEXT.16 d16, d4, d5, #2
VMLAL.S16 q0, d16, d6[2]
VEXT.16 d16, d4, d5, #3
VMLAL.S16 q0, d16, d6[3]
@ Process 2 samples here if we have > 2 left (still reading one extra y value).
xcorr_kernel_neon_process2:
ADDS r12, r12, #2
BLE xcorr_kernel_neon_process1
@ Load x[0...1]
VLD2.16 {d6[],d7[]}, [r4]!
@ Use VAND since it's a data processing instruction again.
VAND d4, d5, d5
SUB r12, r12, #2
@ Load y[4...5]
VLD1.32 {d5[]}, [r5]!
VMLAL.S16 q0, d4, d6
VEXT.16 d16, d4, d5, #1
@ Replace bottom copy of {y5,y4} in d5 with {y3,y2} from d4, using VSRI
@ instead of VEXT, since it's a data-processing instruction.
VSRI.64 d5, d4, #32
VMLAL.S16 q0, d16, d7
@ Process 1 sample using the extra y value we loaded above.
xcorr_kernel_neon_process1:
@ Load next *x
VLD1.16 {d6[]}, [r4]!
ADDS r12, r12, #1
@ y[0...3] are left in d5 from prior iteration(s) (if any)
VMLAL.S16 q0, d5, d6
MOVLE pc, lr
@ Now process 1 last sample, not reading ahead.
@ Load last *y
VLD1.16 {d4[]}, [r5]!
VSRI.64 d4, d5, #16
@ Load last *x
VLD1.16 {d6[]}, [r4]!
VMLAL.S16 q0, d4, d6
MOV pc, lr
.size xcorr_kernel_neon, .-xcorr_kernel_neon @ ENDP
@ opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y,
@ opus_val32 *xcorr, int len, int max_pitch, int arch)
.type celt_pitch_xcorr_neon, %function; celt_pitch_xcorr_neon: @ PROC
@ input:
@ r0 = opus_val16 *_x
@ r1 = opus_val16 *_y
@ r2 = opus_val32 *xcorr
@ r3 = int len
@ output:
@ r0 = int maxcorr
@ internal usage:
@ r4 = opus_val16 *x (for xcorr_kernel_neon())
@ r5 = opus_val16 *y (for xcorr_kernel_neon())
@ r6 = int max_pitch
@ r12 = int j
@ q15 = int maxcorr[4] (q15 is not used by xcorr_kernel_neon())
@ ignored:
@ int arch
STMFD sp!, {r4-r6, lr}
LDR r6, [sp, #16]
VMOV.S32 q15, #1
@ if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done
SUBS r6, r6, #4
BLT celt_pitch_xcorr_neon_process4_done
celt_pitch_xcorr_neon_process4:
@ xcorr_kernel_neon parameters:
@ r3 = len, r4 = _x, r5 = _y, q0 = {0, 0, 0, 0}
MOV r4, r0
MOV r5, r1
VEOR q0, q0, q0
@ xcorr_kernel_neon only modifies r4, r5, r12, and q0...q3.
@ So we don't save/restore any other registers.
BL xcorr_kernel_neon_start
SUBS r6, r6, #4
VST1.32 {q0}, [r2]!
@ _y += 4
ADD r1, r1, #8
VMAX.S32 q15, q15, q0
@ if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done
BGE celt_pitch_xcorr_neon_process4
@ We have less than 4 sums left to compute.
celt_pitch_xcorr_neon_process4_done:
ADDS r6, r6, #4
@ Reduce maxcorr to a single value
VMAX.S32 d30, d30, d31
VPMAX.S32 d30, d30, d30
@ if (max_pitch <= 0) goto celt_pitch_xcorr_neon_done
BLE celt_pitch_xcorr_neon_done
@ Now compute each remaining sum one at a time.
celt_pitch_xcorr_neon_process_remaining:
MOV r4, r0
MOV r5, r1
VMOV.I32 q0, #0
SUBS r12, r3, #8
BLT celt_pitch_xcorr_neon_process_remaining4
@ Sum terms 8 at a time.
celt_pitch_xcorr_neon_process_remaining_loop8:
@ Load x[0...7]
VLD1.16 {q1}, [r4]!
@ Load y[0...7]
VLD1.16 {q2}, [r5]!
SUBS r12, r12, #8
VMLAL.S16 q0, d4, d2
VMLAL.S16 q0, d5, d3
BGE celt_pitch_xcorr_neon_process_remaining_loop8
@ Sum terms 4 at a time.
celt_pitch_xcorr_neon_process_remaining4:
ADDS r12, r12, #4
BLT celt_pitch_xcorr_neon_process_remaining4_done
@ Load x[0...3]
VLD1.16 {d2}, [r4]!
@ Load y[0...3]
VLD1.16 {d3}, [r5]!
SUB r12, r12, #4
VMLAL.S16 q0, d3, d2
celt_pitch_xcorr_neon_process_remaining4_done:
@ Reduce the sum to a single value.
VADD.S32 d0, d0, d1
VPADDL.S32 d0, d0
ADDS r12, r12, #4
BLE celt_pitch_xcorr_neon_process_remaining_loop_done
@ Sum terms 1 at a time.
celt_pitch_xcorr_neon_process_remaining_loop1:
VLD1.16 {d2[]}, [r4]!
VLD1.16 {d3[]}, [r5]!
SUBS r12, r12, #1
VMLAL.S16 q0, d2, d3
BGT celt_pitch_xcorr_neon_process_remaining_loop1
celt_pitch_xcorr_neon_process_remaining_loop_done:
VST1.32 {d0[0]}, [r2]!
VMAX.S32 d30, d30, d0
SUBS r6, r6, #1
@ _y++
ADD r1, r1, #2
@ if (--max_pitch > 0) goto celt_pitch_xcorr_neon_process_remaining
BGT celt_pitch_xcorr_neon_process_remaining
celt_pitch_xcorr_neon_done:
VMOV.32 r0, d30[0]
LDMFD sp!, {r4-r6, pc}
.size celt_pitch_xcorr_neon, .-celt_pitch_xcorr_neon @ ENDP
.endif
.if OPUS_ARM_MAY_HAVE_EDSP
@ This will get used on ARMv7 devices without NEON, so it has been optimized
@ to take advantage of dual-issuing where possible.
.type xcorr_kernel_edsp, %function; xcorr_kernel_edsp: @ PROC
xcorr_kernel_edsp_start:
@ input:
@ r3 = int len
@ r4 = opus_val16 *_x (must be 32-bit aligned)
@ r5 = opus_val16 *_y (must be 32-bit aligned)
@ r6...r9 = opus_val32 sum[4]
@ output:
@ r6...r9 = opus_val32 sum[4]
@ preserved: r0-r5
@ internal usage
@ r2 = int j
@ r12,r14 = opus_val16 x[4]
@ r10,r11 = opus_val16 y[4]
STMFD sp!, {r2,r4,r5,lr}
LDR r10, [r5], #4 @ Load y[0...1]
SUBS r2, r3, #4 @ j = len-4
LDR r11, [r5], #4 @ Load y[2...3]
BLE xcorr_kernel_edsp_process4_done
LDR r12, [r4], #4 @ Load x[0...1]
@ Stall
xcorr_kernel_edsp_process4:
@ The multiplies must issue from pipeline 0, and can't dual-issue with each
@ other. Every other instruction here dual-issues with a multiply, and is
@ thus "free". There should be no stalls in the body of the loop.
SMLABB r6, r12, r10, r6 @ sum[0] = MAC16_16(sum[0],x_0,y_0)
LDR r14, [r4], #4 @ Load x[2...3]
SMLABT r7, r12, r10, r7 @ sum[1] = MAC16_16(sum[1],x_0,y_1)
SUBS r2, r2, #4 @ j-=4
SMLABB r8, r12, r11, r8 @ sum[2] = MAC16_16(sum[2],x_0,y_2)
SMLABT r9, r12, r11, r9 @ sum[3] = MAC16_16(sum[3],x_0,y_3)
SMLATT r6, r12, r10, r6 @ sum[0] = MAC16_16(sum[0],x_1,y_1)
LDR r10, [r5], #4 @ Load y[4...5]
SMLATB r7, r12, r11, r7 @ sum[1] = MAC16_16(sum[1],x_1,y_2)
SMLATT r8, r12, r11, r8 @ sum[2] = MAC16_16(sum[2],x_1,y_3)
SMLATB r9, r12, r10, r9 @ sum[3] = MAC16_16(sum[3],x_1,y_4)
LDRGT r12, [r4], #4 @ Load x[0...1]
SMLABB r6, r14, r11, r6 @ sum[0] = MAC16_16(sum[0],x_2,y_2)
SMLABT r7, r14, r11, r7 @ sum[1] = MAC16_16(sum[1],x_2,y_3)
SMLABB r8, r14, r10, r8 @ sum[2] = MAC16_16(sum[2],x_2,y_4)
SMLABT r9, r14, r10, r9 @ sum[3] = MAC16_16(sum[3],x_2,y_5)
SMLATT r6, r14, r11, r6 @ sum[0] = MAC16_16(sum[0],x_3,y_3)
LDR r11, [r5], #4 @ Load y[6...7]
SMLATB r7, r14, r10, r7 @ sum[1] = MAC16_16(sum[1],x_3,y_4)
SMLATT r8, r14, r10, r8 @ sum[2] = MAC16_16(sum[2],x_3,y_5)
SMLATB r9, r14, r11, r9 @ sum[3] = MAC16_16(sum[3],x_3,y_6)
BGT xcorr_kernel_edsp_process4
xcorr_kernel_edsp_process4_done:
ADDS r2, r2, #4
BLE xcorr_kernel_edsp_done
LDRH r12, [r4], #2 @ r12 = *x++
SUBS r2, r2, #1 @ j--
@ Stall
SMLABB r6, r12, r10, r6 @ sum[0] = MAC16_16(sum[0],x,y_0)
LDRHGT r14, [r4], #2 @ r14 = *x++
SMLABT r7, r12, r10, r7 @ sum[1] = MAC16_16(sum[1],x,y_1)
SMLABB r8, r12, r11, r8 @ sum[2] = MAC16_16(sum[2],x,y_2)
SMLABT r9, r12, r11, r9 @ sum[3] = MAC16_16(sum[3],x,y_3)
BLE xcorr_kernel_edsp_done
SMLABT r6, r14, r10, r6 @ sum[0] = MAC16_16(sum[0],x,y_1)
SUBS r2, r2, #1 @ j--
SMLABB r7, r14, r11, r7 @ sum[1] = MAC16_16(sum[1],x,y_2)
LDRH r10, [r5], #2 @ r10 = y_4 = *y++
SMLABT r8, r14, r11, r8 @ sum[2] = MAC16_16(sum[2],x,y_3)
LDRHGT r12, [r4], #2 @ r12 = *x++
SMLABB r9, r14, r10, r9 @ sum[3] = MAC16_16(sum[3],x,y_4)
BLE xcorr_kernel_edsp_done
SMLABB r6, r12, r11, r6 @ sum[0] = MAC16_16(sum[0],tmp,y_2)
CMP r2, #1 @ j--
SMLABT r7, r12, r11, r7 @ sum[1] = MAC16_16(sum[1],tmp,y_3)
LDRH r2, [r5], #2 @ r2 = y_5 = *y++
SMLABB r8, r12, r10, r8 @ sum[2] = MAC16_16(sum[2],tmp,y_4)
LDRHGT r14, [r4] @ r14 = *x
SMLABB r9, r12, r2, r9 @ sum[3] = MAC16_16(sum[3],tmp,y_5)
BLE xcorr_kernel_edsp_done
SMLABT r6, r14, r11, r6 @ sum[0] = MAC16_16(sum[0],tmp,y_3)
LDRH r11, [r5] @ r11 = y_6 = *y
SMLABB r7, r14, r10, r7 @ sum[1] = MAC16_16(sum[1],tmp,y_4)
SMLABB r8, r14, r2, r8 @ sum[2] = MAC16_16(sum[2],tmp,y_5)
SMLABB r9, r14, r11, r9 @ sum[3] = MAC16_16(sum[3],tmp,y_6)
xcorr_kernel_edsp_done:
LDMFD sp!, {r2,r4,r5,pc}
.size xcorr_kernel_edsp, .-xcorr_kernel_edsp @ ENDP
.type celt_pitch_xcorr_edsp, %function; celt_pitch_xcorr_edsp: @ PROC
@ input:
@ r0 = opus_val16 *_x (must be 32-bit aligned)
@ r1 = opus_val16 *_y (only needs to be 16-bit aligned)
@ r2 = opus_val32 *xcorr
@ r3 = int len
@ output:
@ r0 = maxcorr
@ internal usage
@ r4 = opus_val16 *x
@ r5 = opus_val16 *y
@ r6 = opus_val32 sum0
@ r7 = opus_val32 sum1
@ r8 = opus_val32 sum2
@ r9 = opus_val32 sum3
@ r1 = int max_pitch
@ r12 = int j
@ ignored:
@ int arch
STMFD sp!, {r4-r11, lr}
MOV r5, r1
LDR r1, [sp, #36]
MOV r4, r0
TST r5, #3
@ maxcorr = 1
MOV r0, #1
BEQ celt_pitch_xcorr_edsp_process1u_done
@ Compute one sum at the start to make y 32-bit aligned.
SUBS r12, r3, #4
@ r14 = sum = 0
MOV r14, #0
LDRH r8, [r5], #2
BLE celt_pitch_xcorr_edsp_process1u_loop4_done
LDR r6, [r4], #4
MOV r8, r8, LSL #16
celt_pitch_xcorr_edsp_process1u_loop4:
LDR r9, [r5], #4
SMLABT r14, r6, r8, r14 @ sum = MAC16_16(sum, x_0, y_0)
LDR r7, [r4], #4
SMLATB r14, r6, r9, r14 @ sum = MAC16_16(sum, x_1, y_1)
LDR r8, [r5], #4
SMLABT r14, r7, r9, r14 @ sum = MAC16_16(sum, x_2, y_2)
SUBS r12, r12, #4 @ j-=4
SMLATB r14, r7, r8, r14 @ sum = MAC16_16(sum, x_3, y_3)
LDRGT r6, [r4], #4
BGT celt_pitch_xcorr_edsp_process1u_loop4
MOV r8, r8, LSR #16
celt_pitch_xcorr_edsp_process1u_loop4_done:
ADDS r12, r12, #4
celt_pitch_xcorr_edsp_process1u_loop1:
LDRHGE r6, [r4], #2
@ Stall
SMLABBGE r14, r6, r8, r14 @ sum = MAC16_16(sum, *x, *y)
SUBSGE r12, r12, #1
LDRHGT r8, [r5], #2
BGT celt_pitch_xcorr_edsp_process1u_loop1
@ Restore _x
SUB r4, r4, r3, LSL #1
@ Restore and advance _y
SUB r5, r5, r3, LSL #1
@ maxcorr = max(maxcorr, sum)
CMP r0, r14
ADD r5, r5, #2
MOVLT r0, r14
SUBS r1, r1, #1
@ xcorr[i] = sum
STR r14, [r2], #4
BLE celt_pitch_xcorr_edsp_done
celt_pitch_xcorr_edsp_process1u_done:
@ if (max_pitch < 4) goto celt_pitch_xcorr_edsp_process2
SUBS r1, r1, #4
BLT celt_pitch_xcorr_edsp_process2
celt_pitch_xcorr_edsp_process4:
@ xcorr_kernel_edsp parameters:
@ r3 = len, r4 = _x, r5 = _y, r6...r9 = sum[4] = {0, 0, 0, 0}
MOV r6, #0
MOV r7, #0
MOV r8, #0
MOV r9, #0
BL xcorr_kernel_edsp_start @ xcorr_kernel_edsp(_x, _y+i, xcorr+i, len)
@ maxcorr = max(maxcorr, sum0, sum1, sum2, sum3)
CMP r0, r6
@ _y+=4
ADD r5, r5, #8
MOVLT r0, r6
CMP r0, r7
MOVLT r0, r7
CMP r0, r8
MOVLT r0, r8
CMP r0, r9
MOVLT r0, r9
STMIA r2!, {r6-r9}
SUBS r1, r1, #4
BGE celt_pitch_xcorr_edsp_process4
celt_pitch_xcorr_edsp_process2:
ADDS r1, r1, #2
BLT celt_pitch_xcorr_edsp_process1a
SUBS r12, r3, #4
@ {r10, r11} = {sum0, sum1} = {0, 0}
MOV r10, #0
MOV r11, #0
LDR r8, [r5], #4
BLE celt_pitch_xcorr_edsp_process2_loop_done
LDR r6, [r4], #4
LDR r9, [r5], #4
celt_pitch_xcorr_edsp_process2_loop4:
SMLABB r10, r6, r8, r10 @ sum0 = MAC16_16(sum0, x_0, y_0)
LDR r7, [r4], #4
SMLABT r11, r6, r8, r11 @ sum1 = MAC16_16(sum1, x_0, y_1)
SUBS r12, r12, #4 @ j-=4
SMLATT r10, r6, r8, r10 @ sum0 = MAC16_16(sum0, x_1, y_1)
LDR r8, [r5], #4
SMLATB r11, r6, r9, r11 @ sum1 = MAC16_16(sum1, x_1, y_2)
LDRGT r6, [r4], #4
SMLABB r10, r7, r9, r10 @ sum0 = MAC16_16(sum0, x_2, y_2)
SMLABT r11, r7, r9, r11 @ sum1 = MAC16_16(sum1, x_2, y_3)
SMLATT r10, r7, r9, r10 @ sum0 = MAC16_16(sum0, x_3, y_3)
LDRGT r9, [r5], #4
SMLATB r11, r7, r8, r11 @ sum1 = MAC16_16(sum1, x_3, y_4)
BGT celt_pitch_xcorr_edsp_process2_loop4
celt_pitch_xcorr_edsp_process2_loop_done:
ADDS r12, r12, #2
BLE celt_pitch_xcorr_edsp_process2_1
LDR r6, [r4], #4
@ Stall
SMLABB r10, r6, r8, r10 @ sum0 = MAC16_16(sum0, x_0, y_0)
LDR r9, [r5], #4
SMLABT r11, r6, r8, r11 @ sum1 = MAC16_16(sum1, x_0, y_1)
SUB r12, r12, #2
SMLATT r10, r6, r8, r10 @ sum0 = MAC16_16(sum0, x_1, y_1)
MOV r8, r9
SMLATB r11, r6, r9, r11 @ sum1 = MAC16_16(sum1, x_1, y_2)
celt_pitch_xcorr_edsp_process2_1:
LDRH r6, [r4], #2
ADDS r12, r12, #1
@ Stall
SMLABB r10, r6, r8, r10 @ sum0 = MAC16_16(sum0, x_0, y_0)
LDRHGT r7, [r4], #2
SMLABT r11, r6, r8, r11 @ sum1 = MAC16_16(sum1, x_0, y_1)
BLE celt_pitch_xcorr_edsp_process2_done
LDRH r9, [r5], #2
SMLABT r10, r7, r8, r10 @ sum0 = MAC16_16(sum0, x_0, y_1)
SMLABB r11, r7, r9, r11 @ sum1 = MAC16_16(sum1, x_0, y_2)
celt_pitch_xcorr_edsp_process2_done:
@ Restore _x
SUB r4, r4, r3, LSL #1
@ Restore and advance _y
SUB r5, r5, r3, LSL #1
@ maxcorr = max(maxcorr, sum0)
CMP r0, r10
ADD r5, r5, #2
MOVLT r0, r10
SUB r1, r1, #2
@ maxcorr = max(maxcorr, sum1)
CMP r0, r11
@ xcorr[i] = sum
STR r10, [r2], #4
MOVLT r0, r11
STR r11, [r2], #4
celt_pitch_xcorr_edsp_process1a:
ADDS r1, r1, #1
BLT celt_pitch_xcorr_edsp_done
SUBS r12, r3, #4
@ r14 = sum = 0
MOV r14, #0
BLT celt_pitch_xcorr_edsp_process1a_loop_done
LDR r6, [r4], #4
LDR r8, [r5], #4
LDR r7, [r4], #4
LDR r9, [r5], #4
celt_pitch_xcorr_edsp_process1a_loop4:
SMLABB r14, r6, r8, r14 @ sum = MAC16_16(sum, x_0, y_0)
SUBS r12, r12, #4 @ j-=4
SMLATT r14, r6, r8, r14 @ sum = MAC16_16(sum, x_1, y_1)
LDRGE r6, [r4], #4
SMLABB r14, r7, r9, r14 @ sum = MAC16_16(sum, x_2, y_2)
LDRGE r8, [r5], #4
SMLATT r14, r7, r9, r14 @ sum = MAC16_16(sum, x_3, y_3)
LDRGE r7, [r4], #4
LDRGE r9, [r5], #4
BGE celt_pitch_xcorr_edsp_process1a_loop4
celt_pitch_xcorr_edsp_process1a_loop_done:
ADDS r12, r12, #2
LDRGE r6, [r4], #4
LDRGE r8, [r5], #4
@ Stall
SMLABBGE r14, r6, r8, r14 @ sum = MAC16_16(sum, x_0, y_0)
SUBGE r12, r12, #2
SMLATTGE r14, r6, r8, r14 @ sum = MAC16_16(sum, x_1, y_1)
ADDS r12, r12, #1
LDRHGE r6, [r4], #2
LDRHGE r8, [r5], #2
@ Stall
SMLABBGE r14, r6, r8, r14 @ sum = MAC16_16(sum, *x, *y)
@ maxcorr = max(maxcorr, sum)
CMP r0, r14
@ xcorr[i] = sum
STR r14, [r2], #4
MOVLT r0, r14
celt_pitch_xcorr_edsp_done:
LDMFD sp!, {r4-r11, pc}
.size celt_pitch_xcorr_edsp, .-celt_pitch_xcorr_edsp @ ENDP
.endif
@ END:
.section .note.GNU-stack,"",%progbits

View file

@ -0,0 +1,551 @@
; Copyright (c) 2007-2008 CSIRO
; Copyright (c) 2007-2009 Xiph.Org Foundation
; Copyright (c) 2013 Parrot
; Written by Aurélien Zanelli
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions
; are met:
;
; - Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
;
; - Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
; OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
AREA |.text|, CODE, READONLY
GET celt/arm/armopts.s
IF OPUS_ARM_MAY_HAVE_EDSP
EXPORT celt_pitch_xcorr_edsp
ENDIF
IF OPUS_ARM_MAY_HAVE_NEON
EXPORT celt_pitch_xcorr_neon
ENDIF
IF OPUS_ARM_MAY_HAVE_NEON
; Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3
xcorr_kernel_neon PROC
xcorr_kernel_neon_start
; input:
; r3 = int len
; r4 = opus_val16 *x
; r5 = opus_val16 *y
; q0 = opus_val32 sum[4]
; output:
; q0 = opus_val32 sum[4]
; preserved: r0-r3, r6-r11, d2, q4-q7, q9-q15
; internal usage:
; r12 = int j
; d3 = y_3|y_2|y_1|y_0
; q2 = y_B|y_A|y_9|y_8|y_7|y_6|y_5|y_4
; q3 = x_7|x_6|x_5|x_4|x_3|x_2|x_1|x_0
; q8 = scratch
;
; Load y[0...3]
; This requires len>0 to always be valid (which we assert in the C code).
VLD1.16 {d5}, [r5]!
SUBS r12, r3, #8
BLE xcorr_kernel_neon_process4
; Process 8 samples at a time.
; This loop loads one y value more than we actually need. Therefore we have to
; stop as soon as there are 8 or fewer samples left (instead of 7), to avoid
; reading past the end of the array.
xcorr_kernel_neon_process8
; This loop has 19 total instructions (10 cycles to issue, minimum), with
; - 2 cycles of ARM insrtuctions,
; - 10 cycles of load/store/byte permute instructions, and
; - 9 cycles of data processing instructions.
; On a Cortex A8, we dual-issue the maximum amount (9 cycles) between the
; latter two categories, meaning the whole loop should run in 10 cycles per
; iteration, barring cache misses.
;
; Load x[0...7]
VLD1.16 {d6, d7}, [r4]!
; Unlike VMOV, VAND is a data processsing instruction (and doesn't get
; assembled to VMOV, like VORR would), so it dual-issues with the prior VLD1.
VAND d3, d5, d5
SUBS r12, r12, #8
; Load y[4...11]
VLD1.16 {d4, d5}, [r5]!
VMLAL.S16 q0, d3, d6[0]
VEXT.16 d16, d3, d4, #1
VMLAL.S16 q0, d4, d7[0]
VEXT.16 d17, d4, d5, #1
VMLAL.S16 q0, d16, d6[1]
VEXT.16 d16, d3, d4, #2
VMLAL.S16 q0, d17, d7[1]
VEXT.16 d17, d4, d5, #2
VMLAL.S16 q0, d16, d6[2]
VEXT.16 d16, d3, d4, #3
VMLAL.S16 q0, d17, d7[2]
VEXT.16 d17, d4, d5, #3
VMLAL.S16 q0, d16, d6[3]
VMLAL.S16 q0, d17, d7[3]
BGT xcorr_kernel_neon_process8
; Process 4 samples here if we have > 4 left (still reading one extra y value).
xcorr_kernel_neon_process4
ADDS r12, r12, #4
BLE xcorr_kernel_neon_process2
; Load x[0...3]
VLD1.16 d6, [r4]!
; Use VAND since it's a data processing instruction again.
VAND d4, d5, d5
SUB r12, r12, #4
; Load y[4...7]
VLD1.16 d5, [r5]!
VMLAL.S16 q0, d4, d6[0]
VEXT.16 d16, d4, d5, #1
VMLAL.S16 q0, d16, d6[1]
VEXT.16 d16, d4, d5, #2
VMLAL.S16 q0, d16, d6[2]
VEXT.16 d16, d4, d5, #3
VMLAL.S16 q0, d16, d6[3]
; Process 2 samples here if we have > 2 left (still reading one extra y value).
xcorr_kernel_neon_process2
ADDS r12, r12, #2
BLE xcorr_kernel_neon_process1
; Load x[0...1]
VLD2.16 {d6[],d7[]}, [r4]!
; Use VAND since it's a data processing instruction again.
VAND d4, d5, d5
SUB r12, r12, #2
; Load y[4...5]
VLD1.32 {d5[]}, [r5]!
VMLAL.S16 q0, d4, d6
VEXT.16 d16, d4, d5, #1
; Replace bottom copy of {y5,y4} in d5 with {y3,y2} from d4, using VSRI
; instead of VEXT, since it's a data-processing instruction.
VSRI.64 d5, d4, #32
VMLAL.S16 q0, d16, d7
; Process 1 sample using the extra y value we loaded above.
xcorr_kernel_neon_process1
; Load next *x
VLD1.16 {d6[]}, [r4]!
ADDS r12, r12, #1
; y[0...3] are left in d5 from prior iteration(s) (if any)
VMLAL.S16 q0, d5, d6
MOVLE pc, lr
; Now process 1 last sample, not reading ahead.
; Load last *y
VLD1.16 {d4[]}, [r5]!
VSRI.64 d4, d5, #16
; Load last *x
VLD1.16 {d6[]}, [r4]!
VMLAL.S16 q0, d4, d6
MOV pc, lr
ENDP
; opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y,
; opus_val32 *xcorr, int len, int max_pitch, int arch)
celt_pitch_xcorr_neon PROC
; input:
; r0 = opus_val16 *_x
; r1 = opus_val16 *_y
; r2 = opus_val32 *xcorr
; r3 = int len
; output:
; r0 = int maxcorr
; internal usage:
; r4 = opus_val16 *x (for xcorr_kernel_neon())
; r5 = opus_val16 *y (for xcorr_kernel_neon())
; r6 = int max_pitch
; r12 = int j
; q15 = int maxcorr[4] (q15 is not used by xcorr_kernel_neon())
; ignored:
; int arch
STMFD sp!, {r4-r6, lr}
LDR r6, [sp, #16]
VMOV.S32 q15, #1
; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done
SUBS r6, r6, #4
BLT celt_pitch_xcorr_neon_process4_done
celt_pitch_xcorr_neon_process4
; xcorr_kernel_neon parameters:
; r3 = len, r4 = _x, r5 = _y, q0 = {0, 0, 0, 0}
MOV r4, r0
MOV r5, r1
VEOR q0, q0, q0
; xcorr_kernel_neon only modifies r4, r5, r12, and q0...q3.
; So we don't save/restore any other registers.
BL xcorr_kernel_neon_start
SUBS r6, r6, #4
VST1.32 {q0}, [r2]!
; _y += 4
ADD r1, r1, #8
VMAX.S32 q15, q15, q0
; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done
BGE celt_pitch_xcorr_neon_process4
; We have less than 4 sums left to compute.
celt_pitch_xcorr_neon_process4_done
ADDS r6, r6, #4
; Reduce maxcorr to a single value
VMAX.S32 d30, d30, d31
VPMAX.S32 d30, d30, d30
; if (max_pitch <= 0) goto celt_pitch_xcorr_neon_done
BLE celt_pitch_xcorr_neon_done
; Now compute each remaining sum one at a time.
celt_pitch_xcorr_neon_process_remaining
MOV r4, r0
MOV r5, r1
VMOV.I32 q0, #0
SUBS r12, r3, #8
BLT celt_pitch_xcorr_neon_process_remaining4
; Sum terms 8 at a time.
celt_pitch_xcorr_neon_process_remaining_loop8
; Load x[0...7]
VLD1.16 {q1}, [r4]!
; Load y[0...7]
VLD1.16 {q2}, [r5]!
SUBS r12, r12, #8
VMLAL.S16 q0, d4, d2
VMLAL.S16 q0, d5, d3
BGE celt_pitch_xcorr_neon_process_remaining_loop8
; Sum terms 4 at a time.
celt_pitch_xcorr_neon_process_remaining4
ADDS r12, r12, #4
BLT celt_pitch_xcorr_neon_process_remaining4_done
; Load x[0...3]
VLD1.16 {d2}, [r4]!
; Load y[0...3]
VLD1.16 {d3}, [r5]!
SUB r12, r12, #4
VMLAL.S16 q0, d3, d2
celt_pitch_xcorr_neon_process_remaining4_done
; Reduce the sum to a single value.
VADD.S32 d0, d0, d1
VPADDL.S32 d0, d0
ADDS r12, r12, #4
BLE celt_pitch_xcorr_neon_process_remaining_loop_done
; Sum terms 1 at a time.
celt_pitch_xcorr_neon_process_remaining_loop1
VLD1.16 {d2[]}, [r4]!
VLD1.16 {d3[]}, [r5]!
SUBS r12, r12, #1
VMLAL.S16 q0, d2, d3
BGT celt_pitch_xcorr_neon_process_remaining_loop1
celt_pitch_xcorr_neon_process_remaining_loop_done
VST1.32 {d0[0]}, [r2]!
VMAX.S32 d30, d30, d0
SUBS r6, r6, #1
; _y++
ADD r1, r1, #2
; if (--max_pitch > 0) goto celt_pitch_xcorr_neon_process_remaining
BGT celt_pitch_xcorr_neon_process_remaining
celt_pitch_xcorr_neon_done
VMOV.32 r0, d30[0]
LDMFD sp!, {r4-r6, pc}
ENDP
ENDIF
IF OPUS_ARM_MAY_HAVE_EDSP
; This will get used on ARMv7 devices without NEON, so it has been optimized
; to take advantage of dual-issuing where possible.
xcorr_kernel_edsp PROC
xcorr_kernel_edsp_start
; input:
; r3 = int len
; r4 = opus_val16 *_x (must be 32-bit aligned)
; r5 = opus_val16 *_y (must be 32-bit aligned)
; r6...r9 = opus_val32 sum[4]
; output:
; r6...r9 = opus_val32 sum[4]
; preserved: r0-r5
; internal usage
; r2 = int j
; r12,r14 = opus_val16 x[4]
; r10,r11 = opus_val16 y[4]
STMFD sp!, {r2,r4,r5,lr}
LDR r10, [r5], #4 ; Load y[0...1]
SUBS r2, r3, #4 ; j = len-4
LDR r11, [r5], #4 ; Load y[2...3]
BLE xcorr_kernel_edsp_process4_done
LDR r12, [r4], #4 ; Load x[0...1]
; Stall
xcorr_kernel_edsp_process4
; The multiplies must issue from pipeline 0, and can't dual-issue with each
; other. Every other instruction here dual-issues with a multiply, and is
; thus "free". There should be no stalls in the body of the loop.
SMLABB r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x_0,y_0)
LDR r14, [r4], #4 ; Load x[2...3]
SMLABT r7, r12, r10, r7 ; sum[1] = MAC16_16(sum[1],x_0,y_1)
SUBS r2, r2, #4 ; j-=4
SMLABB r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x_0,y_2)
SMLABT r9, r12, r11, r9 ; sum[3] = MAC16_16(sum[3],x_0,y_3)
SMLATT r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x_1,y_1)
LDR r10, [r5], #4 ; Load y[4...5]
SMLATB r7, r12, r11, r7 ; sum[1] = MAC16_16(sum[1],x_1,y_2)
SMLATT r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x_1,y_3)
SMLATB r9, r12, r10, r9 ; sum[3] = MAC16_16(sum[3],x_1,y_4)
LDRGT r12, [r4], #4 ; Load x[0...1]
SMLABB r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],x_2,y_2)
SMLABT r7, r14, r11, r7 ; sum[1] = MAC16_16(sum[1],x_2,y_3)
SMLABB r8, r14, r10, r8 ; sum[2] = MAC16_16(sum[2],x_2,y_4)
SMLABT r9, r14, r10, r9 ; sum[3] = MAC16_16(sum[3],x_2,y_5)
SMLATT r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],x_3,y_3)
LDR r11, [r5], #4 ; Load y[6...7]
SMLATB r7, r14, r10, r7 ; sum[1] = MAC16_16(sum[1],x_3,y_4)
SMLATT r8, r14, r10, r8 ; sum[2] = MAC16_16(sum[2],x_3,y_5)
SMLATB r9, r14, r11, r9 ; sum[3] = MAC16_16(sum[3],x_3,y_6)
BGT xcorr_kernel_edsp_process4
xcorr_kernel_edsp_process4_done
ADDS r2, r2, #4
BLE xcorr_kernel_edsp_done
LDRH r12, [r4], #2 ; r12 = *x++
SUBS r2, r2, #1 ; j--
; Stall
SMLABB r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x,y_0)
LDRHGT r14, [r4], #2 ; r14 = *x++
SMLABT r7, r12, r10, r7 ; sum[1] = MAC16_16(sum[1],x,y_1)
SMLABB r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x,y_2)
SMLABT r9, r12, r11, r9 ; sum[3] = MAC16_16(sum[3],x,y_3)
BLE xcorr_kernel_edsp_done
SMLABT r6, r14, r10, r6 ; sum[0] = MAC16_16(sum[0],x,y_1)
SUBS r2, r2, #1 ; j--
SMLABB r7, r14, r11, r7 ; sum[1] = MAC16_16(sum[1],x,y_2)
LDRH r10, [r5], #2 ; r10 = y_4 = *y++
SMLABT r8, r14, r11, r8 ; sum[2] = MAC16_16(sum[2],x,y_3)
LDRHGT r12, [r4], #2 ; r12 = *x++
SMLABB r9, r14, r10, r9 ; sum[3] = MAC16_16(sum[3],x,y_4)
BLE xcorr_kernel_edsp_done
SMLABB r6, r12, r11, r6 ; sum[0] = MAC16_16(sum[0],tmp,y_2)
CMP r2, #1 ; j--
SMLABT r7, r12, r11, r7 ; sum[1] = MAC16_16(sum[1],tmp,y_3)
LDRH r2, [r5], #2 ; r2 = y_5 = *y++
SMLABB r8, r12, r10, r8 ; sum[2] = MAC16_16(sum[2],tmp,y_4)
LDRHGT r14, [r4] ; r14 = *x
SMLABB r9, r12, r2, r9 ; sum[3] = MAC16_16(sum[3],tmp,y_5)
BLE xcorr_kernel_edsp_done
SMLABT r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],tmp,y_3)
LDRH r11, [r5] ; r11 = y_6 = *y
SMLABB r7, r14, r10, r7 ; sum[1] = MAC16_16(sum[1],tmp,y_4)
SMLABB r8, r14, r2, r8 ; sum[2] = MAC16_16(sum[2],tmp,y_5)
SMLABB r9, r14, r11, r9 ; sum[3] = MAC16_16(sum[3],tmp,y_6)
xcorr_kernel_edsp_done
LDMFD sp!, {r2,r4,r5,pc}
ENDP
celt_pitch_xcorr_edsp PROC
; input:
; r0 = opus_val16 *_x (must be 32-bit aligned)
; r1 = opus_val16 *_y (only needs to be 16-bit aligned)
; r2 = opus_val32 *xcorr
; r3 = int len
; output:
; r0 = maxcorr
; internal usage
; r4 = opus_val16 *x
; r5 = opus_val16 *y
; r6 = opus_val32 sum0
; r7 = opus_val32 sum1
; r8 = opus_val32 sum2
; r9 = opus_val32 sum3
; r1 = int max_pitch
; r12 = int j
; ignored:
; int arch
STMFD sp!, {r4-r11, lr}
MOV r5, r1
LDR r1, [sp, #36]
MOV r4, r0
TST r5, #3
; maxcorr = 1
MOV r0, #1
BEQ celt_pitch_xcorr_edsp_process1u_done
; Compute one sum at the start to make y 32-bit aligned.
SUBS r12, r3, #4
; r14 = sum = 0
MOV r14, #0
LDRH r8, [r5], #2
BLE celt_pitch_xcorr_edsp_process1u_loop4_done
LDR r6, [r4], #4
MOV r8, r8, LSL #16
celt_pitch_xcorr_edsp_process1u_loop4
LDR r9, [r5], #4
SMLABT r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0)
LDR r7, [r4], #4
SMLATB r14, r6, r9, r14 ; sum = MAC16_16(sum, x_1, y_1)
LDR r8, [r5], #4
SMLABT r14, r7, r9, r14 ; sum = MAC16_16(sum, x_2, y_2)
SUBS r12, r12, #4 ; j-=4
SMLATB r14, r7, r8, r14 ; sum = MAC16_16(sum, x_3, y_3)
LDRGT r6, [r4], #4
BGT celt_pitch_xcorr_edsp_process1u_loop4
MOV r8, r8, LSR #16
celt_pitch_xcorr_edsp_process1u_loop4_done
ADDS r12, r12, #4
celt_pitch_xcorr_edsp_process1u_loop1
LDRHGE r6, [r4], #2
; Stall
SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, *x, *y)
SUBSGE r12, r12, #1
LDRHGT r8, [r5], #2
BGT celt_pitch_xcorr_edsp_process1u_loop1
; Restore _x
SUB r4, r4, r3, LSL #1
; Restore and advance _y
SUB r5, r5, r3, LSL #1
; maxcorr = max(maxcorr, sum)
CMP r0, r14
ADD r5, r5, #2
MOVLT r0, r14
SUBS r1, r1, #1
; xcorr[i] = sum
STR r14, [r2], #4
BLE celt_pitch_xcorr_edsp_done
celt_pitch_xcorr_edsp_process1u_done
; if (max_pitch < 4) goto celt_pitch_xcorr_edsp_process2
SUBS r1, r1, #4
BLT celt_pitch_xcorr_edsp_process2
celt_pitch_xcorr_edsp_process4
; xcorr_kernel_edsp parameters:
; r3 = len, r4 = _x, r5 = _y, r6...r9 = sum[4] = {0, 0, 0, 0}
MOV r6, #0
MOV r7, #0
MOV r8, #0
MOV r9, #0
BL xcorr_kernel_edsp_start ; xcorr_kernel_edsp(_x, _y+i, xcorr+i, len)
; maxcorr = max(maxcorr, sum0, sum1, sum2, sum3)
CMP r0, r6
; _y+=4
ADD r5, r5, #8
MOVLT r0, r6
CMP r0, r7
MOVLT r0, r7
CMP r0, r8
MOVLT r0, r8
CMP r0, r9
MOVLT r0, r9
STMIA r2!, {r6-r9}
SUBS r1, r1, #4
BGE celt_pitch_xcorr_edsp_process4
celt_pitch_xcorr_edsp_process2
ADDS r1, r1, #2
BLT celt_pitch_xcorr_edsp_process1a
SUBS r12, r3, #4
; {r10, r11} = {sum0, sum1} = {0, 0}
MOV r10, #0
MOV r11, #0
LDR r8, [r5], #4
BLE celt_pitch_xcorr_edsp_process2_loop_done
LDR r6, [r4], #4
LDR r9, [r5], #4
celt_pitch_xcorr_edsp_process2_loop4
SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0)
LDR r7, [r4], #4
SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1)
SUBS r12, r12, #4 ; j-=4
SMLATT r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_1, y_1)
LDR r8, [r5], #4
SMLATB r11, r6, r9, r11 ; sum1 = MAC16_16(sum1, x_1, y_2)
LDRGT r6, [r4], #4
SMLABB r10, r7, r9, r10 ; sum0 = MAC16_16(sum0, x_2, y_2)
SMLABT r11, r7, r9, r11 ; sum1 = MAC16_16(sum1, x_2, y_3)
SMLATT r10, r7, r9, r10 ; sum0 = MAC16_16(sum0, x_3, y_3)
LDRGT r9, [r5], #4
SMLATB r11, r7, r8, r11 ; sum1 = MAC16_16(sum1, x_3, y_4)
BGT celt_pitch_xcorr_edsp_process2_loop4
celt_pitch_xcorr_edsp_process2_loop_done
ADDS r12, r12, #2
BLE celt_pitch_xcorr_edsp_process2_1
LDR r6, [r4], #4
; Stall
SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0)
LDR r9, [r5], #4
SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1)
SUB r12, r12, #2
SMLATT r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_1, y_1)
MOV r8, r9
SMLATB r11, r6, r9, r11 ; sum1 = MAC16_16(sum1, x_1, y_2)
celt_pitch_xcorr_edsp_process2_1
LDRH r6, [r4], #2
ADDS r12, r12, #1
; Stall
SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0)
LDRHGT r7, [r4], #2
SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1)
BLE celt_pitch_xcorr_edsp_process2_done
LDRH r9, [r5], #2
SMLABT r10, r7, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_1)
SMLABB r11, r7, r9, r11 ; sum1 = MAC16_16(sum1, x_0, y_2)
celt_pitch_xcorr_edsp_process2_done
; Restore _x
SUB r4, r4, r3, LSL #1
; Restore and advance _y
SUB r5, r5, r3, LSL #1
; maxcorr = max(maxcorr, sum0)
CMP r0, r10
ADD r5, r5, #2
MOVLT r0, r10
SUB r1, r1, #2
; maxcorr = max(maxcorr, sum1)
CMP r0, r11
; xcorr[i] = sum
STR r10, [r2], #4
MOVLT r0, r11
STR r11, [r2], #4
celt_pitch_xcorr_edsp_process1a
ADDS r1, r1, #1
BLT celt_pitch_xcorr_edsp_done
SUBS r12, r3, #4
; r14 = sum = 0
MOV r14, #0
BLT celt_pitch_xcorr_edsp_process1a_loop_done
LDR r6, [r4], #4
LDR r8, [r5], #4
LDR r7, [r4], #4
LDR r9, [r5], #4
celt_pitch_xcorr_edsp_process1a_loop4
SMLABB r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0)
SUBS r12, r12, #4 ; j-=4
SMLATT r14, r6, r8, r14 ; sum = MAC16_16(sum, x_1, y_1)
LDRGE r6, [r4], #4
SMLABB r14, r7, r9, r14 ; sum = MAC16_16(sum, x_2, y_2)
LDRGE r8, [r5], #4
SMLATT r14, r7, r9, r14 ; sum = MAC16_16(sum, x_3, y_3)
LDRGE r7, [r4], #4
LDRGE r9, [r5], #4
BGE celt_pitch_xcorr_edsp_process1a_loop4
celt_pitch_xcorr_edsp_process1a_loop_done
ADDS r12, r12, #2
LDRGE r6, [r4], #4
LDRGE r8, [r5], #4
; Stall
SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0)
SUBGE r12, r12, #2
SMLATTGE r14, r6, r8, r14 ; sum = MAC16_16(sum, x_1, y_1)
ADDS r12, r12, #1
LDRHGE r6, [r4], #2
LDRHGE r8, [r5], #2
; Stall
SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, *x, *y)
; maxcorr = max(maxcorr, sum)
CMP r0, r14
; xcorr[i] = sum
STR r14, [r2], #4
MOVLT r0, r14
celt_pitch_xcorr_edsp_done
LDMFD sp!, {r4-r11, pc}
ENDP
ENDIF
END

View file

@ -0,0 +1,71 @@
/* Copyright (c) 2015 Xiph.Org Foundation
Written by Viswanath Puttagunta */
/**
@file fft_arm.h
@brief ARM Neon Intrinsic optimizations for fft using NE10 library
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(FFT_ARM_H)
#define FFT_ARM_H
#include "kiss_fft.h"
#if defined(HAVE_ARM_NE10)
int opus_fft_alloc_arm_neon(kiss_fft_state *st);
void opus_fft_free_arm_neon(kiss_fft_state *st);
void opus_fft_neon(const kiss_fft_state *st,
const kiss_fft_cpx *fin,
kiss_fft_cpx *fout);
void opus_ifft_neon(const kiss_fft_state *st,
const kiss_fft_cpx *fin,
kiss_fft_cpx *fout);
#if !defined(OPUS_HAVE_RTCD)
#define OVERRIDE_OPUS_FFT (1)
#define opus_fft_alloc_arch(_st, arch) \
((void)(arch), opus_fft_alloc_arm_neon(_st))
#define opus_fft_free_arch(_st, arch) \
((void)(arch), opus_fft_free_arm_neon(_st))
#define opus_fft(_st, _fin, _fout, arch) \
((void)(arch), opus_fft_neon(_st, _fin, _fout))
#define opus_ifft(_st, _fin, _fout, arch) \
((void)(arch), opus_ifft_neon(_st, _fin, _fout))
#endif /* OPUS_HAVE_RTCD */
#endif /* HAVE_ARM_NE10 */
#endif

View file

@ -0,0 +1,35 @@
/* Copyright (C) 2015 Vidyo */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_ARM64_H
#define FIXED_ARM64_H
#include <arm_neon.h>
#undef SIG2WORD16
#define SIG2WORD16(x) (vqmovns_s32(PSHR32((x), SIG_SHIFT)))
#endif

View file

@ -0,0 +1,80 @@
/* Copyright (C) 2013 Xiph.Org Foundation and contributors */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_ARMv4_H
#define FIXED_ARMv4_H
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
#undef MULT16_32_Q16
static OPUS_INLINE opus_val32 MULT16_32_Q16_armv4(opus_val16 a, opus_val32 b)
{
unsigned rd_lo;
int rd_hi;
__asm__(
"#MULT16_32_Q16\n\t"
"smull %0, %1, %2, %3\n\t"
: "=&r"(rd_lo), "=&r"(rd_hi)
: "%r"(b),"r"(SHL32(a,16))
);
return rd_hi;
}
#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv4(a, b))
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
#undef MULT16_32_Q15
static OPUS_INLINE opus_val32 MULT16_32_Q15_armv4(opus_val16 a, opus_val32 b)
{
unsigned rd_lo;
int rd_hi;
__asm__(
"#MULT16_32_Q15\n\t"
"smull %0, %1, %2, %3\n\t"
: "=&r"(rd_lo), "=&r"(rd_hi)
: "%r"(b), "r"(SHL32(a,16))
);
/*We intentionally don't OR in the high bit of rd_lo for speed.*/
return SHL32(rd_hi,1);
}
#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv4(a, b))
/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.
b must fit in 31 bits.
Result fits in 32 bits. */
#undef MAC16_32_Q15
#define MAC16_32_Q15(c, a, b) ADD32(c, MULT16_32_Q15(a, b))
/** 16x32 multiply, followed by a 16-bit shift right and 32-bit add.
Result fits in 32 bits. */
#undef MAC16_32_Q16
#define MAC16_32_Q16(c, a, b) ADD32(c, MULT16_32_Q16(a, b))
/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */
#undef MULT32_32_Q31
#define MULT32_32_Q31(a,b) (opus_val32)((((opus_int64)(a)) * ((opus_int64)(b)))>>31)
#endif

View file

@ -0,0 +1,151 @@
/* Copyright (C) 2007-2009 Xiph.Org Foundation
Copyright (C) 2003-2008 Jean-Marc Valin
Copyright (C) 2007-2008 CSIRO
Copyright (C) 2013 Parrot */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_ARMv5E_H
#define FIXED_ARMv5E_H
#include "fixed_armv4.h"
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
#undef MULT16_32_Q16
static OPUS_INLINE opus_val32 MULT16_32_Q16_armv5e(opus_val16 a, opus_val32 b)
{
int res;
__asm__(
"#MULT16_32_Q16\n\t"
"smulwb %0, %1, %2\n\t"
: "=r"(res)
: "r"(b),"r"(a)
);
return res;
}
#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv5e(a, b))
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
#undef MULT16_32_Q15
static OPUS_INLINE opus_val32 MULT16_32_Q15_armv5e(opus_val16 a, opus_val32 b)
{
int res;
__asm__(
"#MULT16_32_Q15\n\t"
"smulwb %0, %1, %2\n\t"
: "=r"(res)
: "r"(b), "r"(a)
);
return SHL32(res,1);
}
#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b))
/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.
b must fit in 31 bits.
Result fits in 32 bits. */
#undef MAC16_32_Q15
static OPUS_INLINE opus_val32 MAC16_32_Q15_armv5e(opus_val32 c, opus_val16 a,
opus_val32 b)
{
int res;
__asm__(
"#MAC16_32_Q15\n\t"
"smlawb %0, %1, %2, %3;\n"
: "=r"(res)
: "r"(SHL32(b,1)), "r"(a), "r"(c)
);
return res;
}
#define MAC16_32_Q15(c, a, b) (MAC16_32_Q15_armv5e(c, a, b))
/** 16x32 multiply, followed by a 16-bit shift right and 32-bit add.
Result fits in 32 bits. */
#undef MAC16_32_Q16
static OPUS_INLINE opus_val32 MAC16_32_Q16_armv5e(opus_val32 c, opus_val16 a,
opus_val32 b)
{
int res;
__asm__(
"#MAC16_32_Q16\n\t"
"smlawb %0, %1, %2, %3;\n"
: "=r"(res)
: "r"(b), "r"(a), "r"(c)
);
return res;
}
#define MAC16_32_Q16(c, a, b) (MAC16_32_Q16_armv5e(c, a, b))
/** 16x16 multiply-add where the result fits in 32 bits */
#undef MAC16_16
static OPUS_INLINE opus_val32 MAC16_16_armv5e(opus_val32 c, opus_val16 a,
opus_val16 b)
{
int res;
__asm__(
"#MAC16_16\n\t"
"smlabb %0, %1, %2, %3;\n"
: "=r"(res)
: "r"(a), "r"(b), "r"(c)
);
return res;
}
#define MAC16_16(c, a, b) (MAC16_16_armv5e(c, a, b))
/** 16x16 multiplication where the result fits in 32 bits */
#undef MULT16_16
static OPUS_INLINE opus_val32 MULT16_16_armv5e(opus_val16 a, opus_val16 b)
{
int res;
__asm__(
"#MULT16_16\n\t"
"smulbb %0, %1, %2;\n"
: "=r"(res)
: "r"(a), "r"(b)
);
return res;
}
#define MULT16_16(a, b) (MULT16_16_armv5e(a, b))
#ifdef OPUS_ARM_INLINE_MEDIA
#undef SIG2WORD16
static OPUS_INLINE opus_val16 SIG2WORD16_armv6(opus_val32 x)
{
celt_sig res;
__asm__(
"#SIG2WORD16\n\t"
"ssat %0, #16, %1, ASR #12\n\t"
: "=r"(res)
: "r"(x+2048)
);
return EXTRACT16(res);
}
#define SIG2WORD16(x) (SIG2WORD16_armv6(x))
#endif /* OPUS_ARM_INLINE_MEDIA */
#endif

View file

@ -0,0 +1,121 @@
/*Copyright (c) 2013, Xiph.Org Foundation and contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.*/
#ifndef KISS_FFT_ARMv4_H
#define KISS_FFT_ARMv4_H
#if !defined(KISS_FFT_GUTS_H)
#error "This file should only be included from _kiss_fft_guts.h"
#endif
#ifdef FIXED_POINT
#undef C_MUL
#define C_MUL(m,a,b) \
do{ \
int br__; \
int bi__; \
int tt__; \
__asm__ __volatile__( \
"#C_MUL\n\t" \
"ldrsh %[br], [%[bp], #0]\n\t" \
"ldm %[ap], {r0,r1}\n\t" \
"ldrsh %[bi], [%[bp], #2]\n\t" \
"smull %[tt], %[mi], r1, %[br]\n\t" \
"smlal %[tt], %[mi], r0, %[bi]\n\t" \
"rsb %[bi], %[bi], #0\n\t" \
"smull %[br], %[mr], r0, %[br]\n\t" \
"mov %[tt], %[tt], lsr #15\n\t" \
"smlal %[br], %[mr], r1, %[bi]\n\t" \
"orr %[mi], %[tt], %[mi], lsl #17\n\t" \
"mov %[br], %[br], lsr #15\n\t" \
"orr %[mr], %[br], %[mr], lsl #17\n\t" \
: [mr]"=r"((m).r), [mi]"=r"((m).i), \
[br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \
: [ap]"r"(&(a)), [bp]"r"(&(b)) \
: "r0", "r1" \
); \
} \
while(0)
#undef C_MUL4
#define C_MUL4(m,a,b) \
do{ \
int br__; \
int bi__; \
int tt__; \
__asm__ __volatile__( \
"#C_MUL4\n\t" \
"ldrsh %[br], [%[bp], #0]\n\t" \
"ldm %[ap], {r0,r1}\n\t" \
"ldrsh %[bi], [%[bp], #2]\n\t" \
"smull %[tt], %[mi], r1, %[br]\n\t" \
"smlal %[tt], %[mi], r0, %[bi]\n\t" \
"rsb %[bi], %[bi], #0\n\t" \
"smull %[br], %[mr], r0, %[br]\n\t" \
"mov %[tt], %[tt], lsr #17\n\t" \
"smlal %[br], %[mr], r1, %[bi]\n\t" \
"orr %[mi], %[tt], %[mi], lsl #15\n\t" \
"mov %[br], %[br], lsr #17\n\t" \
"orr %[mr], %[br], %[mr], lsl #15\n\t" \
: [mr]"=r"((m).r), [mi]"=r"((m).i), \
[br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \
: [ap]"r"(&(a)), [bp]"r"(&(b)) \
: "r0", "r1" \
); \
} \
while(0)
#undef C_MULC
#define C_MULC(m,a,b) \
do{ \
int br__; \
int bi__; \
int tt__; \
__asm__ __volatile__( \
"#C_MULC\n\t" \
"ldrsh %[br], [%[bp], #0]\n\t" \
"ldm %[ap], {r0,r1}\n\t" \
"ldrsh %[bi], [%[bp], #2]\n\t" \
"smull %[tt], %[mr], r0, %[br]\n\t" \
"smlal %[tt], %[mr], r1, %[bi]\n\t" \
"rsb %[bi], %[bi], #0\n\t" \
"smull %[br], %[mi], r1, %[br]\n\t" \
"mov %[tt], %[tt], lsr #15\n\t" \
"smlal %[br], %[mi], r0, %[bi]\n\t" \
"orr %[mr], %[tt], %[mr], lsl #17\n\t" \
"mov %[br], %[br], lsr #15\n\t" \
"orr %[mi], %[br], %[mi], lsl #17\n\t" \
: [mr]"=r"((m).r), [mi]"=r"((m).i), \
[br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \
: [ap]"r"(&(a)), [bp]"r"(&(b)) \
: "r0", "r1" \
); \
} \
while(0)
#endif /* FIXED_POINT */
#endif /* KISS_FFT_ARMv4_H */

View file

@ -0,0 +1,118 @@
/*Copyright (c) 2013, Xiph.Org Foundation and contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.*/
#ifndef KISS_FFT_ARMv5E_H
#define KISS_FFT_ARMv5E_H
#if !defined(KISS_FFT_GUTS_H)
#error "This file should only be included from _kiss_fft_guts.h"
#endif
#ifdef FIXED_POINT
#if defined(__thumb__)||defined(__thumb2__)
#define LDRD_CONS "Q"
#else
#define LDRD_CONS "Uq"
#endif
#undef C_MUL
#define C_MUL(m,a,b) \
do{ \
int mr1__; \
int mr2__; \
int mi__; \
long long aval__; \
int bval__; \
__asm__( \
"#C_MUL\n\t" \
"ldrd %[aval], %H[aval], %[ap]\n\t" \
"ldr %[bval], %[bp]\n\t" \
"smulwb %[mi], %H[aval], %[bval]\n\t" \
"smulwb %[mr1], %[aval], %[bval]\n\t" \
"smulwt %[mr2], %H[aval], %[bval]\n\t" \
"smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \
: [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \
[aval]"=&r"(aval__), [bval]"=r"(bval__) \
: [ap]LDRD_CONS(a), [bp]"m"(b) \
); \
(m).r = SHL32(SUB32(mr1__, mr2__), 1); \
(m).i = SHL32(mi__, 1); \
} \
while(0)
#undef C_MUL4
#define C_MUL4(m,a,b) \
do{ \
int mr1__; \
int mr2__; \
int mi__; \
long long aval__; \
int bval__; \
__asm__( \
"#C_MUL4\n\t" \
"ldrd %[aval], %H[aval], %[ap]\n\t" \
"ldr %[bval], %[bp]\n\t" \
"smulwb %[mi], %H[aval], %[bval]\n\t" \
"smulwb %[mr1], %[aval], %[bval]\n\t" \
"smulwt %[mr2], %H[aval], %[bval]\n\t" \
"smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \
: [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \
[aval]"=&r"(aval__), [bval]"=r"(bval__) \
: [ap]LDRD_CONS(a), [bp]"m"(b) \
); \
(m).r = SHR32(SUB32(mr1__, mr2__), 1); \
(m).i = SHR32(mi__, 1); \
} \
while(0)
#undef C_MULC
#define C_MULC(m,a,b) \
do{ \
int mr__; \
int mi1__; \
int mi2__; \
long long aval__; \
int bval__; \
__asm__( \
"#C_MULC\n\t" \
"ldrd %[aval], %H[aval], %[ap]\n\t" \
"ldr %[bval], %[bp]\n\t" \
"smulwb %[mr], %[aval], %[bval]\n\t" \
"smulwb %[mi1], %H[aval], %[bval]\n\t" \
"smulwt %[mi2], %[aval], %[bval]\n\t" \
"smlawt %[mr], %H[aval], %[bval], %[mr]\n\t" \
: [mr]"=r"(mr__), [mi1]"=r"(mi1__), [mi2]"=r"(mi2__), \
[aval]"=&r"(aval__), [bval]"=r"(bval__) \
: [ap]LDRD_CONS(a), [bp]"m"(b) \
); \
(m).r = SHL32(mr__, 1); \
(m).i = SHL32(SUB32(mi1__, mi2__), 1); \
} \
while(0)
#endif /* FIXED_POINT */
#endif /* KISS_FFT_GUTS_H */

View file

@ -0,0 +1,59 @@
/* Copyright (c) 2015 Xiph.Org Foundation
Written by Viswanath Puttagunta */
/**
@file arm_mdct.h
@brief ARM Neon Intrinsic optimizations for mdct using NE10 library
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(MDCT_ARM_H)
#define MDCT_ARM_H
#include "mdct.h"
#if defined(HAVE_ARM_NE10)
/** Compute a forward MDCT and scale by 4/N, trashes the input array */
void clt_mdct_forward_neon(const mdct_lookup *l, kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 *window, int overlap,
int shift, int stride, int arch);
void clt_mdct_backward_neon(const mdct_lookup *l, kiss_fft_scalar *in,
kiss_fft_scalar * OPUS_RESTRICT out,
const opus_val16 *window, int overlap,
int shift, int stride, int arch);
#if !defined(OPUS_HAVE_RTCD)
#define OVERRIDE_OPUS_MDCT (1)
#define clt_mdct_forward(_l, _in, _out, _window, _int, _shift, _stride, _arch) \
clt_mdct_forward_neon(_l, _in, _out, _window, _int, _shift, _stride, _arch)
#define clt_mdct_backward(_l, _in, _out, _window, _int, _shift, _stride, _arch) \
clt_mdct_backward_neon(_l, _in, _out, _window, _int, _shift, _stride, _arch)
#endif /* OPUS_HAVE_RTCD */
#endif /* HAVE_ARM_NE10 */
#endif

View file

@ -0,0 +1,160 @@
/* Copyright (c) 2010 Xiph.Org Foundation
* Copyright (c) 2013 Parrot */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(PITCH_ARM_H)
# define PITCH_ARM_H
# include "armcpu.h"
# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N);
void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01,
const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2);
# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
# define OVERRIDE_CELT_INNER_PROD (1)
# define OVERRIDE_DUAL_INNER_PROD (1)
# define celt_inner_prod(x, y, N, arch) ((void)(arch), PRESUME_NEON(celt_inner_prod)(x, y, N))
# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((void)(arch), PRESUME_NEON(dual_inner_prod)(x, y01, y02, N, xy1, xy2))
# endif
# endif
# if !defined(OVERRIDE_CELT_INNER_PROD)
# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
extern opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y, int N);
# define OVERRIDE_CELT_INNER_PROD (1)
# define celt_inner_prod(x, y, N, arch) ((*CELT_INNER_PROD_IMPL[(arch)&OPUS_ARCHMASK])(x, y, N))
# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
# define OVERRIDE_CELT_INNER_PROD (1)
# define celt_inner_prod(x, y, N, arch) ((void)(arch), celt_inner_prod_neon(x, y, N))
# endif
# endif
# if !defined(OVERRIDE_DUAL_INNER_PROD)
# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
extern void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x,
const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2);
# define OVERRIDE_DUAL_INNER_PROD (1)
# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((*DUAL_INNER_PROD_IMPL[(arch)&OPUS_ARCHMASK])(x, y01, y02, N, xy1, xy2))
# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
# define OVERRIDE_DUAL_INNER_PROD (1)
# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((void)(arch), dual_inner_prod_neon(x, y01, y02, N, xy1, xy2))
# endif
# endif
# if defined(FIXED_POINT)
# if defined(OPUS_ARM_MAY_HAVE_NEON)
opus_val32 celt_pitch_xcorr_neon(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch, int arch);
# endif
# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
# define celt_pitch_xcorr_media MAY_HAVE_EDSP(celt_pitch_xcorr)
# endif
# if defined(OPUS_ARM_MAY_HAVE_EDSP)
opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch, int arch);
# endif
# if defined(OPUS_HAVE_RTCD) && \
((defined(OPUS_ARM_MAY_HAVE_NEON) && !defined(OPUS_ARM_PRESUME_NEON)) || \
(defined(OPUS_ARM_MAY_HAVE_MEDIA) && !defined(OPUS_ARM_PRESUME_MEDIA)) || \
(defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP)))
extern opus_val32
(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
const opus_val16 *, opus_val32 *, int, int, int);
# define OVERRIDE_PITCH_XCORR (1)
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
xcorr, len, max_pitch, arch))
# elif defined(OPUS_ARM_PRESUME_EDSP) || \
defined(OPUS_ARM_PRESUME_MEDIA) || \
defined(OPUS_ARM_PRESUME_NEON)
# define OVERRIDE_PITCH_XCORR (1)
# define celt_pitch_xcorr (PRESUME_NEON(celt_pitch_xcorr))
# endif
# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
void xcorr_kernel_neon_fixed(
const opus_val16 *x,
const opus_val16 *y,
opus_val32 sum[4],
int len);
# endif
# if defined(OPUS_HAVE_RTCD) && \
(defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
extern void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
const opus_val16 *x,
const opus_val16 *y,
opus_val32 sum[4],
int len);
# define OVERRIDE_XCORR_KERNEL (1)
# define xcorr_kernel(x, y, sum, len, arch) \
((*XCORR_KERNEL_IMPL[(arch) & OPUS_ARCHMASK])(x, y, sum, len))
# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
# define OVERRIDE_XCORR_KERNEL (1)
# define xcorr_kernel(x, y, sum, len, arch) \
((void)arch, xcorr_kernel_neon_fixed(x, y, sum, len))
# endif
#else /* Start !FIXED_POINT */
/* Float case */
#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch, int arch);
#endif
# if defined(OPUS_HAVE_RTCD) && \
(defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
extern void
(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
const opus_val16 *, opus_val32 *, int, int, int);
# define OVERRIDE_PITCH_XCORR (1)
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
xcorr, len, max_pitch, arch))
# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
# define OVERRIDE_PITCH_XCORR (1)
# define celt_pitch_xcorr celt_pitch_xcorr_float_neon
# endif
#endif /* end !FIXED_POINT */
#endif

View file

@ -0,0 +1,288 @@
/***********************************************************************
Copyright (c) 2017 Google Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Internet Society, IETF or IETF Trust, nor the
names of specific contributors, may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***********************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <arm_neon.h>
#include "pitch.h"
#ifdef FIXED_POINT
opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N)
{
int i;
opus_val32 xy;
int16x8_t x_s16x8, y_s16x8;
int32x4_t xy_s32x4 = vdupq_n_s32(0);
int64x2_t xy_s64x2;
int64x1_t xy_s64x1;
for (i = 0; i < N - 7; i += 8) {
x_s16x8 = vld1q_s16(&x[i]);
y_s16x8 = vld1q_s16(&y[i]);
xy_s32x4 = vmlal_s16(xy_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y_s16x8));
xy_s32x4 = vmlal_s16(xy_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y_s16x8));
}
if (N - i >= 4) {
const int16x4_t x_s16x4 = vld1_s16(&x[i]);
const int16x4_t y_s16x4 = vld1_s16(&y[i]);
xy_s32x4 = vmlal_s16(xy_s32x4, x_s16x4, y_s16x4);
i += 4;
}
xy_s64x2 = vpaddlq_s32(xy_s32x4);
xy_s64x1 = vadd_s64(vget_low_s64(xy_s64x2), vget_high_s64(xy_s64x2));
xy = vget_lane_s32(vreinterpret_s32_s64(xy_s64x1), 0);
for (; i < N; i++) {
xy = MAC16_16(xy, x[i], y[i]);
}
#ifdef OPUS_CHECK_ASM
celt_assert(celt_inner_prod_c(x, y, N) == xy);
#endif
return xy;
}
void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
int N, opus_val32 *xy1, opus_val32 *xy2)
{
int i;
opus_val32 xy01, xy02;
int16x8_t x_s16x8, y01_s16x8, y02_s16x8;
int32x4_t xy01_s32x4 = vdupq_n_s32(0);
int32x4_t xy02_s32x4 = vdupq_n_s32(0);
int64x2_t xy01_s64x2, xy02_s64x2;
int64x1_t xy01_s64x1, xy02_s64x1;
for (i = 0; i < N - 7; i += 8) {
x_s16x8 = vld1q_s16(&x[i]);
y01_s16x8 = vld1q_s16(&y01[i]);
y02_s16x8 = vld1q_s16(&y02[i]);
xy01_s32x4 = vmlal_s16(xy01_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y01_s16x8));
xy02_s32x4 = vmlal_s16(xy02_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y02_s16x8));
xy01_s32x4 = vmlal_s16(xy01_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y01_s16x8));
xy02_s32x4 = vmlal_s16(xy02_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y02_s16x8));
}
if (N - i >= 4) {
const int16x4_t x_s16x4 = vld1_s16(&x[i]);
const int16x4_t y01_s16x4 = vld1_s16(&y01[i]);
const int16x4_t y02_s16x4 = vld1_s16(&y02[i]);
xy01_s32x4 = vmlal_s16(xy01_s32x4, x_s16x4, y01_s16x4);
xy02_s32x4 = vmlal_s16(xy02_s32x4, x_s16x4, y02_s16x4);
i += 4;
}
xy01_s64x2 = vpaddlq_s32(xy01_s32x4);
xy02_s64x2 = vpaddlq_s32(xy02_s32x4);
xy01_s64x1 = vadd_s64(vget_low_s64(xy01_s64x2), vget_high_s64(xy01_s64x2));
xy02_s64x1 = vadd_s64(vget_low_s64(xy02_s64x2), vget_high_s64(xy02_s64x2));
xy01 = vget_lane_s32(vreinterpret_s32_s64(xy01_s64x1), 0);
xy02 = vget_lane_s32(vreinterpret_s32_s64(xy02_s64x1), 0);
for (; i < N; i++) {
xy01 = MAC16_16(xy01, x[i], y01[i]);
xy02 = MAC16_16(xy02, x[i], y02[i]);
}
*xy1 = xy01;
*xy2 = xy02;
#ifdef OPUS_CHECK_ASM
{
opus_val32 xy1_c, xy2_c;
dual_inner_prod_c(x, y01, y02, N, &xy1_c, &xy2_c);
celt_assert(xy1_c == *xy1);
celt_assert(xy2_c == *xy2);
}
#endif
}
#else /* !FIXED_POINT */
/* ========================================================================== */
#ifdef __ARM_FEATURE_FMA
/* If we can, force the compiler to use an FMA instruction rather than break
vmlaq_f32() into fmul/fadd. */
#define vmlaq_f32(a,b,c) vfmaq_f32(a,b,c)
#endif
#ifdef OPUS_CHECK_ASM
/* This part of code simulates floating-point NEON operations. */
/* celt_inner_prod_neon_float_c_simulation() simulates the floating-point */
/* operations of celt_inner_prod_neon(), and both functions should have bit */
/* exact output. */
static opus_val32 celt_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y, float *err, int N)
{
int i;
*err = 0;
opus_val32 xy, xy0 = 0, xy1 = 0, xy2 = 0, xy3 = 0;
for (i = 0; i < N - 3; i += 4) {
xy0 = MAC16_16(xy0, x[i + 0], y[i + 0]);
xy1 = MAC16_16(xy1, x[i + 1], y[i + 1]);
xy2 = MAC16_16(xy2, x[i + 2], y[i + 2]);
xy3 = MAC16_16(xy3, x[i + 3], y[i + 3]);
*err += ABS32(xy0)+ABS32(xy1)+ABS32(xy2)+ABS32(xy3);
}
xy0 += xy2;
xy1 += xy3;
xy = xy0 + xy1;
*err += ABS32(xy1)+ABS32(xy0)+ABS32(xy);
for (; i < N; i++) {
xy = MAC16_16(xy, x[i], y[i]);
*err += ABS32(xy);
}
*err = *err*2e-7 + N*1e-37;
return xy;
}
/* dual_inner_prod_neon_float_c_simulation() simulates the floating-point */
/* operations of dual_inner_prod_neon(), and both functions should have bit */
/* exact output. */
static void dual_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
int N, opus_val32 *xy1, opus_val32 *xy2, float *err)
{
*xy1 = celt_inner_prod_neon_float_c_simulation(x, y01, &err[0], N);
*xy2 = celt_inner_prod_neon_float_c_simulation(x, y02, &err[1], N);
}
#endif /* OPUS_CHECK_ASM */
/* ========================================================================== */
opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N)
{
int i;
opus_val32 xy;
float32x4_t xy_f32x4 = vdupq_n_f32(0);
float32x2_t xy_f32x2;
for (i = 0; i < N - 7; i += 8) {
float32x4_t x_f32x4, y_f32x4;
x_f32x4 = vld1q_f32(&x[i]);
y_f32x4 = vld1q_f32(&y[i]);
xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
x_f32x4 = vld1q_f32(&x[i + 4]);
y_f32x4 = vld1q_f32(&y[i + 4]);
xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
}
if (N - i >= 4) {
const float32x4_t x_f32x4 = vld1q_f32(&x[i]);
const float32x4_t y_f32x4 = vld1q_f32(&y[i]);
xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
i += 4;
}
xy_f32x2 = vadd_f32(vget_low_f32(xy_f32x4), vget_high_f32(xy_f32x4));
xy_f32x2 = vpadd_f32(xy_f32x2, xy_f32x2);
xy = vget_lane_f32(xy_f32x2, 0);
for (; i < N; i++) {
xy = MAC16_16(xy, x[i], y[i]);
}
#ifdef OPUS_CHECK_ASM
{
float err, res;
res = celt_inner_prod_neon_float_c_simulation(x, y, &err, N);
/*if (ABS32(res - xy) > err) fprintf(stderr, "%g %g %g\n", res, xy, err);*/
celt_assert(ABS32(res - xy) <= err);
}
#endif
return xy;
}
void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
int N, opus_val32 *xy1, opus_val32 *xy2)
{
int i;
opus_val32 xy01, xy02;
float32x4_t xy01_f32x4 = vdupq_n_f32(0);
float32x4_t xy02_f32x4 = vdupq_n_f32(0);
float32x2_t xy01_f32x2, xy02_f32x2;
for (i = 0; i < N - 7; i += 8) {
float32x4_t x_f32x4, y01_f32x4, y02_f32x4;
x_f32x4 = vld1q_f32(&x[i]);
y01_f32x4 = vld1q_f32(&y01[i]);
y02_f32x4 = vld1q_f32(&y02[i]);
xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
x_f32x4 = vld1q_f32(&x[i + 4]);
y01_f32x4 = vld1q_f32(&y01[i + 4]);
y02_f32x4 = vld1q_f32(&y02[i + 4]);
xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
}
if (N - i >= 4) {
const float32x4_t x_f32x4 = vld1q_f32(&x[i]);
const float32x4_t y01_f32x4 = vld1q_f32(&y01[i]);
const float32x4_t y02_f32x4 = vld1q_f32(&y02[i]);
xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
i += 4;
}
xy01_f32x2 = vadd_f32(vget_low_f32(xy01_f32x4), vget_high_f32(xy01_f32x4));
xy02_f32x2 = vadd_f32(vget_low_f32(xy02_f32x4), vget_high_f32(xy02_f32x4));
xy01_f32x2 = vpadd_f32(xy01_f32x2, xy01_f32x2);
xy02_f32x2 = vpadd_f32(xy02_f32x2, xy02_f32x2);
xy01 = vget_lane_f32(xy01_f32x2, 0);
xy02 = vget_lane_f32(xy02_f32x2, 0);
for (; i < N; i++) {
xy01 = MAC16_16(xy01, x[i], y01[i]);
xy02 = MAC16_16(xy02, x[i], y02[i]);
}
*xy1 = xy01;
*xy2 = xy02;
#ifdef OPUS_CHECK_ASM
{
opus_val32 xy1_c, xy2_c;
float err[2];
dual_inner_prod_neon_float_c_simulation(x, y01, y02, N, &xy1_c, &xy2_c, err);
/*if (ABS32(xy1_c - *xy1) > err[0]) fprintf(stderr, "dual1 fail: %g %g %g\n", xy1_c, *xy1, err[0]);
if (ABS32(xy2_c - *xy2) > err[1]) fprintf(stderr, "dual2 fail: %g %g %g\n", xy2_c, *xy2, err[1]);*/
celt_assert(ABS32(xy1_c - *xy1) <= err[0]);
celt_assert(ABS32(xy2_c - *xy2) <= err[1]);
}
#endif
}
#endif /* FIXED_POINT */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,123 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Copyright (c) 2008-2009 Gregory Maxwell
Written by Jean-Marc Valin and Gregory Maxwell */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BANDS_H
#define BANDS_H
#include "arch.h"
#include "modes.h"
#include "entenc.h"
#include "entdec.h"
#include "rate.h"
opus_int16 bitexact_cos(opus_int16 x);
int bitexact_log2tan(int isin,int icos);
/** Compute the amplitude (sqrt energy) in each of the bands
* @param m Mode data
* @param X Spectrum
* @param bandE Square root of the energy for each band (returned)
*/
void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch);
/*void compute_noise_energies(const CELTMode *m, const celt_sig *X, const opus_val16 *tonality, celt_ener *bandE);*/
/** Normalise each band of X such that the energy in each band is
equal to 1
* @param m Mode data
* @param X Spectrum (returned normalised)
* @param bandE Square root of the energy for each band
*/
void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M);
/** Denormalise each band of X to restore full amplitude
* @param m Mode data
* @param X Spectrum (returned de-normalised)
* @param bandE Square root of the energy for each band
*/
void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandE, int start,
int end, int M, int downsample, int silence);
#define SPREAD_NONE (0)
#define SPREAD_LIGHT (1)
#define SPREAD_NORMAL (2)
#define SPREAD_AGGRESSIVE (3)
int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
int last_decision, int *hf_average, int *tapset_decision, int update_hf,
int end, int C, int M, const int *spread_weight);
#ifdef MEASURE_NORM_MSE
void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C);
#endif
void haar1(celt_norm *X, int N0, int stride);
/** Quantisation/encoding of the residual spectrum
* @param encode flag that indicates whether we're encoding (1) or decoding (0)
* @param m Mode data
* @param start First band to process
* @param end Last band to process + 1
* @param X Residual (normalised)
* @param Y Residual (normalised) for second channel (or NULL for mono)
* @param collapse_masks Anti-collapse tracking mask
* @param bandE Square root of the energy for each band
* @param pulses Bit allocation (per band) for PVQ
* @param shortBlocks Zero for long blocks, non-zero for short blocks
* @param spread Amount of spreading to use
* @param dual_stereo Zero for MS stereo, non-zero for dual stereo
* @param intensity First band to use intensity stereo
* @param tf_res Time-frequency resolution change
* @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
* @param balance Number of unallocated bits
* @param en Entropy coder state
* @param LM log2() of the number of 2.5 subframes in the frame
* @param codedBands Last band to receive bits + 1
* @param seed Random generator seed
* @param arch Run-time architecture (see opus_select_arch())
*/
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
celt_norm * X, celt_norm * Y, unsigned char *collapse_masks,
const celt_ener *bandE, int *pulses, int shortBlocks, int spread,
int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits,
opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed,
int complexity, int arch, int disable_inv);
void anti_collapse(const CELTMode *m, celt_norm *X_,
unsigned char *collapse_masks, int LM, int C, int size, int start,
int end, const opus_val16 *logE, const opus_val16 *prev1logE,
const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed,
int arch);
opus_uint32 celt_lcg_rand(opus_uint32 seed);
int hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev);
#endif /* BANDS_H */

View file

@ -0,0 +1,316 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2010 Xiph.Org Foundation
Copyright (c) 2008 Gregory Maxwell
Written by Jean-Marc Valin and Gregory Maxwell */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define CELT_C
#include "os_support.h"
#include "mdct.h"
#include <math.h>
#include "celt.h"
#include "pitch.h"
#include "bands.h"
#include "modes.h"
#include "entcode.h"
#include "quant_bands.h"
#include "rate.h"
#include "stack_alloc.h"
#include "mathops.h"
#include "float_cast.h"
#include <stdarg.h>
#include "celt_lpc.h"
#include "vq.h"
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "unknown"
#endif
#if defined(MIPSr1_ASM)
#include "mips/celt_mipsr1.h"
#endif
int resampling_factor(opus_int32 rate)
{
int ret;
switch (rate)
{
case 48000:
ret = 1;
break;
case 24000:
ret = 2;
break;
case 16000:
ret = 3;
break;
case 12000:
ret = 4;
break;
case 8000:
ret = 6;
break;
default:
#ifndef CUSTOM_MODES
celt_assert(0);
#endif
ret = 0;
break;
}
return ret;
}
#if !defined(OVERRIDE_COMB_FILTER_CONST) || defined(NON_STATIC_COMB_FILTER_CONST_C)
/* This version should be faster on ARM */
#ifdef OPUS_ARM_ASM
#ifndef NON_STATIC_COMB_FILTER_CONST_C
static
#endif
void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
opus_val16 g10, opus_val16 g11, opus_val16 g12)
{
opus_val32 x0, x1, x2, x3, x4;
int i;
x4 = SHL32(x[-T-2], 1);
x3 = SHL32(x[-T-1], 1);
x2 = SHL32(x[-T], 1);
x1 = SHL32(x[-T+1], 1);
for (i=0;i<N-4;i+=5)
{
opus_val32 t;
x0=SHL32(x[i-T+2],1);
t = MAC16_32_Q16(x[i], g10, x2);
t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
t = SATURATE(t, SIG_SAT);
y[i] = t;
x4=SHL32(x[i-T+3],1);
t = MAC16_32_Q16(x[i+1], g10, x1);
t = MAC16_32_Q16(t, g11, ADD32(x0,x2));
t = MAC16_32_Q16(t, g12, ADD32(x4,x3));
t = SATURATE(t, SIG_SAT);
y[i+1] = t;
x3=SHL32(x[i-T+4],1);
t = MAC16_32_Q16(x[i+2], g10, x0);
t = MAC16_32_Q16(t, g11, ADD32(x4,x1));
t = MAC16_32_Q16(t, g12, ADD32(x3,x2));
t = SATURATE(t, SIG_SAT);
y[i+2] = t;
x2=SHL32(x[i-T+5],1);
t = MAC16_32_Q16(x[i+3], g10, x4);
t = MAC16_32_Q16(t, g11, ADD32(x3,x0));
t = MAC16_32_Q16(t, g12, ADD32(x2,x1));
t = SATURATE(t, SIG_SAT);
y[i+3] = t;
x1=SHL32(x[i-T+6],1);
t = MAC16_32_Q16(x[i+4], g10, x3);
t = MAC16_32_Q16(t, g11, ADD32(x2,x4));
t = MAC16_32_Q16(t, g12, ADD32(x1,x0));
t = SATURATE(t, SIG_SAT);
y[i+4] = t;
}
#ifdef CUSTOM_MODES
for (;i<N;i++)
{
opus_val32 t;
x0=SHL32(x[i-T+2],1);
t = MAC16_32_Q16(x[i], g10, x2);
t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
t = SATURATE(t, SIG_SAT);
y[i] = t;
x4=x3;
x3=x2;
x2=x1;
x1=x0;
}
#endif
}
#else
#ifndef NON_STATIC_COMB_FILTER_CONST_C
static
#endif
void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
opus_val16 g10, opus_val16 g11, opus_val16 g12)
{
opus_val32 x0, x1, x2, x3, x4;
int i;
x4 = x[-T-2];
x3 = x[-T-1];
x2 = x[-T];
x1 = x[-T+1];
for (i=0;i<N;i++)
{
x0=x[i-T+2];
y[i] = x[i]
+ MULT16_32_Q15(g10,x2)
+ MULT16_32_Q15(g11,ADD32(x1,x3))
+ MULT16_32_Q15(g12,ADD32(x0,x4));
y[i] = SATURATE(y[i], SIG_SAT);
x4=x3;
x3=x2;
x2=x1;
x1=x0;
}
}
#endif
#endif
#ifndef OVERRIDE_comb_filter
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
const opus_val16 *window, int overlap, int arch)
{
int i;
/* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
opus_val16 g00, g01, g02, g10, g11, g12;
opus_val32 x0, x1, x2, x3, x4;
static const opus_val16 gains[3][3] = {
{QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
{QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
{QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
if (g0==0 && g1==0)
{
/* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
if (x!=y)
OPUS_MOVE(y, x, N);
return;
}
/* When the gain is zero, T0 and/or T1 is set to zero. We need
to have then be at least 2 to avoid processing garbage data. */
T0 = IMAX(T0, COMBFILTER_MINPERIOD);
T1 = IMAX(T1, COMBFILTER_MINPERIOD);
g00 = MULT16_16_P15(g0, gains[tapset0][0]);
g01 = MULT16_16_P15(g0, gains[tapset0][1]);
g02 = MULT16_16_P15(g0, gains[tapset0][2]);
g10 = MULT16_16_P15(g1, gains[tapset1][0]);
g11 = MULT16_16_P15(g1, gains[tapset1][1]);
g12 = MULT16_16_P15(g1, gains[tapset1][2]);
x1 = x[-T1+1];
x2 = x[-T1 ];
x3 = x[-T1-1];
x4 = x[-T1-2];
/* If the filter didn't change, we don't need the overlap */
if (g0==g1 && T0==T1 && tapset0==tapset1)
overlap=0;
for (i=0;i<overlap;i++)
{
opus_val16 f;
x0=x[i-T1+2];
f = MULT16_16_Q15(window[i],window[i]);
y[i] = x[i]
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
+ MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)
+ MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))
+ MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));
y[i] = SATURATE(y[i], SIG_SAT);
x4=x3;
x3=x2;
x2=x1;
x1=x0;
}
if (g1==0)
{
/* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
if (x!=y)
OPUS_MOVE(y+overlap, x+overlap, N-overlap);
return;
}
/* Compute the part with the constant filter. */
comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
}
#endif /* OVERRIDE_comb_filter */
/* TF change table. Positive values mean better frequency resolution (longer
effective window), whereas negative values mean better time resolution
(shorter effective window). The second index is computed as:
4*isTransient + 2*tf_select + per_band_flag */
const signed char tf_select_table[4][8] = {
/*isTransient=0 isTransient=1 */
{0, -1, 0, -1, 0,-1, 0,-1}, /* 2.5 ms */
{0, -1, 0, -2, 1, 0, 1,-1}, /* 5 ms */
{0, -2, 0, -3, 2, 0, 1,-1}, /* 10 ms */
{0, -2, 0, -3, 3, 0, 1,-1}, /* 20 ms */
};
void init_caps(const CELTMode *m,int *cap,int LM,int C)
{
int i;
for (i=0;i<m->nbEBands;i++)
{
int N;
N=(m->eBands[i+1]-m->eBands[i])<<LM;
cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
}
}
const char *opus_strerror(int error)
{
static const char * const error_strings[8] = {
"success",
"invalid argument",
"buffer too small",
"internal error",
"corrupted stream",
"request not implemented",
"invalid state",
"memory allocation failed"
};
if (error > 0 || error < -7)
return "unknown error";
else
return error_strings[-error];
}
const char *opus_get_version_string(void)
{
return "libopus " PACKAGE_VERSION
/* Applications may rely on the presence of this substring in the version
string to determine if they have a fixed-point or floating-point build
at runtime. */
#ifdef FIXED_POINT
"-fixed"
#endif
#ifdef FUZZING
"-fuzzing"
#endif
;
}

View file

@ -0,0 +1,252 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Copyright (c) 2008 Gregory Maxwell
Written by Jean-Marc Valin and Gregory Maxwell */
/**
@file celt.h
@brief Contains all the functions for encoding and decoding audio
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CELT_H
#define CELT_H
#include "opus_types.h"
#include "opus_defines.h"
#include "opus_custom.h"
#include "entenc.h"
#include "entdec.h"
#include "arch.h"
#ifdef ENABLE_DEEP_PLC
#include "lpcnet.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define CELTEncoder OpusCustomEncoder
#define CELTDecoder OpusCustomDecoder
#define CELTMode OpusCustomMode
#define LEAK_BANDS 19
typedef struct {
int valid;
float tonality;
float tonality_slope;
float noisiness;
float activity;
float music_prob;
float music_prob_min;
float music_prob_max;
int bandwidth;
float activity_probability;
float max_pitch_ratio;
/* Store as Q6 char to save space. */
unsigned char leak_boost[LEAK_BANDS];
} AnalysisInfo;
typedef struct {
int signalType;
int offset;
} SILKInfo;
#define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
#define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr)))
#define __celt_check_silkinfo_ptr(ptr) ((ptr) + ((ptr) - (const SILKInfo*)(ptr)))
/* Encoder/decoder Requests */
#define CELT_SET_PREDICTION_REQUEST 10002
/** Controls the use of interframe prediction.
0=Independent frames
1=Short term interframe prediction allowed
2=Long term prediction allowed
*/
#define CELT_SET_PREDICTION(x) CELT_SET_PREDICTION_REQUEST, __opus_check_int(x)
#define CELT_SET_INPUT_CLIPPING_REQUEST 10004
#define CELT_SET_INPUT_CLIPPING(x) CELT_SET_INPUT_CLIPPING_REQUEST, __opus_check_int(x)
#define CELT_GET_AND_CLEAR_ERROR_REQUEST 10007
#define CELT_GET_AND_CLEAR_ERROR(x) CELT_GET_AND_CLEAR_ERROR_REQUEST, __opus_check_int_ptr(x)
#define CELT_SET_CHANNELS_REQUEST 10008
#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, __opus_check_int(x)
/* Internal */
#define CELT_SET_START_BAND_REQUEST 10010
#define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, __opus_check_int(x)
#define CELT_SET_END_BAND_REQUEST 10012
#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, __opus_check_int(x)
#define CELT_GET_MODE_REQUEST 10015
/** Get the CELTMode used by an encoder or decoder */
#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, __celt_check_mode_ptr_ptr(x)
#define CELT_SET_SIGNALLING_REQUEST 10016
#define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x)
#define CELT_SET_TONALITY_REQUEST 10018
#define CELT_SET_TONALITY(x) CELT_SET_TONALITY_REQUEST, __opus_check_int(x)
#define CELT_SET_TONALITY_SLOPE_REQUEST 10020
#define CELT_SET_TONALITY_SLOPE(x) CELT_SET_TONALITY_SLOPE_REQUEST, __opus_check_int(x)
#define CELT_SET_ANALYSIS_REQUEST 10022
#define CELT_SET_ANALYSIS(x) CELT_SET_ANALYSIS_REQUEST, __celt_check_analysis_ptr(x)
#define OPUS_SET_LFE_REQUEST 10024
#define OPUS_SET_LFE(x) OPUS_SET_LFE_REQUEST, __opus_check_int(x)
#define OPUS_SET_ENERGY_MASK_REQUEST 10026
#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x)
#define CELT_SET_SILK_INFO_REQUEST 10028
#define CELT_SET_SILK_INFO(x) CELT_SET_SILK_INFO_REQUEST, __celt_check_silkinfo_ptr(x)
/* Encoder stuff */
int celt_encoder_get_size(int channels);
int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc);
int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels,
int arch);
/* Decoder stuff */
int celt_decoder_get_size(int channels);
int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels);
int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data,
int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum
#ifdef ENABLE_DEEP_PLC
,LPCNetPLCState *lpcnet
#endif
);
int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data,
int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum);
#define celt_encoder_ctl opus_custom_encoder_ctl
#define celt_decoder_ctl opus_custom_decoder_ctl
#ifdef CUSTOM_MODES
#define OPUS_CUSTOM_NOSTATIC
#else
#define OPUS_CUSTOM_NOSTATIC static OPUS_INLINE
#endif
static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0};
/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
static const unsigned char spread_icdf[4] = {25, 23, 2, 0};
static const unsigned char tapset_icdf[3]={2,1,0};
#ifdef CUSTOM_MODES
static const unsigned char toOpusTable[20] = {
0xE0, 0xE8, 0xF0, 0xF8,
0xC0, 0xC8, 0xD0, 0xD8,
0xA0, 0xA8, 0xB0, 0xB8,
0x00, 0x00, 0x00, 0x00,
0x80, 0x88, 0x90, 0x98,
};
static const unsigned char fromOpusTable[16] = {
0x80, 0x88, 0x90, 0x98,
0x40, 0x48, 0x50, 0x58,
0x20, 0x28, 0x30, 0x38,
0x00, 0x08, 0x10, 0x18
};
static OPUS_INLINE int toOpus(unsigned char c)
{
int ret=0;
if (c<0xA0)
ret = toOpusTable[c>>3];
if (ret == 0)
return -1;
else
return ret|(c&0x7);
}
static OPUS_INLINE int fromOpus(unsigned char c)
{
if (c<0x80)
return -1;
else
return fromOpusTable[(c>>3)-16] | (c&0x7);
}
#endif /* CUSTOM_MODES */
#define COMBFILTER_MAXPERIOD 1024
#define COMBFILTER_MINPERIOD 15
extern const signed char tf_select_table[4][8];
#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
void validate_celt_decoder(CELTDecoder *st);
#define VALIDATE_CELT_DECODER(st) validate_celt_decoder(st)
#else
#define VALIDATE_CELT_DECODER(st)
#endif
int resampling_factor(opus_int32 rate);
void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip);
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
const opus_val16 *window, int overlap, int arch);
void init_caps(const CELTMode *m,int *cap,int LM,int C);
#ifdef RESYNTH
void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, int accum);
void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
opus_val16 *oldBandE, int start, int effEnd, int C, int CC, int isTransient,
int LM, int downsample, int silence, int arch);
#endif
#ifdef __cplusplus
}
#endif
#endif /* CELT_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,363 @@
/* Copyright (c) 2009-2010 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "celt_lpc.h"
#include "stack_alloc.h"
#include "mathops.h"
#include "pitch.h"
void _celt_lpc(
opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */
const opus_val32 *ac, /* in: [0...p] autocorrelation values */
int p
)
{
int i, j;
opus_val32 r;
opus_val32 error = ac[0];
#ifdef FIXED_POINT
opus_val32 lpc[CELT_LPC_ORDER];
#else
float *lpc = _lpc;
#endif
OPUS_CLEAR(lpc, p);
#ifdef FIXED_POINT
if (ac[0] != 0)
#else
if (ac[0] > 1e-10f)
#endif
{
for (i = 0; i < p; i++) {
/* Sum up this iteration's reflection coefficient */
opus_val32 rr = 0;
for (j = 0; j < i; j++)
rr += MULT32_32_Q31(lpc[j],ac[i - j]);
rr += SHR32(ac[i + 1],6);
r = -frac_div32(SHL32(rr,6), error);
/* Update LPC coefficients and total error */
lpc[i] = SHR32(r,6);
for (j = 0; j < (i+1)>>1; j++)
{
opus_val32 tmp1, tmp2;
tmp1 = lpc[j];
tmp2 = lpc[i-1-j];
lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2);
lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
}
error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
/* Bail out once we get 30 dB gain */
#ifdef FIXED_POINT
if (error<=SHR32(ac[0],10))
break;
#else
if (error<=.001f*ac[0])
break;
#endif
}
}
#ifdef FIXED_POINT
{
/* Convert the int32 lpcs to int16 and ensure there are no wrap-arounds.
This reuses the logic in silk_LPC_fit() and silk_bwexpander_32(). Any bug
fixes should also be applied there. */
int iter, idx = 0;
opus_val32 maxabs, absval, chirp_Q16, chirp_minus_one_Q16;
for (iter = 0; iter < 10; iter++) {
maxabs = 0;
for (i = 0; i < p; i++) {
absval = ABS32(lpc[i]);
if (absval > maxabs) {
maxabs = absval;
idx = i;
}
}
maxabs = PSHR32(maxabs, 13); /* Q25->Q12 */
if (maxabs > 32767) {
maxabs = MIN32(maxabs, 163838);
chirp_Q16 = QCONST32(0.999, 16) - DIV32(SHL32(maxabs - 32767, 14),
SHR32(MULT32_32_32(maxabs, idx + 1), 2));
chirp_minus_one_Q16 = chirp_Q16 - 65536;
/* Apply bandwidth expansion. */
for (i = 0; i < p - 1; i++) {
lpc[i] = MULT32_32_Q16(chirp_Q16, lpc[i]);
chirp_Q16 += PSHR32(MULT32_32_32(chirp_Q16, chirp_minus_one_Q16), 16);
}
lpc[p - 1] = MULT32_32_Q16(chirp_Q16, lpc[p - 1]);
} else {
break;
}
}
if (iter == 10) {
/* If the coeffs still do not fit into the 16 bit range after 10 iterations,
fall back to the A(z)=1 filter. */
OPUS_CLEAR(lpc, p);
_lpc[0] = 4096; /* Q12 */
} else {
for (i = 0; i < p; i++) {
_lpc[i] = EXTRACT16(PSHR32(lpc[i], 13)); /* Q25->Q12 */
}
}
}
#endif
}
void celt_fir_c(
const opus_val16 *x,
const opus_val16 *num,
opus_val16 *y,
int N,
int ord,
int arch)
{
int i,j;
VARDECL(opus_val16, rnum);
SAVE_STACK;
celt_assert(x != y);
ALLOC(rnum, ord, opus_val16);
for(i=0;i<ord;i++)
rnum[i] = num[ord-i-1];
for (i=0;i<N-3;i+=4)
{
opus_val32 sum[4];
sum[0] = SHL32(EXTEND32(x[i ]), SIG_SHIFT);
sum[1] = SHL32(EXTEND32(x[i+1]), SIG_SHIFT);
sum[2] = SHL32(EXTEND32(x[i+2]), SIG_SHIFT);
sum[3] = SHL32(EXTEND32(x[i+3]), SIG_SHIFT);
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
{
opus_val32 sum_c[4];
memcpy(sum_c, sum, sizeof(sum_c));
xcorr_kernel_c(rnum, x+i-ord, sum_c, ord);
#endif
xcorr_kernel(rnum, x+i-ord, sum, ord, arch);
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
celt_assert(memcmp(sum, sum_c, sizeof(sum)) == 0);
}
#endif
y[i ] = SROUND16(sum[0], SIG_SHIFT);
y[i+1] = SROUND16(sum[1], SIG_SHIFT);
y[i+2] = SROUND16(sum[2], SIG_SHIFT);
y[i+3] = SROUND16(sum[3], SIG_SHIFT);
}
for (;i<N;i++)
{
opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
for (j=0;j<ord;j++)
sum = MAC16_16(sum,rnum[j],x[i+j-ord]);
y[i] = SROUND16(sum, SIG_SHIFT);
}
RESTORE_STACK;
}
void celt_iir(const opus_val32 *_x,
const opus_val16 *den,
opus_val32 *_y,
int N,
int ord,
opus_val16 *mem,
int arch)
{
#ifdef SMALL_FOOTPRINT
int i,j;
(void)arch;
for (i=0;i<N;i++)
{
opus_val32 sum = _x[i];
for (j=0;j<ord;j++)
{
sum -= MULT16_16(den[j],mem[j]);
}
for (j=ord-1;j>=1;j--)
{
mem[j]=mem[j-1];
}
mem[0] = SROUND16(sum, SIG_SHIFT);
_y[i] = sum;
}
#else
int i,j;
VARDECL(opus_val16, rden);
VARDECL(opus_val16, y);
SAVE_STACK;
celt_assert((ord&3)==0);
ALLOC(rden, ord, opus_val16);
ALLOC(y, N+ord, opus_val16);
for(i=0;i<ord;i++)
rden[i] = den[ord-i-1];
for(i=0;i<ord;i++)
y[i] = -mem[ord-i-1];
for(;i<N+ord;i++)
y[i]=0;
for (i=0;i<N-3;i+=4)
{
/* Unroll by 4 as if it were an FIR filter */
opus_val32 sum[4];
sum[0]=_x[i];
sum[1]=_x[i+1];
sum[2]=_x[i+2];
sum[3]=_x[i+3];
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
{
opus_val32 sum_c[4];
memcpy(sum_c, sum, sizeof(sum_c));
xcorr_kernel_c(rden, y+i, sum_c, ord);
#endif
xcorr_kernel(rden, y+i, sum, ord, arch);
#if defined(OPUS_CHECK_ASM) && defined(FIXED_POINT)
celt_assert(memcmp(sum, sum_c, sizeof(sum)) == 0);
}
#endif
/* Patch up the result to compensate for the fact that this is an IIR */
y[i+ord ] = -SROUND16(sum[0],SIG_SHIFT);
_y[i ] = sum[0];
sum[1] = MAC16_16(sum[1], y[i+ord ], den[0]);
y[i+ord+1] = -SROUND16(sum[1],SIG_SHIFT);
_y[i+1] = sum[1];
sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
sum[2] = MAC16_16(sum[2], y[i+ord ], den[1]);
y[i+ord+2] = -SROUND16(sum[2],SIG_SHIFT);
_y[i+2] = sum[2];
sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
sum[3] = MAC16_16(sum[3], y[i+ord ], den[2]);
y[i+ord+3] = -SROUND16(sum[3],SIG_SHIFT);
_y[i+3] = sum[3];
}
for (;i<N;i++)
{
opus_val32 sum = _x[i];
for (j=0;j<ord;j++)
sum -= MULT16_16(rden[j],y[i+j]);
y[i+ord] = SROUND16(sum,SIG_SHIFT);
_y[i] = sum;
}
for(i=0;i<ord;i++)
mem[i] = _y[N-i-1];
RESTORE_STACK;
#endif
}
int _celt_autocorr(
const opus_val16 *x, /* in: [0...n-1] samples x */
opus_val32 *ac, /* out: [0...lag-1] ac values */
const opus_val16 *window,
int overlap,
int lag,
int n,
int arch
)
{
opus_val32 d;
int i, k;
int fastN=n-lag;
int shift;
const opus_val16 *xptr;
VARDECL(opus_val16, xx);
SAVE_STACK;
ALLOC(xx, n, opus_val16);
celt_assert(n>0);
celt_assert(overlap>=0);
if (overlap == 0)
{
xptr = x;
} else {
for (i=0;i<n;i++)
xx[i] = x[i];
for (i=0;i<overlap;i++)
{
xx[i] = MULT16_16_Q15(x[i],window[i]);
xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
}
xptr = xx;
}
shift=0;
#ifdef FIXED_POINT
{
opus_val32 ac0;
ac0 = 1+(n<<7);
if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),9);
for(i=(n&1);i<n;i+=2)
{
ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),9);
ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),9);
}
shift = celt_ilog2(ac0)-30+10;
shift = (shift)/2;
if (shift>0)
{
for(i=0;i<n;i++)
xx[i] = PSHR32(xptr[i], shift);
xptr = xx;
} else
shift = 0;
}
#endif
celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1, arch);
for (k=0;k<=lag;k++)
{
for (i = k+fastN, d = 0; i < n; i++)
d = MAC16_16(d, xptr[i], xptr[i-k]);
ac[k] += d;
}
#ifdef FIXED_POINT
shift = 2*shift;
if (shift<=0)
ac[0] += SHL32((opus_int32)1, -shift);
if (ac[0] < 268435456)
{
int shift2 = 29 - EC_ILOG(ac[0]);
for (i=0;i<=lag;i++)
ac[i] = SHL32(ac[i], shift2);
shift -= shift2;
} else if (ac[0] >= 536870912)
{
int shift2=1;
if (ac[0] >= 1073741824)
shift2++;
for (i=0;i<=lag;i++)
ac[i] = SHR32(ac[i], shift2);
shift += shift2;
}
#endif
RESTORE_STACK;
return shift;
}

View file

@ -0,0 +1,66 @@
/* Copyright (c) 2009-2010 Xiph.Org Foundation
Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PLC_H
#define PLC_H
#include "arch.h"
#include "cpu_support.h"
#if defined(OPUS_X86_MAY_HAVE_SSE4_1)
#include "x86/celt_lpc_sse.h"
#endif
#define CELT_LPC_ORDER 24
void _celt_lpc(opus_val16 *_lpc, const opus_val32 *ac, int p);
void celt_fir_c(
const opus_val16 *x,
const opus_val16 *num,
opus_val16 *y,
int N,
int ord,
int arch);
#if !defined(OVERRIDE_CELT_FIR)
#define celt_fir(x, num, y, N, ord, arch) \
(celt_fir_c(x, num, y, N, ord, arch))
#endif
void celt_iir(const opus_val32 *x,
const opus_val16 *den,
opus_val32 *y,
int N,
int ord,
opus_val16 *mem,
int arch);
int _celt_autocorr(const opus_val16 *x, opus_val32 *ac,
const opus_val16 *window, int overlap, int lag, int n, int arch);
#endif /* PLC_H */

View file

@ -0,0 +1,72 @@
/* Copyright (c) 2010 Xiph.Org Foundation
* Copyright (c) 2013 Parrot */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CPU_SUPPORT_H
#define CPU_SUPPORT_H
#include "opus_types.h"
#include "opus_defines.h"
#if defined(OPUS_HAVE_RTCD) && \
(defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
#include "arm/armcpu.h"
/* We currently support 5 ARM variants:
* arch[0] -> ARMv4
* arch[1] -> ARMv5E
* arch[2] -> ARMv6
* arch[3] -> NEON
* arch[4] -> NEON+DOTPROD
*/
#define OPUS_ARCHMASK 7
#elif defined(OPUS_HAVE_RTCD) && \
((defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \
(defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)) || \
(defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \
(defined(OPUS_X86_MAY_HAVE_AVX2) && !defined(OPUS_X86_PRESUME_AVX2)))
#include "x86/x86cpu.h"
/* We currently support 5 x86 variants:
* arch[0] -> non-sse
* arch[1] -> sse
* arch[2] -> sse2
* arch[3] -> sse4.1
* arch[4] -> avx
*/
#define OPUS_ARCHMASK 7
int opus_select_arch(void);
#else
#define OPUS_ARCHMASK 0
static OPUS_INLINE int opus_select_arch(void)
{
return 0;
}
#endif
#endif

View file

@ -0,0 +1,715 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Copyright (c) 2007-2009 Timothy B. Terriberry
Written by Timothy B. Terriberry and Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "os_support.h"
#include "cwrs.h"
#include "mathops.h"
#include "arch.h"
#ifdef CUSTOM_MODES
/*Guaranteed to return a conservatively large estimate of the binary logarithm
with frac bits of fractional precision.
Tested for all possible 32-bit inputs with frac=4, where the maximum
overestimation is 0.06254243 bits.*/
int log2_frac(opus_uint32 val, int frac)
{
int l;
l=EC_ILOG(val);
if(val&(val-1)){
/*This is (val>>l-16), but guaranteed to round up, even if adding a bias
before the shift would cause overflow (e.g., for 0xFFFFxxxx).
Doesn't work for val=0, but that case fails the test above.*/
if(l>16)val=((val-1)>>(l-16))+1;
else val<<=16-l;
l=(l-1)<<frac;
/*Note that we always need one iteration, since the rounding up above means
that we might need to adjust the integer part of the logarithm.*/
do{
int b;
b=(int)(val>>16);
l+=b<<frac;
val=(val+b)>>b;
val=(val*val+0x7FFF)>>15;
}
while(frac-->0);
/*If val is not exactly 0x8000, then we have to round up the remainder.*/
return l+(val>0x8000);
}
/*Exact powers of two require no rounding.*/
else return (l-1)<<frac;
}
#endif
/*Although derived separately, the pulse vector coding scheme is equivalent to
a Pyramid Vector Quantizer \cite{Fis86}.
Some additional notes about an early version appear at
https://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering
and the definitions of some terms have evolved since that was written.
The conversion from a pulse vector to an integer index (encoding) and back
(decoding) is governed by two related functions, V(N,K) and U(N,K).
V(N,K) = the number of combinations, with replacement, of N items, taken K
at a time, when a sign bit is added to each item taken at least once (i.e.,
the number of N-dimensional unit pulse vectors with K pulses).
One way to compute this is via
V(N,K) = K>0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1,
where choose() is the binomial function.
A table of values for N<10 and K<10 looks like:
V[10][10] = {
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{1, 4, 8, 12, 16, 20, 24, 28, 32, 36},
{1, 6, 18, 38, 66, 102, 146, 198, 258, 326},
{1, 8, 32, 88, 192, 360, 608, 952, 1408, 1992},
{1, 10, 50, 170, 450, 1002, 1970, 3530, 5890, 9290},
{1, 12, 72, 292, 912, 2364, 5336, 10836, 20256, 35436},
{1, 14, 98, 462, 1666, 4942, 12642, 28814, 59906, 115598},
{1, 16, 128, 688, 2816, 9424, 27008, 68464, 157184, 332688},
{1, 18, 162, 978, 4482, 16722, 53154, 148626, 374274, 864146}
};
U(N,K) = the number of such combinations wherein N-1 objects are taken at
most K-1 at a time.
This is given by
U(N,K) = sum(k=0...K-1,V(N-1,k))
= K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0.
The latter expression also makes clear that U(N,K) is half the number of such
combinations wherein the first object is taken at least once.
Although it may not be clear from either of these definitions, U(N,K) is the
natural function to work with when enumerating the pulse vector codebooks,
not V(N,K).
U(N,K) is not well-defined for N=0, but with the extension
U(0,K) = K>0 ? 0 : 1,
the function becomes symmetric: U(N,K) = U(K,N), with a similar table:
U[10][10] = {
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 1, 3, 5, 7, 9, 11, 13, 15, 17},
{0, 1, 5, 13, 25, 41, 61, 85, 113, 145},
{0, 1, 7, 25, 63, 129, 231, 377, 575, 833},
{0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649},
{0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073},
{0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081},
{0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545},
{0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729}
};
With this extension, V(N,K) may be written in terms of U(N,K):
V(N,K) = U(N,K) + U(N,K+1)
for all N>=0, K>=0.
Thus U(N,K+1) represents the number of combinations where the first element
is positive or zero, and U(N,K) represents the number of combinations where
it is negative.
With a large enough table of U(N,K) values, we could write O(N) encoding
and O(min(N*log(K),N+K)) decoding routines, but such a table would be
prohibitively large for small embedded devices (K may be as large as 32767
for small N, and N may be as large as 200).
Both functions obey the same recurrence relation:
V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1),
U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1),
for all N>0, K>0, with different initial conditions at N=0 or K=0.
This allows us to construct a row of one of the tables above given the
previous row or the next row.
Thus we can derive O(NK) encoding and decoding routines with O(K) memory
using only addition and subtraction.
When encoding, we build up from the U(2,K) row and work our way forwards.
When decoding, we need to start at the U(N,K) row and work our way backwards,
which requires a means of computing U(N,K).
U(N,K) may be computed from two previous values with the same N:
U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2)
for all N>1, and since U(N,K) is symmetric, a similar relation holds for two
previous values with the same K:
U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K)
for all K>1.
This allows us to construct an arbitrary row of the U(N,K) table by starting
with the first two values, which are constants.
This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K)
multiplications.
Similar relations can be derived for V(N,K), but are not used here.
For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree
polynomial for fixed N.
The first few are
U(1,K) = 1,
U(2,K) = 2*K-1,
U(3,K) = (2*K-2)*K+1,
U(4,K) = (((4*K-6)*K+8)*K-3)/3,
U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3,
and
V(1,K) = 2,
V(2,K) = 4*K,
V(3,K) = 4*K*K+2,
V(4,K) = 8*(K*K+2)*K/3,
V(5,K) = ((4*K*K+20)*K*K+6)/3,
for all K>0.
This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for
small N (and indeed decoding is also O(N) for N<3).
@ARTICLE{Fis86,
author="Thomas R. Fischer",
title="A Pyramid Vector Quantizer",
journal="IEEE Transactions on Information Theory",
volume="IT-32",
number=4,
pages="568--583",
month=Jul,
year=1986
}*/
#if !defined(SMALL_FOOTPRINT)
/*U(N,K) = U(K,N) := N>0?K>0?U(N-1,K)+U(N,K-1)+U(N-1,K-1):0:K>0?1:0*/
# define CELT_PVQ_U(_n,_k) (CELT_PVQ_U_ROW[IMIN(_n,_k)][IMAX(_n,_k)])
/*V(N,K) := U(N,K)+U(N,K+1) = the number of PVQ codewords for a band of size N
with K pulses allocated to it.*/
# define CELT_PVQ_V(_n,_k) (CELT_PVQ_U(_n,_k)+CELT_PVQ_U(_n,(_k)+1))
/*For each V(N,K) supported, we will access element U(min(N,K+1),max(N,K+1)).
Thus, the number of entries in row I is the larger of the maximum number of
pulses we will ever allocate for a given N=I (K=128, or however many fit in
32 bits, whichever is smaller), plus one, and the maximum N for which
K=I-1 pulses fit in 32 bits.
The largest band size in an Opus Custom mode is 208.
Otherwise, we can limit things to the set of N which can be achieved by
splitting a band from a standard Opus mode: 176, 144, 96, 88, 72, 64, 48,
44, 36, 32, 24, 22, 18, 16, 8, 4, 2).*/
#if defined(CUSTOM_MODES)
static const opus_uint32 CELT_PVQ_U_DATA[1488]={
#else
static const opus_uint32 CELT_PVQ_U_DATA[1272]={
#endif
/*N=0, K=0...176:*/
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#if defined(CUSTOM_MODES)
/*...208:*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
#endif
/*N=1, K=1...176:*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#if defined(CUSTOM_MODES)
/*...208:*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1,
#endif
/*N=2, K=2...176:*/
3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41,
43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79,
81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113,
115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143,
145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173,
175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203,
205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233,
235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263,
265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293,
295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323,
325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351,
#if defined(CUSTOM_MODES)
/*...208:*/
353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381,
383, 385, 387, 389, 391, 393, 395, 397, 399, 401, 403, 405, 407, 409, 411,
413, 415,
#endif
/*N=3, K=3...176:*/
13, 25, 41, 61, 85, 113, 145, 181, 221, 265, 313, 365, 421, 481, 545, 613,
685, 761, 841, 925, 1013, 1105, 1201, 1301, 1405, 1513, 1625, 1741, 1861,
1985, 2113, 2245, 2381, 2521, 2665, 2813, 2965, 3121, 3281, 3445, 3613, 3785,
3961, 4141, 4325, 4513, 4705, 4901, 5101, 5305, 5513, 5725, 5941, 6161, 6385,
6613, 6845, 7081, 7321, 7565, 7813, 8065, 8321, 8581, 8845, 9113, 9385, 9661,
9941, 10225, 10513, 10805, 11101, 11401, 11705, 12013, 12325, 12641, 12961,
13285, 13613, 13945, 14281, 14621, 14965, 15313, 15665, 16021, 16381, 16745,
17113, 17485, 17861, 18241, 18625, 19013, 19405, 19801, 20201, 20605, 21013,
21425, 21841, 22261, 22685, 23113, 23545, 23981, 24421, 24865, 25313, 25765,
26221, 26681, 27145, 27613, 28085, 28561, 29041, 29525, 30013, 30505, 31001,
31501, 32005, 32513, 33025, 33541, 34061, 34585, 35113, 35645, 36181, 36721,
37265, 37813, 38365, 38921, 39481, 40045, 40613, 41185, 41761, 42341, 42925,
43513, 44105, 44701, 45301, 45905, 46513, 47125, 47741, 48361, 48985, 49613,
50245, 50881, 51521, 52165, 52813, 53465, 54121, 54781, 55445, 56113, 56785,
57461, 58141, 58825, 59513, 60205, 60901, 61601,
#if defined(CUSTOM_MODES)
/*...208:*/
62305, 63013, 63725, 64441, 65161, 65885, 66613, 67345, 68081, 68821, 69565,
70313, 71065, 71821, 72581, 73345, 74113, 74885, 75661, 76441, 77225, 78013,
78805, 79601, 80401, 81205, 82013, 82825, 83641, 84461, 85285, 86113,
#endif
/*N=4, K=4...176:*/
63, 129, 231, 377, 575, 833, 1159, 1561, 2047, 2625, 3303, 4089, 4991, 6017,
7175, 8473, 9919, 11521, 13287, 15225, 17343, 19649, 22151, 24857, 27775,
30913, 34279, 37881, 41727, 45825, 50183, 54809, 59711, 64897, 70375, 76153,
82239, 88641, 95367, 102425, 109823, 117569, 125671, 134137, 142975, 152193,
161799, 171801, 182207, 193025, 204263, 215929, 228031, 240577, 253575,
267033, 280959, 295361, 310247, 325625, 341503, 357889, 374791, 392217,
410175, 428673, 447719, 467321, 487487, 508225, 529543, 551449, 573951,
597057, 620775, 645113, 670079, 695681, 721927, 748825, 776383, 804609,
833511, 863097, 893375, 924353, 956039, 988441, 1021567, 1055425, 1090023,
1125369, 1161471, 1198337, 1235975, 1274393, 1313599, 1353601, 1394407,
1436025, 1478463, 1521729, 1565831, 1610777, 1656575, 1703233, 1750759,
1799161, 1848447, 1898625, 1949703, 2001689, 2054591, 2108417, 2163175,
2218873, 2275519, 2333121, 2391687, 2451225, 2511743, 2573249, 2635751,
2699257, 2763775, 2829313, 2895879, 2963481, 3032127, 3101825, 3172583,
3244409, 3317311, 3391297, 3466375, 3542553, 3619839, 3698241, 3777767,
3858425, 3940223, 4023169, 4107271, 4192537, 4278975, 4366593, 4455399,
4545401, 4636607, 4729025, 4822663, 4917529, 5013631, 5110977, 5209575,
5309433, 5410559, 5512961, 5616647, 5721625, 5827903, 5935489, 6044391,
6154617, 6266175, 6379073, 6493319, 6608921, 6725887, 6844225, 6963943,
7085049, 7207551,
#if defined(CUSTOM_MODES)
/*...208:*/
7331457, 7456775, 7583513, 7711679, 7841281, 7972327, 8104825, 8238783,
8374209, 8511111, 8649497, 8789375, 8930753, 9073639, 9218041, 9363967,
9511425, 9660423, 9810969, 9963071, 10116737, 10271975, 10428793, 10587199,
10747201, 10908807, 11072025, 11236863, 11403329, 11571431, 11741177,
11912575,
#endif
/*N=5, K=5...176:*/
321, 681, 1289, 2241, 3649, 5641, 8361, 11969, 16641, 22569, 29961, 39041,
50049, 63241, 78889, 97281, 118721, 143529, 172041, 204609, 241601, 283401,
330409, 383041, 441729, 506921, 579081, 658689, 746241, 842249, 947241,
1061761, 1186369, 1321641, 1468169, 1626561, 1797441, 1981449, 2179241,
2391489, 2618881, 2862121, 3121929, 3399041, 3694209, 4008201, 4341801,
4695809, 5071041, 5468329, 5888521, 6332481, 6801089, 7295241, 7815849,
8363841, 8940161, 9545769, 10181641, 10848769, 11548161, 12280841, 13047849,
13850241, 14689089, 15565481, 16480521, 17435329, 18431041, 19468809,
20549801, 21675201, 22846209, 24064041, 25329929, 26645121, 28010881,
29428489, 30899241, 32424449, 34005441, 35643561, 37340169, 39096641,
40914369, 42794761, 44739241, 46749249, 48826241, 50971689, 53187081,
55473921, 57833729, 60268041, 62778409, 65366401, 68033601, 70781609,
73612041, 76526529, 79526721, 82614281, 85790889, 89058241, 92418049,
95872041, 99421961, 103069569, 106816641, 110664969, 114616361, 118672641,
122835649, 127107241, 131489289, 135983681, 140592321, 145317129, 150160041,
155123009, 160208001, 165417001, 170752009, 176215041, 181808129, 187533321,
193392681, 199388289, 205522241, 211796649, 218213641, 224775361, 231483969,
238341641, 245350569, 252512961, 259831041, 267307049, 274943241, 282741889,
290705281, 298835721, 307135529, 315607041, 324252609, 333074601, 342075401,
351257409, 360623041, 370174729, 379914921, 389846081, 399970689, 410291241,
420810249, 431530241, 442453761, 453583369, 464921641, 476471169, 488234561,
500214441, 512413449, 524834241, 537479489, 550351881, 563454121, 576788929,
590359041, 604167209, 618216201, 632508801,
#if defined(CUSTOM_MODES)
/*...208:*/
647047809, 661836041, 676876329, 692171521, 707724481, 723538089, 739615241,
755958849, 772571841, 789457161, 806617769, 824056641, 841776769, 859781161,
878072841, 896654849, 915530241, 934702089, 954173481, 973947521, 994027329,
1014416041, 1035116809, 1056132801, 1077467201, 1099123209, 1121104041,
1143412929, 1166053121, 1189027881, 1212340489, 1235994241,
#endif
/*N=6, K=6...96:*/
1683, 3653, 7183, 13073, 22363, 36365, 56695, 85305, 124515, 177045, 246047,
335137, 448427, 590557, 766727, 982729, 1244979, 1560549, 1937199, 2383409,
2908411, 3522221, 4235671, 5060441, 6009091, 7095093, 8332863, 9737793,
11326283, 13115773, 15124775, 17372905, 19880915, 22670725, 25765455,
29189457, 32968347, 37129037, 41699767, 46710137, 52191139, 58175189,
64696159, 71789409, 79491819, 87841821, 96879431, 106646281, 117185651,
128542501, 140763503, 153897073, 167993403, 183104493, 199284183, 216588185,
235074115, 254801525, 275831935, 298228865, 322057867, 347386557, 374284647,
402823977, 433078547, 465124549, 499040399, 534906769, 572806619, 612825229,
655050231, 699571641, 746481891, 795875861, 847850911, 902506913, 959946283,
1020274013, 1083597703, 1150027593, 1219676595, 1292660325, 1369097135,
1449108145, 1532817275, 1620351277, 1711839767, 1807415257, 1907213187,
2011371957, 2120032959,
#if defined(CUSTOM_MODES)
/*...109:*/
2233340609U, 2351442379U, 2474488829U, 2602633639U, 2736033641U, 2874848851U,
3019242501U, 3169381071U, 3325434321U, 3487575323U, 3655980493U, 3830829623U,
4012305913U,
#endif
/*N=7, K=7...54*/
8989, 19825, 40081, 75517, 134245, 227305, 369305, 579125, 880685, 1303777,
1884961, 2668525, 3707509, 5064793, 6814249, 9041957, 11847485, 15345233,
19665841, 24957661, 31388293, 39146185, 48442297, 59511829, 72616013,
88043969, 106114625, 127178701, 151620757, 179861305, 212358985, 249612805,
292164445, 340600625, 395555537, 457713341, 527810725, 606639529, 695049433,
793950709, 904317037, 1027188385, 1163673953, 1314955181, 1482288821,
1667010073, 1870535785, 2094367717,
#if defined(CUSTOM_MODES)
/*...60:*/
2340095869U, 2609401873U, 2904062449U, 3225952925U, 3577050821U, 3959439497U,
#endif
/*N=8, K=8...37*/
48639, 108545, 224143, 433905, 795455, 1392065, 2340495, 3800305, 5984767,
9173505, 13726991, 20103025, 28875327, 40754369, 56610575, 77500017,
104692735, 139703809, 184327311, 240673265, 311207743, 398796225, 506750351,
638878193, 799538175, 993696769, 1226990095, 1505789553, 1837271615,
2229491905U,
#if defined(CUSTOM_MODES)
/*...40:*/
2691463695U, 3233240945U, 3866006015U,
#endif
/*N=9, K=9...28:*/
265729, 598417, 1256465, 2485825, 4673345, 8405905, 14546705, 24331777,
39490049, 62390545, 96220561, 145198913, 214828609, 312193553, 446304145,
628496897, 872893441, 1196924561, 1621925137, 2173806145U,
#if defined(CUSTOM_MODES)
/*...29:*/
2883810113U,
#endif
/*N=10, K=10...24:*/
1462563, 3317445, 7059735, 14218905, 27298155, 50250765, 89129247, 152951073,
254831667, 413442773, 654862247, 1014889769, 1541911931, 2300409629U,
3375210671U,
/*N=11, K=11...19:*/
8097453, 18474633, 39753273, 81270333, 158819253, 298199265, 540279585,
948062325, 1616336765,
#if defined(CUSTOM_MODES)
/*...20:*/
2684641785U,
#endif
/*N=12, K=12...18:*/
45046719, 103274625, 224298231, 464387817, 921406335, 1759885185,
3248227095U,
/*N=13, K=13...16:*/
251595969, 579168825, 1267854873, 2653649025U,
/*N=14, K=14:*/
1409933619
};
#if defined(CUSTOM_MODES)
static const opus_uint32 *const CELT_PVQ_U_ROW[15]={
CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 208,CELT_PVQ_U_DATA+ 415,
CELT_PVQ_U_DATA+ 621,CELT_PVQ_U_DATA+ 826,CELT_PVQ_U_DATA+1030,
CELT_PVQ_U_DATA+1233,CELT_PVQ_U_DATA+1336,CELT_PVQ_U_DATA+1389,
CELT_PVQ_U_DATA+1421,CELT_PVQ_U_DATA+1441,CELT_PVQ_U_DATA+1455,
CELT_PVQ_U_DATA+1464,CELT_PVQ_U_DATA+1470,CELT_PVQ_U_DATA+1473
};
#else
static const opus_uint32 *const CELT_PVQ_U_ROW[15]={
CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 176,CELT_PVQ_U_DATA+ 351,
CELT_PVQ_U_DATA+ 525,CELT_PVQ_U_DATA+ 698,CELT_PVQ_U_DATA+ 870,
CELT_PVQ_U_DATA+1041,CELT_PVQ_U_DATA+1131,CELT_PVQ_U_DATA+1178,
CELT_PVQ_U_DATA+1207,CELT_PVQ_U_DATA+1226,CELT_PVQ_U_DATA+1240,
CELT_PVQ_U_DATA+1248,CELT_PVQ_U_DATA+1254,CELT_PVQ_U_DATA+1257
};
#endif
#if defined(CUSTOM_MODES)
void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){
int k;
/*_maxk==0 => there's nothing to do.*/
celt_assert(_maxk>0);
_bits[0]=0;
for(k=1;k<=_maxk;k++)_bits[k]=log2_frac(CELT_PVQ_V(_n,k),_frac);
}
#endif
static opus_uint32 icwrs(int _n,const int *_y){
opus_uint32 i;
int j;
int k;
celt_assert(_n>=2);
j=_n-1;
i=_y[j]<0;
k=abs(_y[j]);
do{
j--;
i+=CELT_PVQ_U(_n-j,k);
k+=abs(_y[j]);
if(_y[j]<0)i+=CELT_PVQ_U(_n-j,k+1);
}
while(j>0);
return i;
}
void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){
celt_assert(_k>0);
ec_enc_uint(_enc,icwrs(_n,_y),CELT_PVQ_V(_n,_k));
}
static opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y){
opus_uint32 p;
int s;
int k0;
opus_int16 val;
opus_val32 yy=0;
celt_assert(_k>0);
celt_assert(_n>1);
while(_n>2){
opus_uint32 q;
/*Lots of pulses case:*/
if(_k>=_n){
const opus_uint32 *row;
row=CELT_PVQ_U_ROW[_n];
/*Are the pulses in this dimension negative?*/
p=row[_k+1];
s=-(_i>=p);
_i-=p&s;
/*Count how many pulses were placed in this dimension.*/
k0=_k;
q=row[_n];
if(q>_i){
celt_sig_assert(p>q);
_k=_n;
do p=CELT_PVQ_U_ROW[--_k][_n];
while(p>_i);
}
else for(p=row[_k];p>_i;p=row[_k])_k--;
_i-=p;
val=(k0-_k+s)^s;
*_y++=val;
yy=MAC16_16(yy,val,val);
}
/*Lots of dimensions case:*/
else{
/*Are there any pulses in this dimension at all?*/
p=CELT_PVQ_U_ROW[_k][_n];
q=CELT_PVQ_U_ROW[_k+1][_n];
if(p<=_i&&_i<q){
_i-=p;
*_y++=0;
}
else{
/*Are the pulses in this dimension negative?*/
s=-(_i>=q);
_i-=q&s;
/*Count how many pulses were placed in this dimension.*/
k0=_k;
do p=CELT_PVQ_U_ROW[--_k][_n];
while(p>_i);
_i-=p;
val=(k0-_k+s)^s;
*_y++=val;
yy=MAC16_16(yy,val,val);
}
}
_n--;
}
/*_n==2*/
p=2*_k+1;
s=-(_i>=p);
_i-=p&s;
k0=_k;
_k=(_i+1)>>1;
if(_k)_i-=2*_k-1;
val=(k0-_k+s)^s;
*_y++=val;
yy=MAC16_16(yy,val,val);
/*_n==1*/
s=-(int)_i;
val=(_k+s)^s;
*_y=val;
yy=MAC16_16(yy,val,val);
return yy;
}
opus_val32 decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){
return cwrsi(_n,_k,ec_dec_uint(_dec,CELT_PVQ_V(_n,_k)),_y);
}
#else /* SMALL_FOOTPRINT */
/*Computes the next row/column of any recurrence that obeys the relation
u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1].
_ui0 is the base case for the new row/column.*/
static OPUS_INLINE void unext(opus_uint32 *_ui,unsigned _len,opus_uint32 _ui0){
opus_uint32 ui1;
unsigned j;
/*This do-while will overrun the array if we don't have storage for at least
2 values.*/
j=1; do {
ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0);
_ui[j-1]=_ui0;
_ui0=ui1;
} while (++j<_len);
_ui[j-1]=_ui0;
}
/*Computes the previous row/column of any recurrence that obeys the relation
u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1].
_ui0 is the base case for the new row/column.*/
static OPUS_INLINE void uprev(opus_uint32 *_ui,unsigned _n,opus_uint32 _ui0){
opus_uint32 ui1;
unsigned j;
/*This do-while will overrun the array if we don't have storage for at least
2 values.*/
j=1; do {
ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0);
_ui[j-1]=_ui0;
_ui0=ui1;
} while (++j<_n);
_ui[j-1]=_ui0;
}
/*Compute V(_n,_k), as well as U(_n,0..._k+1).
_u: On exit, _u[i] contains U(_n,i) for i in [0..._k+1].*/
static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){
opus_uint32 um2;
unsigned len;
unsigned k;
len=_k+2;
/*We require storage at least 3 values (e.g., _k>0).*/
celt_assert(len>=3);
_u[0]=0;
_u[1]=um2=1;
/*If _n==0, _u[0] should be 1 and the rest should be 0.*/
/*If _n==1, _u[i] should be 1 for i>1.*/
celt_assert(_n>=2);
/*If _k==0, the following do-while loop will overflow the buffer.*/
celt_assert(_k>0);
k=2;
do _u[k]=(k<<1)-1;
while(++k<len);
for(k=2;k<_n;k++)unext(_u+1,_k+1,1);
return _u[_k]+_u[_k+1];
}
/*Returns the _i'th combination of _k elements chosen from a set of size _n
with associated sign bits.
_y: Returns the vector of pulses.
_u: Must contain entries [0..._k+1] of row _n of U() on input.
Its contents will be destructively modified.*/
static opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y,opus_uint32 *_u){
int j;
opus_int16 val;
opus_val32 yy=0;
celt_assert(_n>0);
j=0;
do{
opus_uint32 p;
int s;
int yj;
p=_u[_k+1];
s=-(_i>=p);
_i-=p&s;
yj=_k;
p=_u[_k];
while(p>_i)p=_u[--_k];
_i-=p;
yj-=_k;
val=(yj+s)^s;
_y[j]=val;
yy=MAC16_16(yy,val,val);
uprev(_u,_k+2,0);
}
while(++j<_n);
return yy;
}
/*Returns the index of the given combination of K elements chosen from a set
of size 1 with associated sign bits.
_y: The vector of pulses, whose sum of absolute values is K.
_k: Returns K.*/
static OPUS_INLINE opus_uint32 icwrs1(const int *_y,int *_k){
*_k=abs(_y[0]);
return _y[0]<0;
}
/*Returns the index of the given combination of K elements chosen from a set
of size _n with associated sign bits.
_y: The vector of pulses, whose sum of absolute values must be _k.
_nc: Returns V(_n,_k).*/
static OPUS_INLINE opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y,
opus_uint32 *_u){
opus_uint32 i;
int j;
int k;
/*We can't unroll the first two iterations of the loop unless _n>=2.*/
celt_assert(_n>=2);
_u[0]=0;
for(k=1;k<=_k+1;k++)_u[k]=(k<<1)-1;
i=icwrs1(_y+_n-1,&k);
j=_n-2;
i+=_u[k];
k+=abs(_y[j]);
if(_y[j]<0)i+=_u[k+1];
while(j-->0){
unext(_u,_k+2,0);
i+=_u[k];
k+=abs(_y[j]);
if(_y[j]<0)i+=_u[k+1];
}
*_nc=_u[k]+_u[k+1];
return i;
}
#ifdef CUSTOM_MODES
void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){
int k;
/*_maxk==0 => there's nothing to do.*/
celt_assert(_maxk>0);
_bits[0]=0;
if (_n==1)
{
for (k=1;k<=_maxk;k++)
_bits[k] = 1<<_frac;
}
else {
VARDECL(opus_uint32,u);
SAVE_STACK;
ALLOC(u,_maxk+2U,opus_uint32);
ncwrs_urow(_n,_maxk,u);
for(k=1;k<=_maxk;k++)
_bits[k]=log2_frac(u[k]+u[k+1],_frac);
RESTORE_STACK;
}
}
#endif /* CUSTOM_MODES */
void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){
opus_uint32 i;
VARDECL(opus_uint32,u);
opus_uint32 nc;
SAVE_STACK;
celt_assert(_k>0);
ALLOC(u,_k+2U,opus_uint32);
i=icwrs(_n,_k,&nc,_y,u);
ec_enc_uint(_enc,i,nc);
RESTORE_STACK;
}
opus_val32 decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){
VARDECL(opus_uint32,u);
int ret;
SAVE_STACK;
celt_assert(_k>0);
ALLOC(u,_k+2U,opus_uint32);
ret = cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u);
RESTORE_STACK;
return ret;
}
#endif /* SMALL_FOOTPRINT */

View file

@ -0,0 +1,48 @@
/* Copyright (c) 2007-2008 CSIRO
Copyright (c) 2007-2009 Xiph.Org Foundation
Copyright (c) 2007-2009 Timothy B. Terriberry
Written by Timothy B. Terriberry and Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CWRS_H
#define CWRS_H
#include "arch.h"
#include "stack_alloc.h"
#include "entenc.h"
#include "entdec.h"
#ifdef CUSTOM_MODES
int log2_frac(opus_uint32 val, int frac);
#endif
void get_required_bits(opus_int16 *bits, int N, int K, int frac);
void encode_pulses(const int *_y, int N, int K, ec_enc *enc);
opus_val32 decode_pulses(int *_y, int N, int K, ec_dec *dec);
#endif /* CWRS_H */

View file

@ -0,0 +1,91 @@
/* Copyright (c) 2003-2008 Timothy B. Terriberry
Copyright (c) 2008 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*Some common macros for potential platform-specific optimization.*/
#include "opus_types.h"
#include <math.h>
#include <limits.h>
#include "arch.h"
#if !defined(_ecintrin_H)
# define _ecintrin_H (1)
/*Some specific platforms may have optimized intrinsic or OPUS_INLINE assembly
versions of these functions which can substantially improve performance.
We define macros for them to allow easy incorporation of these non-ANSI
features.*/
/*Modern gcc (4.x) can compile the naive versions of min and max with cmov if
given an appropriate architecture, but the branchless bit-twiddling versions
are just as fast, and do not require any special target architecture.
Earlier gcc versions (3.x) compiled both code to the same assembly
instructions, because of the way they represented ((_b)>(_a)) internally.*/
# define EC_MINI(_a,_b) ((_a)+(((_b)-(_a))&-((_b)<(_a))))
/*Count leading zeros.
This macro should only be used for implementing ec_ilog(), if it is defined.
All other code should use EC_ILOG() instead.*/
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
#if defined(_MSC_VER) && (_MSC_VER >= 1910)
# include <intrin0.h> /* Improve compiler throughput. */
#else
# include <intrin.h>
#endif
/*In _DEBUG mode this is not an intrinsic by default.*/
# pragma intrinsic(_BitScanReverse)
static __inline int ec_bsr(unsigned long _x){
unsigned long ret;
_BitScanReverse(&ret,_x);
return (int)ret;
}
# define EC_CLZ0 (1)
# define EC_CLZ(_x) (-ec_bsr(_x))
#elif defined(ENABLE_TI_DSPLIB)
# include "dsplib.h"
# define EC_CLZ0 (31)
# define EC_CLZ(_x) (_lnorm(_x))
#elif __GNUC_PREREQ(3,4)
# if INT_MAX>=2147483647
# define EC_CLZ0 ((int)sizeof(unsigned)*CHAR_BIT)
# define EC_CLZ(_x) (__builtin_clz(_x))
# elif LONG_MAX>=2147483647L
# define EC_CLZ0 ((int)sizeof(unsigned long)*CHAR_BIT)
# define EC_CLZ(_x) (__builtin_clzl(_x))
# endif
#endif
#if defined(EC_CLZ)
/*Note that __builtin_clz is not defined when _x==0, according to the gcc
documentation (and that of the BSR instruction that implements it on x86).
The majority of the time we can never pass it zero.
When we need to, it can be special cased.*/
# define EC_ILOG(_x) (EC_CLZ0-EC_CLZ(_x))
#else
int ec_ilog(opus_uint32 _v);
# define EC_ILOG(_x) (ec_ilog(_x))
#endif
#endif

View file

@ -0,0 +1,153 @@
/* Copyright (c) 2001-2011 Timothy B. Terriberry
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "entcode.h"
#include "arch.h"
#if !defined(EC_CLZ)
/*This is a fallback for systems where we don't know how to access
a BSR or CLZ instruction (see ecintrin.h).
If you are optimizing Opus on a new platform and it has a native CLZ or
BZR (e.g. cell, MIPS, x86, etc) then making it available to Opus will be
an easy performance win.*/
int ec_ilog(opus_uint32 _v){
/*On a Pentium M, this branchless version tested as the fastest on
1,000,000,000 random 32-bit integers, edging out a similar version with
branches, and a 256-entry LUT version.*/
int ret;
int m;
ret=!!_v;
m=!!(_v&0xFFFF0000)<<4;
_v>>=m;
ret|=m;
m=!!(_v&0xFF00)<<3;
_v>>=m;
ret|=m;
m=!!(_v&0xF0)<<2;
_v>>=m;
ret|=m;
m=!!(_v&0xC)<<1;
_v>>=m;
ret|=m;
ret+=!!(_v&0x2);
return ret;
}
#endif
#if 1
/* This is a faster version of ec_tell_frac() that takes advantage
of the low (1/8 bit) resolution to use just a linear function
followed by a lookup to determine the exact transition thresholds. */
opus_uint32 ec_tell_frac(ec_ctx *_this){
static const unsigned correction[8] =
{35733, 38967, 42495, 46340,
50535, 55109, 60097, 65535};
opus_uint32 nbits;
opus_uint32 r;
int l;
unsigned b;
nbits=_this->nbits_total<<BITRES;
l=EC_ILOG(_this->rng);
r=_this->rng>>(l-16);
b = (r>>12)-8;
b += r>correction[b];
l = (l<<3)+b;
return nbits-l;
}
#else
opus_uint32 ec_tell_frac(ec_ctx *_this){
opus_uint32 nbits;
opus_uint32 r;
int l;
int i;
/*To handle the non-integral number of bits still left in the encoder/decoder
state, we compute the worst-case number of bits of val that must be
encoded to ensure that the value is inside the range for any possible
subsequent bits.
The computation here is independent of val itself (the decoder does not
even track that value), even though the real number of bits used after
ec_enc_done() may be 1 smaller if rng is a power of two and the
corresponding trailing bits of val are all zeros.
If we did try to track that special case, then coding a value with a
probability of 1/(1<<n) might sometimes appear to use more than n bits.
This may help explain the surprising result that a newly initialized
encoder or decoder claims to have used 1 bit.*/
nbits=_this->nbits_total<<BITRES;
l=EC_ILOG(_this->rng);
r=_this->rng>>(l-16);
for(i=BITRES;i-->0;){
int b;
r=r*r>>15;
b=(int)(r>>16);
l=l<<1|b;
r>>=b;
}
return nbits-l;
}
#endif
#ifdef USE_SMALL_DIV_TABLE
/* Result of 2^32/(2*i+1), except for i=0. */
const opus_uint32 SMALL_DIV_TABLE[129] = {
0xFFFFFFFF, 0x55555555, 0x33333333, 0x24924924,
0x1C71C71C, 0x1745D174, 0x13B13B13, 0x11111111,
0x0F0F0F0F, 0x0D79435E, 0x0C30C30C, 0x0B21642C,
0x0A3D70A3, 0x097B425E, 0x08D3DCB0, 0x08421084,
0x07C1F07C, 0x07507507, 0x06EB3E45, 0x06906906,
0x063E7063, 0x05F417D0, 0x05B05B05, 0x0572620A,
0x05397829, 0x05050505, 0x04D4873E, 0x04A7904A,
0x047DC11F, 0x0456C797, 0x04325C53, 0x04104104,
0x03F03F03, 0x03D22635, 0x03B5CC0E, 0x039B0AD1,
0x0381C0E0, 0x0369D036, 0x03531DEC, 0x033D91D2,
0x0329161F, 0x03159721, 0x03030303, 0x02F14990,
0x02E05C0B, 0x02D02D02, 0x02C0B02C, 0x02B1DA46,
0x02A3A0FD, 0x0295FAD4, 0x0288DF0C, 0x027C4597,
0x02702702, 0x02647C69, 0x02593F69, 0x024E6A17,
0x0243F6F0, 0x0239E0D5, 0x02302302, 0x0226B902,
0x021D9EAD, 0x0214D021, 0x020C49BA, 0x02040810,
0x01FC07F0, 0x01F44659, 0x01ECC07B, 0x01E573AC,
0x01DE5D6E, 0x01D77B65, 0x01D0CB58, 0x01CA4B30,
0x01C3F8F0, 0x01BDD2B8, 0x01B7D6C3, 0x01B20364,
0x01AC5701, 0x01A6D01A, 0x01A16D3F, 0x019C2D14,
0x01970E4F, 0x01920FB4, 0x018D3018, 0x01886E5F,
0x0183C977, 0x017F405F, 0x017AD220, 0x01767DCE,
0x01724287, 0x016E1F76, 0x016A13CD, 0x01661EC6,
0x01623FA7, 0x015E75BB, 0x015AC056, 0x01571ED3,
0x01539094, 0x01501501, 0x014CAB88, 0x0149539E,
0x01460CBC, 0x0142D662, 0x013FB013, 0x013C995A,
0x013991C2, 0x013698DF, 0x0133AE45, 0x0130D190,
0x012E025C, 0x012B404A, 0x01288B01, 0x0125E227,
0x01234567, 0x0120B470, 0x011E2EF3, 0x011BB4A4,
0x01194538, 0x0116E068, 0x011485F0, 0x0112358E,
0x010FEF01, 0x010DB20A, 0x010B7E6E, 0x010953F3,
0x01073260, 0x0105197F, 0x0103091B, 0x01010101
};
#endif

View file

@ -0,0 +1,152 @@
/* Copyright (c) 2001-2011 Timothy B. Terriberry
Copyright (c) 2008-2009 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "opus_types.h"
#include "opus_defines.h"
#if !defined(_entcode_H)
# define _entcode_H (1)
# include <limits.h>
# include <stddef.h>
# include "ecintrin.h"
extern const opus_uint32 SMALL_DIV_TABLE[129];
#ifdef OPUS_ARM_ASM
#define USE_SMALL_DIV_TABLE
#endif
/*OPT: ec_window must be at least 32 bits, but if you have fast arithmetic on a
larger type, you can speed up the decoder by using it here.*/
typedef opus_uint32 ec_window;
typedef struct ec_ctx ec_ctx;
typedef struct ec_ctx ec_enc;
typedef struct ec_ctx ec_dec;
# define EC_WINDOW_SIZE ((int)sizeof(ec_window)*CHAR_BIT)
/*The number of bits to use for the range-coded part of unsigned integers.*/
# define EC_UINT_BITS (8)
/*The resolution of fractional-precision bit usage measurements, i.e.,
3 => 1/8th bits.*/
# define BITRES 3
/*The entropy encoder/decoder context.
We use the same structure for both, so that common functions like ec_tell()
can be used on either one.*/
struct ec_ctx{
/*Buffered input/output.*/
unsigned char *buf;
/*The size of the buffer.*/
opus_uint32 storage;
/*The offset at which the last byte containing raw bits was read/written.*/
opus_uint32 end_offs;
/*Bits that will be read from/written at the end.*/
ec_window end_window;
/*Number of valid bits in end_window.*/
int nend_bits;
/*The total number of whole bits read/written.
This does not include partial bits currently in the range coder.*/
int nbits_total;
/*The offset at which the next range coder byte will be read/written.*/
opus_uint32 offs;
/*The number of values in the current range.*/
opus_uint32 rng;
/*In the decoder: the difference between the top of the current range and
the input value, minus one.
In the encoder: the low end of the current range.*/
opus_uint32 val;
/*In the decoder: the saved normalization factor from ec_decode().
In the encoder: the number of oustanding carry propagating symbols.*/
opus_uint32 ext;
/*A buffered input/output symbol, awaiting carry propagation.*/
int rem;
/*Nonzero if an error occurred.*/
int error;
};
static OPUS_INLINE opus_uint32 ec_range_bytes(ec_ctx *_this){
return _this->offs;
}
static OPUS_INLINE unsigned char *ec_get_buffer(ec_ctx *_this){
return _this->buf;
}
static OPUS_INLINE int ec_get_error(ec_ctx *_this){
return _this->error;
}
/*Returns the number of bits "used" by the encoded or decoded symbols so far.
This same number can be computed in either the encoder or the decoder, and is
suitable for making coding decisions.
Return: The number of bits.
This will always be slightly larger than the exact value (e.g., all
rounding error is in the positive direction).*/
static OPUS_INLINE int ec_tell(ec_ctx *_this){
return _this->nbits_total-EC_ILOG(_this->rng);
}
/*Returns the number of bits "used" by the encoded or decoded symbols so far.
This same number can be computed in either the encoder or the decoder, and is
suitable for making coding decisions.
Return: The number of bits scaled by 2**BITRES.
This will always be slightly larger than the exact value (e.g., all
rounding error is in the positive direction).*/
opus_uint32 ec_tell_frac(ec_ctx *_this);
/* Tested exhaustively for all n and for 1<=d<=256 */
static OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) {
celt_sig_assert(d>0);
#ifdef USE_SMALL_DIV_TABLE
if (d>256)
return n/d;
else {
opus_uint32 t, q;
t = EC_ILOG(d&-d);
q = (opus_uint64)SMALL_DIV_TABLE[d>>t]*(n>>(t-1))>>32;
return q+(n-q*d >= d);
}
#else
return n/d;
#endif
}
static OPUS_INLINE opus_int32 celt_sudiv(opus_int32 n, opus_int32 d) {
celt_sig_assert(d>0);
#ifdef USE_SMALL_DIV_TABLE
if (n<0)
return -(opus_int32)celt_udiv(-n, d);
else
return celt_udiv(n, d);
#else
return n/d;
#endif
}
#endif

View file

@ -0,0 +1,266 @@
/* Copyright (c) 2001-2011 Timothy B. Terriberry
Copyright (c) 2008-2009 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stddef.h>
#include "os_support.h"
#include "arch.h"
#include "entdec.h"
#include "mfrngcod.h"
/*A range decoder.
This is an entropy decoder based upon \cite{Mar79}, which is itself a
rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}.
It is very similar to arithmetic encoding, except that encoding is done with
digits in any base, instead of with bits, and so it is faster when using
larger bases (i.e.: a byte).
The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$
is the base, longer than the theoretical optimum, but to my knowledge there
is no published justification for this claim.
This only seems true when using near-infinite precision arithmetic so that
the process is carried out with no rounding errors.
An excellent description of implementation details is available at
http://www.arturocampos.com/ac_range.html
A recent work \cite{MNW98} which proposes several changes to arithmetic
encoding for efficiency actually re-discovers many of the principles
behind range encoding, and presents a good theoretical analysis of them.
End of stream is handled by writing out the smallest number of bits that
ensures that the stream will be correctly decoded regardless of the value of
any subsequent bits.
ec_tell() can be used to determine how many bits were needed to decode
all the symbols thus far; other data can be packed in the remaining bits of
the input buffer.
@PHDTHESIS{Pas76,
author="Richard Clark Pasco",
title="Source coding algorithms for fast data compression",
school="Dept. of Electrical Engineering, Stanford University",
address="Stanford, CA",
month=May,
year=1976
}
@INPROCEEDINGS{Mar79,
author="Martin, G.N.N.",
title="Range encoding: an algorithm for removing redundancy from a digitised
message",
booktitle="Video & Data Recording Conference",
year=1979,
address="Southampton",
month=Jul
}
@ARTICLE{MNW98,
author="Alistair Moffat and Radford Neal and Ian H. Witten",
title="Arithmetic Coding Revisited",
journal="{ACM} Transactions on Information Systems",
year=1998,
volume=16,
number=3,
pages="256--294",
month=Jul,
URL="http://www.stanford.edu/class/ee398a/handouts/papers/Moffat98ArithmCoding.pdf"
}*/
static int ec_read_byte(ec_dec *_this){
return _this->offs<_this->storage?_this->buf[_this->offs++]:0;
}
static int ec_read_byte_from_end(ec_dec *_this){
return _this->end_offs<_this->storage?
_this->buf[_this->storage-++(_this->end_offs)]:0;
}
/*Normalizes the contents of val and rng so that rng lies entirely in the
high-order symbol.*/
static void ec_dec_normalize(ec_dec *_this){
/*If the range is too small, rescale it and input some bits.*/
while(_this->rng<=EC_CODE_BOT){
int sym;
_this->nbits_total+=EC_SYM_BITS;
_this->rng<<=EC_SYM_BITS;
/*Use up the remaining bits from our last symbol.*/
sym=_this->rem;
/*Read the next value from the input.*/
_this->rem=ec_read_byte(_this);
/*Take the rest of the bits we need from this new symbol.*/
sym=(sym<<EC_SYM_BITS|_this->rem)>>(EC_SYM_BITS-EC_CODE_EXTRA);
/*And subtract them from val, capped to be less than EC_CODE_TOP.*/
_this->val=((_this->val<<EC_SYM_BITS)+(EC_SYM_MAX&~sym))&(EC_CODE_TOP-1);
}
}
void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage){
_this->buf=_buf;
_this->storage=_storage;
_this->end_offs=0;
_this->end_window=0;
_this->nend_bits=0;
/*This is the offset from which ec_tell() will subtract partial bits.
The final value after the ec_dec_normalize() call will be the same as in
the encoder, but we have to compensate for the bits that are added there.*/
_this->nbits_total=EC_CODE_BITS+1
-((EC_CODE_BITS-EC_CODE_EXTRA)/EC_SYM_BITS)*EC_SYM_BITS;
_this->offs=0;
_this->rng=1U<<EC_CODE_EXTRA;
_this->rem=ec_read_byte(_this);
_this->val=_this->rng-1-(_this->rem>>(EC_SYM_BITS-EC_CODE_EXTRA));
_this->error=0;
/*Normalize the interval.*/
ec_dec_normalize(_this);
}
unsigned ec_decode(ec_dec *_this,unsigned _ft){
unsigned s;
_this->ext=celt_udiv(_this->rng,_ft);
s=(unsigned)(_this->val/_this->ext);
return _ft-EC_MINI(s+1,_ft);
}
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){
unsigned s;
_this->ext=_this->rng>>_bits;
s=(unsigned)(_this->val/_this->ext);
return (1U<<_bits)-EC_MINI(s+1U,1U<<_bits);
}
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
opus_uint32 s;
s=IMUL32(_this->ext,_ft-_fh);
_this->val-=s;
_this->rng=_fl>0?IMUL32(_this->ext,_fh-_fl):_this->rng-s;
ec_dec_normalize(_this);
}
/*The probability of having a "one" is 1/(1<<_logp).*/
int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){
opus_uint32 r;
opus_uint32 d;
opus_uint32 s;
int ret;
r=_this->rng;
d=_this->val;
s=r>>_logp;
ret=d<s;
if(!ret)_this->val=d-s;
_this->rng=ret?s:r-s;
ec_dec_normalize(_this);
return ret;
}
int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){
opus_uint32 r;
opus_uint32 d;
opus_uint32 s;
opus_uint32 t;
int ret;
s=_this->rng;
d=_this->val;
r=s>>_ftb;
ret=-1;
do{
t=s;
s=IMUL32(r,_icdf[++ret]);
}
while(d<s);
_this->val=d-s;
_this->rng=t-s;
ec_dec_normalize(_this);
return ret;
}
int ec_dec_icdf16(ec_dec *_this,const opus_uint16 *_icdf,unsigned _ftb){
opus_uint32 r;
opus_uint32 d;
opus_uint32 s;
opus_uint32 t;
int ret;
s=_this->rng;
d=_this->val;
r=s>>_ftb;
ret=-1;
do{
t=s;
s=IMUL32(r,_icdf[++ret]);
}
while(d<s);
_this->val=d-s;
_this->rng=t-s;
ec_dec_normalize(_this);
return ret;
}
opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft){
unsigned ft;
unsigned s;
int ftb;
/*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
celt_assert(_ft>1);
_ft--;
ftb=EC_ILOG(_ft);
if(ftb>EC_UINT_BITS){
opus_uint32 t;
ftb-=EC_UINT_BITS;
ft=(unsigned)(_ft>>ftb)+1;
s=ec_decode(_this,ft);
ec_dec_update(_this,s,s+1,ft);
t=(opus_uint32)s<<ftb|ec_dec_bits(_this,ftb);
if(t<=_ft)return t;
_this->error=1;
return _ft;
}
else{
_ft++;
s=ec_decode(_this,(unsigned)_ft);
ec_dec_update(_this,s,s+1,(unsigned)_ft);
return s;
}
}
opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _bits){
ec_window window;
int available;
opus_uint32 ret;
window=_this->end_window;
available=_this->nend_bits;
if((unsigned)available<_bits){
do{
window|=(ec_window)ec_read_byte_from_end(_this)<<available;
available+=EC_SYM_BITS;
}
while(available<=EC_WINDOW_SIZE-EC_SYM_BITS);
}
ret=(opus_uint32)window&(((opus_uint32)1<<_bits)-1U);
window>>=_bits;
available-=_bits;
_this->end_window=window;
_this->nend_bits=available;
_this->nbits_total+=_bits;
return ret;
}

View file

@ -0,0 +1,110 @@
/* Copyright (c) 2001-2011 Timothy B. Terriberry
Copyright (c) 2008-2009 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(_entdec_H)
# define _entdec_H (1)
# include <limits.h>
# include "entcode.h"
/*Initializes the decoder.
_buf: The input buffer to use.
Return: 0 on success, or a negative value on error.*/
void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage);
/*Calculates the cumulative frequency for the next symbol.
This can then be fed into the probability model to determine what that
symbol is, and the additional frequency information required to advance to
the next symbol.
This function cannot be called more than once without a corresponding call to
ec_dec_update(), or decoding will not proceed correctly.
_ft: The total frequency of the symbols in the alphabet the next symbol was
encoded with.
Return: A cumulative frequency representing the encoded symbol.
If the cumulative frequency of all the symbols before the one that
was encoded was fl, and the cumulative frequency of all the symbols
up to and including the one encoded is fh, then the returned value
will fall in the range [fl,fh).*/
unsigned ec_decode(ec_dec *_this,unsigned _ft);
/*Equivalent to ec_decode() with _ft==1<<_bits.*/
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits);
/*Advance the decoder past the next symbol using the frequency information the
symbol was encoded with.
Exactly one call to ec_decode() must have been made so that all necessary
intermediate calculations are performed.
_fl: The cumulative frequency of all symbols that come before the symbol
decoded.
_fh: The cumulative frequency of all symbols up to and including the symbol
decoded.
Together with _fl, this defines the range [_fl,_fh) in which the value
returned above must fall.
_ft: The total frequency of the symbols in the alphabet the symbol decoded
was encoded in.
This must be the same as passed to the preceding call to ec_decode().*/
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft);
/* Decode a bit that has a 1/(1<<_logp) probability of being a one */
int ec_dec_bit_logp(ec_dec *_this,unsigned _logp);
/*Decodes a symbol given an "inverse" CDF table.
No call to ec_dec_update() is necessary after this call.
_icdf: The "inverse" CDF, such that symbol s falls in the range
[s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb.
The values must be monotonically non-increasing, and the last value
must be 0.
_ftb: The number of bits of precision in the cumulative distribution.
Return: The decoded symbol s.*/
int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb);
/*Decodes a symbol given an "inverse" CDF table.
No call to ec_dec_update() is necessary after this call.
_icdf: The "inverse" CDF, such that symbol s falls in the range
[s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb.
The values must be monotonically non-increasing, and the last value
must be 0.
_ftb: The number of bits of precision in the cumulative distribution.
Return: The decoded symbol s.*/
int ec_dec_icdf16(ec_dec *_this,const opus_uint16 *_icdf,unsigned _ftb);
/*Extracts a raw unsigned integer with a non-power-of-2 range from the stream.
The bits must have been encoded with ec_enc_uint().
No call to ec_dec_update() is necessary after this call.
_ft: The number of integers that can be decoded (one more than the max).
This must be at least 2, and no more than 2**32-1.
Return: The decoded bits.*/
opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft);
/*Extracts a sequence of raw bits from the stream.
The bits must have been encoded with ec_enc_bits().
No call to ec_dec_update() is necessary after this call.
_ftb: The number of bits to extract.
This must be between 0 and 25, inclusive.
Return: The decoded bits.*/
opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb);
#endif

Some files were not shown because too many files have changed in this diff Show more