package Ġcom . otal i ast ud ios . trans coder . internal . audio Ċ Ċ import Ġandroid . media . Media Format Ċ import Ġandroid . media . Media Format .* Ċ import Ġandroid . view . Surface Ċ import Ġcom . otal i ast ud ios . trans coder . internal . audio . rem ix . Audio Rem ix er Ċ import Ġcom . otal i ast ud ios . trans coder . internal . codec .* Ċ import Ġcom . otal i ast ud ios . trans coder . internal . pipeline .* Ċ import Ġcom . otal i ast ud ios . trans coder . internal . utils . Logger Ċ import Ġcom . otal i ast ud ios . trans coder . internal . utils . track Map Of Ċ import Ġcom . otal i ast ud ios . trans coder . resample . Audio Res ampler Ċ import Ġcom . otal i ast ud ios . trans coder . stretch . Audio Stretch er Ċ import Ġjava . util . concurrent . atomic . Atomic Integer Ċ import Ġkotlin . math . ceil Ċ import Ġkotlin . math . floor Ċ Ċ /** Ċ Ġ* ĠPerforms Ġaudio Ġrendering , Ġfrom Ġdecoder Ġoutput Ġto Ġencoder Ġinput , Ġapplying Ġsample Ġrate Ġconversion , Ċ Ġ* Ġrem ix ing , Ġstretch ing . ĠTODO : ĠWith Ġsome Ġextra Ġwork Ġthis Ġcould Ġbe Ġsplit Ġin Ġdifferent Ġsteps . Ċ Ġ*/ Ċ internal Ġclass ĠAudio Engine ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġstretch er : ĠAudio Stretch er , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġres ampler : ĠAudio Res ampler , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġtarget Format : ĠMedia Format Ċ ): ĠQue ued Step < Decoder Data , ĠDecoder Channel , ĠEncoder Data , ĠEncoder Channel >(), ĠDecoder Channel Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠID Ġ= ĠAtomicInteger ( 0 ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġval Ġlog Ġ= ĠLogger (" Audio Engine (${ ID . get And Increment () }) ") ĊĊĠĠĠ Ġoverride Ġval Ġchannel Ġ= Ġthis ĊĠĠĠ Ġprivate Ġval Ġbuffers Ġ= ĠShort Buffers () ĊĊĠĠĠ Ġprivate Ġval ĠMedia Format . sample Rate Ġget () Ġ= Ġget Integer ( KEY _ SAMPLE _ RATE ) ĊĠĠĠ Ġprivate Ġval ĠMedia Format . channels Ġget () Ġ= Ġget Integer ( KEY _ CHANNEL _ COUNT ) ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġraw Format : ĠMedia Format ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġchunks : ĠChunk Queue ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġrem ix er : ĠAudio Rem ix er ĊĊĠĠĠ Ġoverride Ġfun Ġhandle Source Format ( source Format : ĠMedia Format ): ĠSurface ? Ġ= Ġnull ĊĊĠĠĠ Ġoverride Ġfun Ġhandle Raw Format ( raw Format : ĠMedia Format ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . i (" handle Raw Format ($ raw Format )") ĊĠĠĠĠĠĠĠ Ġthis . raw Format Ġ= Ġraw Format ĊĠĠĠĠĠĠĠ Ġrem ix er Ġ= ĠAudio Rem ix er [ raw Format . channels , Ġtarget Format . channels ] ĊĠĠĠĠĠĠĠ Ġchunks Ġ= ĠChunk Queue ( raw Format . sample Rate , Ġraw Format . channels ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġenqueue E os ( data : ĠDecoder Data ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . i (" enqueue E os () ") ĊĠĠĠĠĠĠĠ Ġdata . release ( false ) ĊĠĠĠĠĠĠĠ Ġchunks . enqueue E os () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġenqueue ( data : ĠDecoder Data ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstretch Ġ= Ġ( data Ġas ? ĠDecoder Timer Data )?. time Stretch Ġ?: Ġ 1 . 0 ĊĠĠĠĠĠĠĠ Ġchunks . enqueue ( data . buffer . as Short Buffer (), Ġdata . time Us , Ġstretch ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata . release ( false ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdrain (): ĠState < Encoder Data > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( chunks . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . i (" drain (): Ġno Ġchunks , Ġwaiting ...") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠState . Wait ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġ( out Bytes , Ġout Id ) Ġ= Ġnext . buffer () Ġ?: Ġreturn Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . i (" drain (): Ġno Ġnext Ġbuffer , Ġwaiting ...") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . Wait ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġout Buffer Ġ= Ġout Bytes . as Short Buffer () ĊĠĠĠĠĠĠĠ Ġreturn Ġchunks . drain ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġeos Ġ= ĠState . E os ( Encoder Data ( out Bytes , Ġout Id , Ġ 0 )) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ Ġin Buffer , Ġtime Us , Ġstretch Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġout Size Ġ= Ġout Buffer . remaining () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġin Size Ġ= Ġin Buffer . remaining () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCompute Ġthe Ġdesired Ġoutput Ġsize Ġbased Ġon Ġall Ġsteps Ġthat Ġwe 'll Ġgo Ġthrough ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġdesired Out Size Ġ= Ġceil ( in Size Ġ* Ġstretch ) Ġ// Ġstretch ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdesired Out Size Ġ= Ġrem ix er . get Rem ixed Size ( desired Out Size . toInt ()). toDouble () Ġ// Ġrem ix ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdesired Out Size Ġ= Ġceil ( desired Out Size Ġ* Ġtarget Format . sample Rate Ġ/ Ġraw Format . sample Rate ) Ġ// Ġres ample ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSee Ġif Ġwe Ġhave Ġenough Ġroom Ġto Ġprocess Ġthe Ġwhole Ġinput ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprocess able Size Ġ= Ġif Ġ( desired Out Size Ġ<= Ġout Size ) Ġin Size Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfactor Ġ= Ġdesired Out Size Ġ/ Ġin Size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfloor ( out Size Ġ/ Ġfactor ). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Buffer . limit ( in Buffer . position () Ġ+ Ġprocess able Size ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSt retch ing ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstretch Size Ġ= Ġceil ( process able Size Ġ* Ġstretch ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstretch Buffer Ġ= Ġbuffers . acquire (" stretch ", Ġstretch Size . toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstretch er . stretch ( in Buffer , Ġstretch Buffer , Ġraw Format . channels ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstretch Buffer . flip () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRem ix ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrem ix Size Ġ= Ġrem ix er . get Rem ixed Size ( stretch Size . toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrem ix Buffer Ġ= Ġbuffers . acquire (" rem ix ", Ġrem ix Size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrem ix er . rem ix ( stretch Buffer , Ġrem ix Buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrem ix Buffer . flip () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRes ample ĊĠĠĠĠĠĠĠĠĠĠĠ Ġres ampler . resample ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrem ix Buffer , Ġraw Format . sample Rate , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout Buffer , Ġtarget Format . sample Rate , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Format . channels ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout Buffer . flip () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAdjust Ġposition Ġand Ġdispatch . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout Bytes . clear () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout Bytes . limit ( out Buffer . limit () Ġ* ĠBY TES _ PER _ SHORT ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout Bytes . position ( out Buffer . position () Ġ* ĠBY TES _ PER _ SHORT ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState . Ok ( Encoder Data ( out Bytes , Ġout Id , Ġtime Us )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }