/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 5 ĠGoogle ĠInc . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġcom . d ve . aud i ow avel ib . sound file Ċ Ċ import Ġandroid . media .* Ċ import Ġandroid . os . Build Ċ import Ġandroid . os . Environment Ċ import Ġandroid . util . Log Ċ import Ġjava . io .* Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . nio . Byte Order Ċ import Ġjava . nio . Short Buffer Ċ import Ġjava . util .* Ċ import Ġkotlin . math . abs Ċ Ċ // ĠA ĠSound File Ġobject Ġshould Ġonly Ġbe Ġcreated Ġusing Ġthe Ġstatic Ġmethods Ġcreate () Ġand Ġrecord (). Ċ Ċ public Ġclass ĠSound File Ġprivate Ġconstructor () Ġ{ ĊĊĠĠĠ Ġprivate Ġval ĠserialVersionUID Ġ= Ġ- 2 5 0 5 6 9 8 9 9 1 5 9 7 8 3 7 1 6 5 L ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm Progress Listener : ĠProgress Listener ĊĠĠĠ Ġprivate Ġ Ġvar Ġm Input File : ĠFile ? Ġ= Ġnull ĊĊĠĠĠ Ġ// ĠMember Ġvariables Ġrepresenting Ġframe Ġdata ĊĠĠĠ Ġvar Ġfile type : ĠString ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar ĠfileSize Bytes Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġavg Bit rate Kb ps Ġ// ĠAverage Ġbit Ġrate Ġin Ġkb ps . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġsample Rate Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġchannels Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġ// ĠNumber Ġof Ġsamples Ġper Ġchannel . ĊĠĠĠ Ġvar Ġnum Samples Ġ// Ġtotal Ġnumber Ġof Ġsamples Ġper Ġchannel Ġin Ġaudio Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġprivate Ġvar Ġm Decoded Bytes Ġ// ĠRaw Ġaudio Ġdata ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ: ĠByteBuffer ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġm Decoded Samples Ġ// Ġshared Ġbuffer Ġwith Ġm Decoded Bytes . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ: ĠShort Buffer ? Ġ= Ġnull ĊĊĠĠĠ Ġ// ĠShould Ġbe Ġremoved Ġwhen Ġthe Ġapp Ġwill Ġuse Ġdirectly Ġthe Ġsamples Ġinstead Ġof Ġthe Ġframes . ĊĠĠĠ Ġ// Ġm Decoded Samples Ġhas Ġthe Ġfollowing Ġformat : ĊĠĠĠ Ġ// Ġ{ s 1 c 1 , Ġs 1 c 2 , Ġ..., Ġs 1 cM , Ġs 2 c 1 , Ġ..., Ġs 2 cM , Ġ..., Ġs Nc 1 , Ġ..., Ġs Nc M } ĊĠĠĠ Ġ// Ġwhere Ġsic j Ġis Ġthe Ġ ith Ġsample Ġof Ġthe Ġj th Ġchannel Ġ( a Ġsample Ġis Ġa Ġsigned Ġshort ) ĊĠĠĠ Ġ// ĠM Ġis Ġthe Ġnumber Ġof Ġchannels Ġ( e . g . Ġ 2 Ġfor Ġst ereo ) Ġand ĠN Ġis Ġthe Ġnumber Ġof Ġsamples Ġper Ġchannel . ĊĠĠĠ Ġ// ĠMember Ġvariables Ġfor Ġhack Ġ( making Ġit Ġwork Ġwith Ġold Ġversion , Ġuntil Ġapp Ġjust Ġuses Ġthe Ġsamples ). ĊĠĠĠ Ġvar Ġnum Frames Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġ// ĠShould Ġbe Ġremoved Ġwhen Ġthe Ġapp Ġwill Ġuse Ġdirectly Ġthe Ġsamples Ġinstead Ġof Ġthe Ġframes . ĊĠĠĠ Ġvar Ġframe G ains : ĠInt Array ?= null ĊĊĠĠĠ Ġprivate Ġvar Ġm Frame Lens : ĠInt Array ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġm Frame Offsets : ĠInt Array ? Ġ Ġ= null ĊĊĠĠĠ Ġ// ĠProgress Ġlistener Ġinterface . ĊĠĠĠ Ġinterface ĠProgress Listener Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠWill Ġbe Ġcalled Ġby Ġthe ĠSound File Ġclass Ġperiodically ĊĠĠĠĠĠĠĠĠ Ġ* Ġwith Ġvalues Ġbetween Ġ 0 . 0 Ġand Ġ 1 . 0 . Ġ ĠReturn Ġtrue Ġto Ġcontinue ĊĠĠĠĠĠĠĠĠ Ġ* Ġloading Ġthe Ġfile Ġor Ġrecording Ġthe Ġaudio , Ġand Ġfalse Ġto Ġcancel Ġor Ġstop Ġrecording . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġreport Progress ( fraction Complete : ĠDouble ): ĠBoolean ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠCustom Ġexception Ġfor Ġinvalid Ġinputs . ĊĠĠĠ Ġinner Ġclass ĠInvalid Input Exception ( message : ĠString ?) Ġ: ĠException ( message ) Ġ{ ĊĊĠĠĠ Ġ}// Ġjust Ġa Ġfixed Ġvalue Ġhere ... ĊĊĠĠĠ Ġ// ĠShould Ġbe Ġremoved Ġwhen Ġthe Ġapp Ġwill Ġuse Ġdirectly Ġthe Ġsamples Ġinstead Ġof Ġthe Ġframes . ĊĠĠĠ Ġval Ġsamples Per Frame : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġ 1 0 2 4 Ġ// Ġjust Ġa Ġfixed Ġvalue Ġhere ... ĊĊĠĠĠ Ġ// ĠHack Ġfor ĠN ou gat Ġwhere Ġas ReadOnly Buffer Ġfails Ġto Ġrespect Ġbyte Ġordering . ĊĠĠĠ Ġ// ĠSee Ġhttps :// code . google . com / p / android / issues / detail ? id = 2 2 3 8 2 4 ĊĠĠĠ Ġval Ġsamples : ĠShort Buffer ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġif Ġ( m Decoded Samples Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . N Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBuild . VERSION . SDK _ INT Ġ<= ĠBuild . VERSION _ CODES . N _ MR 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠHack Ġfor ĠN ou gat Ġwhere Ġas ReadOnly Buffer Ġfails Ġto Ġrespect Ġbyte Ġordering . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSee Ġhttps :// code . google . com / p / android / issues / detail ? id = 2 2 3 8 2 4 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Samples ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Samples !!. as ReadOnly Buffer () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġset Progress Listener ( progress Listener : ĠProgress Listener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġm Progress Listener Ġ= Ġprogress Listener ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( FileNotFoundException :: class , ĠIOException :: class , ĠInvalid Input Exception :: class ) ĊĠĠĠ Ġprivate Ġfun ĠRead File ( inputFile : ĠFile ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġextractor : ĠMedia Extractor ? Ġ= ĠMedia Extractor () ĊĠĠĠĠĠĠĠ Ġvar Ġformat : ĠMedia Format ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġi : ĠInt ĊĠĠĠĠĠĠĠ Ġm Input File Ġ= Ġinput File ĊĠĠĠĠĠĠĠ Ġval Ġcomponents Ġ= Ġm Input File !!. path . split ("\\ . "). to Typed Array () ĊĠĠĠĠĠĠĠ Ġfile type Ġ= Ġcomponents [ components . size Ġ- Ġ 1 ] ĊĠĠĠĠĠĠĠ ĠfileSize Bytes Ġ= Ġm Input File !!. length (). toInt () ĊĠĠĠĠĠĠĠ Ġextractor !!. set DataSource ( m Input File !!. path ) ĊĠĠĠĠĠĠĠ Ġval Ġnum Tracks Ġ= Ġextractor . track Count ĊĠĠĠĠĠĠĠ Ġ// Ġfind Ġand Ġselect Ġthe Ġfirst Ġaudio Ġtrack Ġpresent Ġin Ġthe Ġfile . ĊĠĠĠĠĠĠĠ Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( i Ġ< Ġnum Tracks ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġformat Ġ= Ġextractor . get Track Format ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( format . getString ( Media Format . KEY _ MIME ). startsWith (" audio / ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġextractor . select Track ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġi ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( i Ġ== Ġnum Tracks ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠInvalid Input Exception (" No Ġaudio Ġtrack Ġfound Ġin Ġ$ m Input File ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġchannels Ġ= Ġformat !!. getInteger ( Media Format . KEY _ CHANNEL _ COUNT ) ĊĠĠĠĠĠĠĠ Ġsample Rate Ġ= Ġformat . getInteger ( Media Format . KEY _ SAMPLE _ RATE ) ĊĠĠĠĠĠĠĠ Ġ// ĠExpected Ġtotal Ġnumber Ġof Ġsamples Ġper Ġchannel . ĊĠĠĠĠĠĠĠ Ġval Ġexpected Num Samples Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( format . getLong ( Media Format . KEY _ DURATION ) Ġ/ Ġ 1 0 0 0 0 0 0 f Ġ* Ġsample Rate Ġ+ Ġ 0 . 5 f ). toInt () ĊĠĠĠĠĠĠĠ Ġvar Ġcodec : ĠMedia Codec ? Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Codec . create Decoder ByType ( format . getString ( Media Format . KEY _ MIME )) ĊĠĠĠĠĠĠĠ Ġcodec !!. configure ( format , Ġnull , Ġnull , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġcodec . start () ĊĠĠĠĠĠĠĠ Ġvar Ġdecoded Samples Size Ġ= Ġ 0 Ġ// Ġsize Ġof Ġthe Ġoutput Ġbuffer Ġcontaining Ġdecoded Ġsamples . ĊĠĠĠĠĠĠĠ Ġvar Ġdecoded Samples : ĠByteArray ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġinput Buffers Ġ= Ġcodec . input Buffers ĊĠĠĠĠĠĠĠ Ġvar Ġoutput Buffers Ġ= Ġcodec . output Buffers ĊĠĠĠĠĠĠĠ Ġvar Ġsample _ size : ĠInt ĊĠĠĠĠĠĠĠ Ġval Ġinfo Ġ= ĠMedia Codec . Buffer Info () ĊĠĠĠĠĠĠĠ Ġvar Ġpresentation _ time : ĠLong ĊĠĠĠĠĠĠĠ Ġvar Ġtot _ size _ read Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġdone _ reading Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġ// ĠSet Ġthe Ġsize Ġof Ġthe Ġdecoded Ġsamples Ġbuffer Ġto Ġ 1 MB Ġ(~ 6 sec Ġof Ġa Ġst ereo Ġstream Ġat Ġ 4 4 . 1 k Hz ). ĊĠĠĠĠĠĠĠ Ġ// ĠFor Ġlonger Ġstreams , Ġthe Ġbuffer Ġsize Ġwill Ġbe Ġincreased Ġlater Ġon , Ġcalculating Ġa Ġrough ĊĠĠĠĠĠĠĠ Ġ// Ġestimate Ġof Ġthe Ġtotal Ġsize Ġneeded Ġto Ġstore Ġall Ġthe Ġsamples Ġin Ġorder Ġto Ġresize Ġthe Ġbuffer ĊĠĠĠĠĠĠĠ Ġ// Ġonly Ġonce . ĊĠĠĠĠĠĠĠ Ġm Decoded Bytes Ġ= ĠByteBuffer . allocate ( 1 Ġshl Ġ 2 0 ) ĊĠĠĠĠĠĠĠ Ġvar Ġfirst Sample Data Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġread Ġdata Ġfrom Ġfile Ġand Ġfeed Ġit Ġto Ġthe Ġdecoder Ġinput Ġbuffers . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinput Buffer Index Ġ= Ġcodec !!. de queue Input Buffer ( 1 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! done _ reading Ġ&& Ġinput Buffer Index Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsample _ size Ġ= Ġextractor !!. read Sample Data ( input Buffers [ input Buffer Index ], Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( first Sample Data ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġformat . getString ( Media Format . KEY _ MIME ) Ġ== Ġ" audio / mp 4 a - lat m " Ġ&& Ġsample _ size Ġ== Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFor Ġsome Ġreasons Ġon Ġsome Ġdevices Ġ( e . g . Ġthe ĠSamsung ĠS 3 ) Ġyou Ġshould Ġnot ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġprovide Ġthe Ġfirst Ġtwo Ġbytes Ġof Ġan ĠA AC Ġstream , Ġotherwise Ġthe ĠMedia Codec Ġwill ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcrash . ĠThese Ġtwo Ġbytes Ġdo Ġnot Ġcontain Ġmusic Ġdata Ġbut Ġbasic Ġinfo Ġon Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġstream Ġ( e . g . Ġchannel Ġconfiguration Ġand Ġsampling Ġfrequency ), Ġand Ġskipping Ġthem ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġseems ĠOK Ġwith Ġother Ġdevices Ġ( Media Codec Ġhas Ġalready Ġbeen Ġconfigured Ġand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġalready Ġknows Ġthese Ġparameters ). ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġextractor . advance () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtot _ size _ read Ġ+= Ġsample _ size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( sample _ size Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAll Ġsamples Ġhave Ġbeen Ġread . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcodec . queue Input Buffer ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput Buffer Index , Ġ 0 , Ġ 0 , Ġ- 1 , ĠMedia Codec . BUFFER _ FLAG _ END _ OF _ STREAM ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdone _ reading Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpresentation _ time Ġ= Ġextractor . sample Time ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcodec . queue Input Buffer ( input Buffer Index , Ġ 0 , Ġsample _ size , Ġpresentation _ time , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġextractor . advance () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtot _ size _ read Ġ+= Ġsample _ size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Progress Listener Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! m Progress Listener !!. report Progress (( tot _ size _ read . toFloat () Ġ/ ĠfileSize Bytes ). toDouble ())) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġare Ġasked Ġto Ġstop Ġreading Ġthe Ġfile . ĠReturn ing Ġimmediately . ĠThe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSound File Ġobject Ġis Ġinvalid Ġand Ġshould ĠNOT Ġbe Ġused Ġafter ward ! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġextractor . release () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġextractor Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcodec . stop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcodec . release () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcodec Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfirst Sample Data Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġdecoded Ġstream Ġfrom Ġthe Ġdecoder Ġoutput Ġbuffers . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput Buffer Index Ġ= Ġcodec . de queue Output Buffer ( info , Ġ 1 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( output Buffer Index Ġ>= Ġ 0 Ġ&& Ġinfo . size Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( decoded Samples Size Ġ< Ġinfo . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdecoded Samples Size Ġ= Ġinfo . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdecoded Samples Ġ= ĠByteArray ( decoded Samples Size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Buffers [ output Buffer Index ][ decoded Samples , Ġ 0 , Ġinfo . size ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Buffers [ output Buffer Index ]. clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġif Ġbuffer Ġis Ġbig Ġenough . ĠResize Ġit Ġif Ġit 's Ġtoo Ġsmall . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Decoded Bytes !!. remaining () Ġ< Ġinfo . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGetting Ġa Ġrough Ġestimate Ġof Ġthe Ġtotal Ġsize , Ġallocate Ġ 2 0 % Ġmore , Ġand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġmake Ġsure Ġto Ġallocate Ġat Ġleast Ġ 5 MB Ġmore Ġthan Ġthe Ġinitial Ġsize . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġposition Ġ= Ġm Decoded Bytes !!. position () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnew Size Ġ= Ġ( position Ġ* Ġ( 1 . 0 Ġ* ĠfileSize Bytes Ġ/ Ġtot _ size _ read ) Ġ* Ġ 1 . 2 ). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Size Ġ- Ġposition Ġ< Ġinfo . size Ġ+ Ġ 5 Ġ* Ġ( 1 Ġshl Ġ 2 0 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Size Ġ= Ġposition Ġ+ Ġinfo . size Ġ+ Ġ 5 Ġ* Ġ( 1 Ġshl Ġ 2 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnew Decoded Bytes : ĠByteBuffer ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTry Ġto Ġallocate Ġmemory . ĠIf Ġwe Ġare ĠO OM , Ġtry Ġto Ġrun Ġthe Ġgarbage Ġcollector . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġretry Ġ= Ġ 1 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( retry Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Decoded Bytes Ġ= ĠByteBuffer . allocate ( new Size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( oo me : ĠOut Of Memory Error ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsetting Ġandroid : large Heap =" true " Ġin Ġ< application > Ġseem Ġto Ġhelp Ġnot ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġre aching Ġthis Ġsection . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġretry -- ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( retry Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFailed Ġto Ġallocate Ġmemory ... ĠStop Ġreading Ġmore Ġdata Ġand Ġfinalize Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġinstance Ġwith Ġthe Ġdata Ġdecoded Ġso Ġfar . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ByteBuffer Ġnew Decoded Bytes Ġ= ĠByteBuffer . allocate ( new Size ); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. rewind () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Decoded Bytes !!. put ( m Decoded Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes Ġ= Ġnew Decoded Bytes ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. position ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. put ( decoded Samples , Ġ 0 , Ġinfo . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcodec . release Output Buffer ( output Buffer Index , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( output Buffer Index Ġ== ĠMedia Codec . INFO _ OUTPUT _ BUFFER S _ CHANGED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Buffers Ġ= Ġcodec . output Buffers ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( output Buffer Index Ġ== ĠMedia Codec . INFO _ OUTPUT _ FORMAT _ CHANGED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSub sequent Ġdata Ġwill Ġconform Ġto Ġnew Ġformat . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġcould Ġcheck Ġthat Ġcodec . getOutput Format (), Ġwhich Ġis Ġthe Ġnew Ġoutput Ġformat , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġis Ġwhat Ġwe Ġexpect . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( info . flags Ġand ĠMedia Codec . BUFFER _ FLAG _ END _ OF _ STREAM Ġ!= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġm Decoded Bytes !!. position () Ġ/ Ġ( 2 Ġ* Ġchannels ) Ġ>= Ġexpected Num Samples ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġgot Ġall Ġthe Ġdecoded Ġdata Ġfrom Ġthe Ġdecoder . ĠStop Ġhere . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe oret ically Ġde queue Output Buffer ( info , Ġ...) Ġshould Ġhave Ġset Ġinfo . flags Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMedia Codec . BUFFER _ FLAG _ END _ OF _ STREAM . ĠHowever Ġsome Ġph ones Ġ( e . g . ĠSamsung ĠS 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwon 't Ġdo Ġthat Ġfor Ġsome Ġfiles Ġ( e . g . Ġwith Ġmono ĠA AC Ġfiles ), Ġin Ġwhich Ġcase Ġsubsequent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcalls Ġto Ġde queue Output Buffer Ġmay Ġresult Ġin Ġthe Ġapplication Ġcrash ing , Ġwithout ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġeven Ġan Ġexception Ġbeing Ġthrown ... ĠHence Ġthe Ġsecond Ġcheck . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ( for Ġmono ĠA AC Ġfiles , Ġthe ĠS 3 Ġwill Ġactually Ġdouble Ġeach Ġsample , Ġas Ġif Ġthe Ġstream ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwas Ġst ereo . ĠThe Ġresulting Ġstream Ġis Ġhalf Ġwhat Ġit 's Ġsupposed Ġto Ġbe Ġand Ġwith Ġa Ġmuch ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġlower Ġpitch .) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġnum Samples Ġ= Ġm Decoded Bytes !!. position () Ġ/ Ġ( channels Ġ* Ġ 2 ) Ġ// ĠOne Ġsample Ġ= Ġ 2 Ġbytes . ĊĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. rewind () ĊĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. order ( Byte Order . LIT TLE _ ENDIAN ) ĊĠĠĠĠĠĠĠ Ġm Decoded Samples Ġ= Ġm Decoded Bytes !!. as Short Buffer () ĊĠĠĠĠĠĠĠ Ġavg Bit rate Kb ps Ġ= Ġ( file Size Bytes Ġ* Ġ 8 Ġ* Ġ( sample Rate . toFloat () Ġ/ Ġnum Samples ) Ġ/ Ġ 1 0 0 0 ). toInt () ĊĠĠĠĠĠĠĠ Ġextractor !!. release () ĊĠĠĠĠĠĠĠ Ġextractor Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġcodec !!. stop () ĊĠĠĠĠĠĠĠ Ġcodec . release () ĊĠĠĠĠĠĠĠ Ġcodec Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġ// ĠTemporary Ġhack Ġto Ġmake Ġit Ġwork Ġwith Ġthe Ġold Ġversion . ĊĠĠĠĠĠĠĠ Ġnum Frames Ġ= Ġnum Samples Ġ/ Ġsamples Per Frame ĊĠĠĠĠĠĠĠ Ġif Ġ( num Samples Ġ% Ġsamples Per Frame Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnum Frames ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġframe G ains Ġ= ĠInt Array ( num Frames ) ĊĠĠĠĠĠĠĠ Ġm Frame Lens Ġ= ĠInt Array ( num Frames ) ĊĠĠĠĠĠĠĠ Ġm Frame Offsets Ġ= ĠInt Array ( num Frames ) ĊĠĠĠĠĠĠĠ Ġvar Ġj : ĠInt ĊĠĠĠĠĠĠĠ Ġvar Ġgain : ĠInt ĊĠĠĠĠĠĠĠ Ġvar Ġvalue : ĠInt ĊĠĠĠĠĠĠĠ Ġval Ġframe Lens Ġ= Ġ( 1 0 0 0 Ġ* Ġavg Bit rate Kb ps Ġ/ Ġ 8 Ġ* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( samples Per Frame . toFloat () Ġ/ Ġsample Rate )). toInt () ĊĠĠĠĠĠĠĠ Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( i Ġ< Ġnum Frames ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgain Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġj Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( j Ġ< Ġsamples Per Frame ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( k Ġin Ġ 0 Ġuntil Ġchannels ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Decoded Samples !!. remaining () Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ+= Ġabs ( m Decoded Samples !!. get (). toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ/= Ġchannels ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( gain Ġ< Ġvalue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgain Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġj ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġframe G ains ! ![ i ] Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMath . sqrt ( gain . toDouble ()). toInt () Ġ// Ġhere Ġgain Ġ= Ġsqrt ( max Ġvalue Ġof Ġ 1 st Ġchannel )... ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Frame Lens ! ![ i ] Ġ= Ġframe Lens Ġ// Ġtotally Ġnot Ġaccurate ... ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Frame Offsets ! ![ i ] Ġ= Ġ( i Ġ* Ġ( 1 0 0 0 Ġ* Ġavg Bit rate Kb ps Ġ/ Ġ 8 ) Ġ* Ġ Ġ// Ġ Ġ= Ġi Ġ* Ġframe Lens ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( samples Per Frame . toFloat () Ġ/ Ġsample Rate )). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġi ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġm Decoded Samples !!. rewind () ĊĠĠĠĠĠĠĠ Ġ// ĠDump Samples (); Ġ Ġ// ĠUncomment Ġthis Ġline Ġto Ġdump Ġthe Ġsamples Ġin Ġa ĠT SV Ġfile . ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠRecord Audio () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( m Progress Listener Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠA Ġprogress Ġlistener Ġis Ġmandatory Ġhere , Ġas Ġit Ġwill Ġlet Ġus Ġknow Ġwhen Ġto Ġstop Ġrecording . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġm Input File Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġfile type Ġ= Ġ" raw " ĊĠĠĠĠĠĠĠ ĠfileSize Bytes Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġsample Rate Ġ= Ġ 4 4 1 0 0 ĊĠĠĠĠĠĠĠ Ġchannels Ġ= Ġ 1 Ġ// Ġrecord Ġmono Ġaudio . ĊĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠShort Array ( 1 0 2 4 ) Ġ// Ġbuffer Ġcontains Ġ 1 Ġmono Ġframe Ġof Ġ 1 0 2 4 Ġ 1 6 Ġbits Ġsamples ĊĠĠĠĠĠĠĠ Ġvar Ġmin BufferSize Ġ= ĠAudio Record . getMin BufferSize ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsample Rate , ĠAudio Format . CHANNEL _ IN _ MON O , ĠAudio Format . ENCODING _ PCM _ 1 6 BIT ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ// Ġmake Ġsure Ġmin BufferSize Ġcan Ġcontain Ġat Ġleast Ġ 1 Ġsecond Ġof Ġaudio Ġ( 1 6 Ġbits Ġsample ). ĊĠĠĠĠĠĠĠ Ġif Ġ( min BufferSize Ġ< Ġsample Rate Ġ* Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmin BufferSize Ġ= Ġsample Rate Ġ* Ġ 2 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġaudio Record Ġ= ĠAudio Record ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Recorder . Audio Source . DEFAULT , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsample Rate , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAudio Format . CHANNEL _ IN _ MON O , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAudio Format . ENCODING _ PCM _ 1 6 BIT , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmin BufferSize ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAllocate Ġmemory Ġfor Ġ 2 0 Ġseconds Ġfirst . ĠRe allocate Ġlater Ġif Ġmore Ġis Ġneeded . ĊĠĠĠĠĠĠĠ Ġm Decoded Bytes Ġ= ĠByteBuffer . allocate ( 2 0 Ġ* Ġsample Rate Ġ* Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. order ( Byte Order . LIT TLE _ ENDIAN ) ĊĠĠĠĠĠĠĠ Ġm Decoded Samples Ġ= Ġm Decoded Bytes !!. as Short Buffer () ĊĠĠĠĠĠĠĠ Ġaudio Record . start Recording () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġif Ġm Decoded Samples Ġcan Ġcontain Ġ 1 0 2 4 Ġadditional Ġsamples . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Decoded Samples !!. remaining () Ġ< Ġ 1 0 2 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTry Ġto Ġallocate Ġmemory Ġfor Ġ 1 0 Ġadditional Ġseconds . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Capacity Ġ= Ġm Decoded Bytes !!. capacity () Ġ+ Ġ 1 0 Ġ* Ġsample Rate Ġ* Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnew Decoded Bytes : ĠByteBuffer ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Decoded Bytes Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠByteBuffer . allocate ( new Capacity ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( oo me : ĠOut Of Memory Error ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġposition Ġ= Ġm Decoded Samples !!. position () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. rewind () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Decoded Bytes !!. put ( m Decoded Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes Ġ= Ġnew Decoded Bytes ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. order ( Byte Order . LIT TLE _ ENDIAN ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. rewind () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Samples Ġ= Ġm Decoded Bytes !!. as Short Buffer () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Samples !!. position ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO ( nf ar al li ): Ġmaybe Ġuse Ġthe Ġread Ġmethod Ġthat Ġtakes Ġa Ġdirect ĠByteBuffer Ġargument . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġaudio Record . read ( buffer , Ġ 0 , Ġbuffer . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Samples !!. put ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLet Ġthe Ġprogress Ġlistener Ġknow Ġhow Ġmany Ġseconds Ġhave Ġbeen Ġrecorded . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġreturned Ġvalue Ġtells Ġus Ġif Ġwe Ġshould Ġkeep Ġrecording Ġor Ġstop . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! m Progress Listener !!. report Progress ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Samples !!. position (). toFloat () Ġ/ Ġsample Rate ). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġaudio Record . stop () ĊĠĠĠĠĠĠĠ Ġaudio Record . release () ĊĠĠĠĠĠĠĠ Ġnum Samples Ġ= Ġm Decoded Samples !!. position () ĊĠĠĠĠĠĠĠ Ġm Decoded Samples !!. rewind () ĊĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. rewind () ĊĠĠĠĠĠĠĠ Ġavg Bit rate Kb ps Ġ= Ġsample Rate Ġ* Ġ 1 6 Ġ/ Ġ 1 0 0 0 ĊĊĠĠĠĠĠĠĠ Ġ// ĠTemporary Ġhack Ġto Ġmake Ġit Ġwork Ġwith Ġthe Ġold Ġversion . ĊĠĠĠĠĠĠĠ Ġnum Frames Ġ= Ġnum Samples Ġ/ Ġsamples Per Frame ĊĠĠĠĠĠĠĠ Ġif Ġ( num Samples Ġ% Ġsamples Per Frame Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnum Frames ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġframe G ains Ġ= ĠInt Array ( num Frames ) ĊĠĠĠĠĠĠĠ Ġm Frame Lens Ġ= Ġnull Ġ// Ġnot Ġneeded Ġfor Ġrecorded Ġaudio ĊĠĠĠĠĠĠĠ Ġm Frame Offsets Ġ= Ġnull Ġ// Ġnot Ġneeded Ġfor Ġrecorded Ġaudio ĊĠĠĠĠĠĠĠ Ġvar Ġi : ĠInt ĊĠĠĠĠĠĠĠ Ġvar Ġj : ĠInt ĊĠĠĠĠĠĠĠ Ġvar Ġgain : ĠInt ĊĠĠĠĠĠĠĠ Ġvar Ġvalue : ĠInt ĊĠĠĠĠĠĠĠ Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( i Ġ< Ġnum Frames ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgain Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġj Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( j Ġ< Ġsamples Per Frame ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġif Ġ( m Decoded Samples !!. remaining () Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMath . abs ( m Decoded Samples !!. get (). toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( gain Ġ< Ġvalue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgain Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġj ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġframe G ains ! ![ i ] Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMath . sqrt ( gain . toDouble ()). toInt () Ġ// Ġhere Ġgain Ġ= Ġsqrt ( max Ġvalue Ġof Ġ 1 st Ġchannel )... ĊĠĠĠĠĠĠĠĠĠĠĠ Ġi ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġm Decoded Samples !!. rewind () ĊĠĠĠĠĠĠĠ Ġ// ĠDump Samples (); Ġ Ġ// ĠUncomment Ġthis Ġline Ġto Ġdump Ġthe Ġsamples Ġin Ġa ĠT SV Ġfile . ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġshould Ġbe Ġremoved Ġin Ġthe Ġnear Ġfuture ... ĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġfun ĠWrite File ( outputFile : ĠFile ?, Ġstart Frame : ĠInt , Ġnum Frames : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠstartTime Ġ= Ġstart Frame . toFloat () Ġ* Ġsamples Per Frame Ġ/ Ġsample Rate ĊĠĠĠĠĠĠĠ Ġval ĠendTime Ġ= Ġ( start Frame Ġ+ Ġnum Frames ) Ġas ĠFloat Ġ* Ġsamples Per Frame Ġ/ Ġsample Rate ĊĠĠĠĠĠĠĠ ĠWrite File ( outputFile , ĠstartTime , ĠendTime ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġfun ĠWrite File ( outputFile : ĠFile ?, ĠstartTime : ĠFloat , ĠendTime : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstart Offset Ġ= Ġ( startTime Ġ* Ġsample Rate ). toInt () Ġ* Ġ 2 Ġ* Ġchannels ĊĠĠĠĠĠĠĠ Ġvar Ġnum Samples Ġ= Ġ(( endTime Ġ- ĠstartTime ) Ġ* Ġsample Rate ). toInt () ĊĠĠĠĠĠĠĠ Ġ// ĠSome Ġdevices Ġhave Ġproblems Ġreading Ġmono ĠA AC Ġfiles Ġ( e . g . ĠSamsung ĠS 3 ). ĠMaking Ġit Ġst ereo . ĊĠĠĠĠĠĠĠ Ġval Ġnum Channels Ġ= Ġif Ġ( channels Ġ== Ġ 1 ) Ġ 2 Ġelse Ġchannels ĊĠĠĠĠĠĠĠ Ġval ĠmimeType Ġ= Ġ" audio / mp 4 a - lat m " ĊĠĠĠĠĠĠĠ Ġval Ġbit rate Ġ= Ġ 6 4 0 0 0 Ġ* Ġnum Channels Ġ// Ġrule Ġof Ġthumb Ġfor Ġa Ġgood Ġquality : Ġ 6 4 kb ps Ġper Ġchannel . ĊĠĠĠĠĠĠĠ Ġvar Ġcodec : ĠMedia Codec ? Ġ= ĠMedia Codec . create Encoder ByType ( mime Type ) ĊĠĠĠĠĠĠĠ Ġval Ġformat Ġ= ĠMedia Format . create Audio Format ( mime Type , Ġsample Rate , Ġnum Channels ) ĊĠĠĠĠĠĠĠ Ġformat . set Integer ( Media Format . KEY _ BIT _ RATE , Ġbit rate ) ĊĠĠĠĠĠĠĠ Ġcodec !!. configure ( format , Ġnull , Ġnull , ĠMedia Codec . CONFIGURE _ FLAG _ ENCODE ) ĊĠĠĠĠĠĠĠ Ġcodec . start () ĊĊĠĠĠĠĠĠĠ Ġ// ĠGet Ġan Ġestimation Ġof Ġthe Ġencoded Ġdata Ġbased Ġon Ġthe Ġbit rate . ĠAdd Ġ 1 0 % Ġto Ġit . ĊĠĠĠĠĠĠĠ Ġvar Ġestimated Encoded Size Ġ= Ġ(( endTime Ġ- ĠstartTime ) Ġ* Ġ( bit rate Ġ/ Ġ 8 ) Ġ* Ġ 1 . 1 ). toInt () ĊĠĠĠĠĠĠĠ Ġvar Ġencoded Bytes Ġ= ĠByteBuffer . allocate ( estimated Encoded Size ) ĊĠĠĠĠĠĠĠ Ġval Ġinput Buffers Ġ= Ġcodec . input Buffers ĊĠĠĠĠĠĠĠ Ġvar Ġoutput Buffers Ġ= Ġcodec . output Buffers ĊĠĠĠĠĠĠĠ Ġval Ġinfo Ġ= ĠMedia Codec . Buffer Info () ĊĠĠĠĠĠĠĠ Ġvar Ġdone _ reading Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvar Ġpresentation _ time : ĠLong Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġval Ġframe _ size Ġ= Ġ 1 0 2 4 Ġ// Ġnumber Ġof Ġsamples Ġper Ġframe Ġper Ġchannel Ġfor Ġan Ġmp 4 Ġ( AAC ) Ġstream . ĊĠĠĠĠĠĠĠ Ġvar Ġbuffer Ġ= ĠByteArray ( frame _ size Ġ* Ġnum Channels Ġ* Ġ 2 ) Ġ// Ġa Ġsample Ġis Ġcoded Ġwith Ġa Ġshort . ĊĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. position ( start Offset ) ĊĠĠĠĠĠĠĠ Ġnum Samples Ġ+= Ġ 2 Ġ* Ġframe _ size Ġ// ĠAdding Ġ 2 Ġframes , ĠC f . Ġpri ming Ġframes Ġfor ĠA AC . ĊĠĠĠĠĠĠĠ Ġvar Ġtot _ num _ frames Ġ= Ġ 1 Ġ+ Ġnum Samples Ġ/ Ġframe _ size Ġ// Ġfirst ĠA AC Ġframe Ġ= Ġ 2 Ġbytes ĊĠĠĠĠĠĠĠ Ġif Ġ( num Samples Ġ% Ġframe _ size Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtot _ num _ frames ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġframe _ sizes Ġ= ĠInt Array ( tot _ num _ frames ) ĊĠĠĠĠĠĠĠ Ġvar Ġnum _ out _ frames Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġnum _ frames Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġnum _ samples _ left Ġ= Ġnum Samples ĊĠĠĠĠĠĠĠ Ġvar Ġencoded Samples Size Ġ= Ġ 0 Ġ// Ġsize Ġof Ġthe Ġoutput Ġbuffer Ġcontaining Ġthe Ġencoded Ġsamples . ĊĠĠĠĠĠĠĠ Ġvar Ġencoded Samples : ĠByteArray ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFeed Ġthe Ġsamples Ġto Ġthe Ġencoder . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinput Buffer Index Ġ= Ġcodec . de queue Input Buffer ( 1 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! done _ reading Ġ&& Ġinput Buffer Index Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( num _ samples _ left Ġ<= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAll Ġsamples Ġhave Ġbeen Ġread . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcodec . queue Input Buffer ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput Buffer Index , Ġ 0 , Ġ 0 , Ġ- 1 , ĠMedia Codec . BUFFER _ FLAG _ END _ OF _ STREAM ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdone _ reading Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput Buffers [ input Buffer Index ]. clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( buffer . size Ġ> Ġinput Buffers [ input Buffer Index ]. remaining ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠInput Ġbuffer Ġis Ġsmaller Ġthan Ġone Ġframe . ĠThis Ġshould Ġnever Ġhappen . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠbufferSize Ġis Ġa Ġhack Ġto Ġcreate Ġa Ġst ereo Ġfile Ġfrom Ġa Ġmono Ġstream . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠbufferSize Ġ= Ġif Ġ( channels Ġ== Ġ 1 ) Ġbuffer . size Ġ/ Ġ 2 Ġelse Ġbuffer . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Decoded Bytes !!. remaining () Ġ< ĠbufferSize ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġm Decoded Bytes !!. remaining () Ġuntil ĠbufferSize ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ i ] Ġ= Ġ 0 Ġ// Ġpad Ġwith Ġextra Ġ 0 s Ġto Ġmake Ġa Ġfull Ġframe . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes ! ![ buffer , Ġ 0 , Ġm Decoded Bytes !!. remaining ()] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes ! ![ buffer , Ġ 0 , ĠbufferSize ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( channels Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġi Ġ= ĠbufferSize Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( i Ġ>= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ 2 Ġ* Ġi Ġ+ Ġ 1 ] Ġ= Ġbuffer [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ 2 Ġ* Ġi ] Ġ= Ġbuffer [ i Ġ- Ġ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ 2 Ġ* Ġi Ġ- Ġ 1 ] Ġ= Ġbuffer [ 2 Ġ* Ġi Ġ+ Ġ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ 2 Ġ* Ġi Ġ- Ġ 2 ] Ġ= Ġbuffer [ 2 Ġ* Ġi ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi Ġ-= Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnum _ samples _ left Ġ-= Ġframe _ size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput Buffers [ input Buffer Index ]. put ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpresentation _ time Ġ= Ġ( num _ frames ++ Ġ* Ġframe _ size Ġ* Ġ 1 e 6 Ġ/ Ġsample Rate ). to Long () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcodec . queue Input Buffer ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput Buffer Index , Ġ 0 , Ġbuffer . size , Ġpresentation _ time , Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġencoded Ġsamples Ġfrom Ġthe Ġencoder . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput Buffer Index Ġ= Ġcodec . de queue Output Buffer ( info , Ġ 1 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( output Buffer Index Ġ>= Ġ 0 Ġ&& Ġinfo . size Ġ> Ġ 0 Ġ&& Ġinfo . presentation Time Us Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( num _ out _ frames Ġ< Ġframe _ sizes . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġframe _ sizes [ num _ out _ frames ++] Ġ= Ġinfo . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( encoded Samples Size Ġ< Ġinfo . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Samples Size Ġ= Ġinfo . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Samples Ġ= ĠByteArray ( encoded Samples Size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Buffers [ output Buffer Index ][ encoded Samples , Ġ 0 , Ġinfo . size ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Buffers [ output Buffer Index ]. clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcodec . release Output Buffer ( output Buffer Index , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( encoded Bytes . remaining () Ġ< Ġinfo . size ) Ġ{ Ġ Ġ// ĠHope fully Ġthis Ġshould Ġnot Ġhappen . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġestimated Encoded Size Ġ= Ġ( estimated Encoded Size Ġ* Ġ 1 . 2 ). toInt () Ġ// ĠAdd Ġ 2 0 %. ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Encoded Bytes Ġ= ĠByteBuffer . allocate ( estimated Encoded Size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġposition Ġ= Ġencoded Bytes . position () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Bytes . rewind () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Encoded Bytes . put ( encoded Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Bytes Ġ= Ġnew Encoded Bytes ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Bytes . position ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Bytes . put ( encoded Samples , Ġ 0 , Ġinfo . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( output Buffer Index Ġ== ĠMedia Codec . INFO _ OUTPUT _ BUFFER S _ CHANGED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Buffers Ġ= Ġcodec . output Buffers ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( output Buffer Index Ġ== ĠMedia Codec . INFO _ OUTPUT _ FORMAT _ CHANGED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSub sequent Ġdata Ġwill Ġconform Ġto Ġnew Ġformat . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġcould Ġcheck Ġthat Ġcodec . getOutput Format (), Ġwhich Ġis Ġthe Ġnew Ġoutput Ġformat , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġis Ġwhat Ġwe Ġexpect . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( info . flags Ġand ĠMedia Codec . BUFFER _ FLAG _ END _ OF _ STREAM Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġgot Ġall Ġthe Ġencoded Ġdata Ġfrom Ġthe Ġencoder . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġencoded _ size Ġ= Ġencoded Bytes . position () ĊĠĠĠĠĠĠĠ Ġencoded Bytes . rewind () ĊĠĠĠĠĠĠĠ Ġcodec . stop () ĊĠĠĠĠĠĠĠ Ġcodec . release () ĊĠĠĠĠĠĠĠ Ġcodec Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġ// ĠWrite Ġthe Ġencoded Ġstream Ġto Ġthe Ġfile , Ġ 4 kB Ġat Ġa Ġtime . ĊĠĠĠĠĠĠĠ Ġbuffer Ġ= ĠByteArray ( 4 0 9 6 ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠoutputStream Ġ= ĠFileOutputStream ( outputFile ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . write ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMP 4 Header . get MP 4 Header ( sample Rate , Ġnum Channels , Ġframe _ sizes , Ġbit rate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( encoded _ size Ġ- Ġencoded Bytes . position () Ġ> Ġbuffer . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Bytes [ buffer ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . write ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremaining Ġ= Ġencoded _ size Ġ- Ġencoded Bytes . position () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( remaining Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencoded Bytes [ buffer , Ġ 0 , Ġremaining ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . write ( buffer , Ġ 0 , Ġremaining ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . close () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e (" Ring d roid ", Ġ" Failed Ġto Ġcreate Ġthe Ġ. m 4 a Ġfile .") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e (" Ring d roid ", Ġget StackTrace ( e )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠMethod Ġused Ġto Ġswap Ġthe Ġleft Ġand Ġright Ġchannels Ġ( needed Ġfor Ġst ereo ĠW AV Ġfiles ). ĊĠĠĠ Ġ// Ġbuffer Ġcontains Ġthe ĠP CM Ġdata : Ġ{ sample Ġ 1 Ġright , Ġsample Ġ 1 Ġleft , Ġsample Ġ 2 Ġright , Ġetc .} ĊĠĠĠ Ġ// ĠThe Ġsize Ġof Ġa Ġsample Ġis Ġassumed Ġto Ġbe Ġ 1 6 Ġbits Ġ( for Ġa Ġsingle Ġchannel ). ĊĠĠĠ Ġ// ĠWhen Ġdone , Ġbuffer Ġwill Ġcontain Ġ{ sample Ġ 1 Ġleft , Ġsample Ġ 1 Ġright , Ġsample Ġ 2 Ġleft , Ġetc .} ĊĠĠĠ Ġprivate Ġfun Ġswap Left Right Channels ( buffer : ĠByteArray ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġleft Ġ= ĠByteArray ( 2 ) ĊĠĠĠĠĠĠĠ Ġval Ġright Ġ= ĠByteArray ( 2 ) ĊĠĠĠĠĠĠĠ Ġif Ġ( buffer . size Ġ% Ġ 4 Ġ!= Ġ 0 ) Ġ{ Ġ Ġ// Ġ 2 Ġchannels , Ġ 2 Ġbytes Ġper Ġsample Ġ( for Ġone Ġchannel ). ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠInvalid Ġbuffer Ġsize . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġoffset Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( offset Ġ< Ġbuffer . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġleft [ 0 ] Ġ= Ġbuffer [ offset ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġleft [ 1 ] Ġ= Ġbuffer [ offset Ġ+ Ġ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġright [ 0 ] Ġ= Ġbuffer [ offset Ġ+ Ġ 2 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġright [ 1 ] Ġ= Ġbuffer [ offset Ġ+ Ġ 3 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ offset ] Ġ= Ġright [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ offset Ġ+ Ġ 1 ] Ġ= Ġright [ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ offset Ġ+ Ġ 2 ] Ġ= Ġleft [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ offset Ġ+ Ġ 3 ] Ġ= Ġleft [ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Ġ+= Ġ 4 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġshould Ġbe Ġremoved Ġin Ġthe Ġnear Ġfuture ... ĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġfun ĠWrite W AV File ( outputFile : ĠFile ?, Ġstart Frame : ĠInt , Ġnum Frames : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠstartTime Ġ= Ġstart Frame . toFloat () Ġ* Ġsamples Per Frame Ġ/ Ġsample Rate ĊĠĠĠĠĠĠĠ Ġval ĠendTime Ġ= Ġ( start Frame Ġ+ Ġnum Frames ) Ġas ĠFloat Ġ* Ġsamples Per Frame Ġ/ Ġsample Rate ĊĠĠĠĠĠĠĠ ĠWrite W AV File ( outputFile , ĠstartTime , ĠendTime ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġfun ĠWrite W AV File ( outputFile : ĠFile ?, ĠstartTime : ĠFloat , ĠendTime : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstart Offset Ġ= Ġ( startTime Ġ* Ġsample Rate ). toInt () Ġ* Ġ 2 Ġ* Ġchannels ĊĠĠĠĠĠĠĠ Ġval Ġnum Samples Ġ= Ġ(( endTime Ġ- ĠstartTime ) Ġ* Ġsample Rate ). toInt () ĊĊĠĠĠĠĠĠĠ Ġ// ĠStart Ġby Ġwriting Ġthe ĠR IFF Ġheader . ĊĠĠĠĠĠĠĠ Ġval ĠoutputStream Ġ= ĠFileOutputStream ( outputFile ) ĊĠĠĠĠĠĠĠ ĠoutputStream . write ( W AV Header . get W AV Header ( sample Rate , Ġchannels , Ġnum Samples )) ĊĊĠĠĠĠĠĠĠ Ġ// ĠWrite Ġthe Ġsamples Ġto Ġthe Ġfile , Ġ 1 0 2 4 Ġat Ġa Ġtime . ĊĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArray ( 1 0 2 4 Ġ* Ġchannels Ġ* Ġ 2 ) Ġ// ĠEach Ġsample Ġis Ġcoded Ġwith Ġa Ġshort . ĊĠĠĠĠĠĠĠ Ġm Decoded Bytes !!. position ( start Offset ) ĊĠĠĠĠĠĠĠ Ġvar Ġnum Bytes Left Ġ= Ġnum Samples Ġ* Ġchannels Ġ* Ġ 2 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( num Bytes Left Ġ>= Ġbuffer . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Decoded Bytes !!. remaining () Ġ< Ġbuffer . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġshould Ġnot Ġhappen . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġm Decoded Bytes !!. remaining () Ġuntil Ġbuffer . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ i ] Ġ= Ġ 0 Ġ// Ġpad Ġwith Ġextra Ġ 0 s Ġto Ġmake Ġa Ġfull Ġframe . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes ! ![ buffer , Ġ 0 , Ġm Decoded Bytes !!. remaining ()] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes ! ![ buffer ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( channels Ġ== Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġswap Left Right Channels ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . write ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnum Bytes Left Ġ-= Ġbuffer . size ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( num Bytes Left Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Decoded Bytes !!. remaining () Ġ< Ġnum Bytes Left ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġshould Ġnot Ġhappen . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġm Decoded Bytes !!. remaining () Ġuntil Ġnum Bytes Left ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ i ] Ġ= Ġ 0 Ġ// Ġpad Ġwith Ġextra Ġ 0 s Ġto Ġmake Ġa Ġfull Ġframe . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes ! ![ buffer , Ġ 0 , Ġm Decoded Bytes !!. remaining ()] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Decoded Bytes ! ![ buffer , Ġ 0 , Ġnum Bytes Left ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( channels Ġ== Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġswap Left Right Channels ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . write ( buffer , Ġ 0 , Ġnum Bytes Left ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠoutputStream . close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠDebug ging Ġmethod Ġdump ing Ġall Ġthe Ġsamples Ġin Ġm Decoded Samples Ġin Ġa ĠT SV Ġfile . ĊĠĠĠ Ġ// ĠEach Ġrow Ġdescribes Ġone Ġsample Ġand Ġhas Ġthe Ġfollowing Ġformat : ĊĠĠĠ Ġ// Ġ"< presentation Ġtime Ġin Ġseconds >\ t < channel Ġ 1 >\ t ...\ t < channel ĠN >\ n " ĊĠĠĠ Ġ// ĠFile Ġwill Ġbe Ġwritten Ġon Ġthe ĠSD Card Ġunder Ġmedia / audio / debug / ĊĠĠĠ Ġ// ĠIf ĠfileName Ġis Ġnull Ġor Ġempty , Ġthen Ġthe Ġdefault Ġfile Ġname Ġ( samples . tsv ) Ġis Ġused . ĊĠĠĠ Ġ// ĠHelper Ġmethod Ġ( samples Ġwill Ġbe Ġdumped Ġin Ġmedia / audio / debug / samples . tsv ). ĊĠĠĠ Ġprivate Ġfun ĠDump Samples ( fileName : ĠString ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar ĠfileName Ġ= ĠfileName ĊĠĠĠĠĠĠĠ Ġvar Ġexternal Root Dir Ġ= ĠEnvironment . get External Storage Directory (). path ĊĠĠĠĠĠĠĠ Ġif Ġ(! external Root Dir . endsWith ("/ ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexternal Root Dir Ġ+= Ġ"/" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġparent Dir Ġ= Ġexternal Root Dir Ġ+ Ġ" media / audio / debug /" ĊĠĠĠĠĠĠĠ Ġ// ĠCreate Ġthe Ġparent Ġdirectory ĊĠĠĠĠĠĠĠ Ġval Ġparent Dir File Ġ= ĠFile ( parent Dir ) ĊĠĠĠĠĠĠĠ Ġparent Dir File . mkdir s () ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġwe Ġcan 't Ġwrite Ġto Ġthat Ġspecial Ġpath , Ġtry Ġjust Ġwriting Ġdirectly Ġto Ġthe ĠSD Card . ĊĠĠĠĠĠĠĠ Ġif Ġ(! parent Dir File . isDirectory ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparent Dir Ġ= Ġexternal Root Dir ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( fileName Ġ== Ġnull Ġ|| ĠfileName . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠfileName Ġ= Ġ" samples . tsv " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġout File Ġ= ĠFile ( parent Dir Ġ+ ĠfileName ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠStart Ġdump ing Ġthe Ġsamples . ĊĠĠĠĠĠĠĠ Ġvar Ġwriter : ĠBuffered Writer ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġpresentation Time Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠ Ġm Decoded Samples !!. rewind () ĊĠĠĠĠĠĠĠ Ġvar Ġrow : ĠString ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwriter Ġ= ĠBuffered Writer ( FileWriter ( out File )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( sample Index Ġin Ġ 0 Ġuntil Ġnum Samples ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpresentation Time Ġ= Ġsample Index . toFloat () Ġ/ Ġsample Rate ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrow Ġ= Ġjava . lang . Float . toString ( presentation Time ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( channel Index Ġin Ġ 0 Ġuntil Ġchannels ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrow Ġ+= Ġ"\ t " Ġ+ Ġm Decoded Samples !!. get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrow Ġ+= Ġ"\ n " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwriter . write ( row ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w (" Ring d roid ", Ġ" Failed Ġto Ġcreate Ġthe Ġsample ĠT SV Ġfile .") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w (" Ring d roid ", Ġget StackTrace ( e )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġare Ġdone Ġhere . ĠClose Ġthe Ġfile Ġand Ġre wind Ġthe Ġbuffer . ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwriter !!. close () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w (" Ring d roid ", Ġ" Failed Ġto Ġclose Ġsample ĠT SV Ġfile .") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w (" Ring d roid ", Ġget StackTrace ( e )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġm Decoded Samples !!. rewind () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠReturn Ġthe Ġstack Ġtrace Ġof Ġa Ġgiven Ġexception . ĊĠĠĠ Ġprivate Ġfun Ġget StackTrace ( e : ĠException ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġwriter Ġ= ĠString Writer () ĊĠĠĠĠĠĠĠ Ġe . printStackTrace ( PrintWriter ( writer )) ĊĠĠĠĠĠĠĠ Ġreturn Ġwriter . toString () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠTODO ( nf ar al li ): Ġwhat Ġis Ġthe Ġreal Ġlist Ġof Ġsupported Ġextensions ? ĠIs Ġit Ġdevice Ġdependent ? ĊĠĠĠĠĠĠĠ Ġval Ġsupported Extensions : ĠArray < String > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget () Ġ= ĠarrayOf (" mp 3 ", Ġ" wav ", Ġ" 3 g pp ", Ġ" 3 gp ", Ġ" am r ", Ġ" aac ", Ġ" m 4 a ", Ġ" ogg ") ĊĊĠĠĠĠĠĠĠ Ġfun Ġis Filename Supported ( filename : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġextensions Ġ= Ġsupported Extensions ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġextensions . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( filename . endsWith (" ." Ġ+ Ġextensions [ i ])) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠCreate Ġand Ġreturn Ġa ĠSound File Ġobject Ġusing Ġthe Ġfile ĠfileName . ĊĠĠĠĠĠĠĠ Ġ@ Throws ( FileNotFoundException :: class , ĠIOException :: class , ĠInvalid Input Exception :: class ) ĊĠĠĠĠĠĠĠ Ġfun Ġcreate ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠfileName : ĠString ?, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprogress Listener : ĠProgress Listener ĊĠĠĠĠĠĠĠ Ġ): ĠSound File ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFirst Ġcheck Ġthat Ġthe Ġfile Ġexists Ġand Ġthat Ġits Ġextension Ġis Ġsupported . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġf Ġ= ĠFile ( fileName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! f . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠFileNotFoundException ( fileName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġf . name . toLowerCase () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcomponents Ġ= Ġname . split ("\\ . "). to Typed Array () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( components . size Ġ< Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! listOf (* supported Extensions ). contains ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomponents [ components . size Ġ- Ġ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsound File Ġ= ĠSound File () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsound File . set Progress Listener ( progress Listener ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsound File . ReadFile ( f ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsound File ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠCreate Ġand Ġreturn Ġa ĠSound File Ġobject Ġby Ġrecording Ġa Ġmono Ġaudio Ġstream . ĊĠĠĠĠĠĠĠ Ġfun Ġrecord ( progress Listener : ĠProgress Listener ?): ĠSound File ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( progress Listener Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġmust Ġhave Ġa Ġpro ge ss Listener Ġto Ġstop Ġthe Ġrecording . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsound File Ġ= ĠSound File () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsound File . set Progress Listener ( progress Listener ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsound File . Record Audio () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsound File ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }