package Ġde . fab max . k ool . modules . audio Ċ Ċ import Ġde . fab max . k ool . math . clamp Ċ import Ġde . fab max . k ool . now Ċ import Ġde . fab max . k ool . util . log E Ċ import Ġjava . io . ByteArray InputStream Ċ import Ġjavax . sound . sampled . Audio System Ċ import Ġjavax . sound . sampled . Clip Ċ import Ġjavax . sound . sampled . Float Control Ċ import Ġjavax . sound . sampled . Line Event Ċ import Ġkotlin . math . log 1 0 Ċ import Ġkotlin . math . pow ĊĊ Ċ actual Ġclass ĠAudio Clip ( private Ġval Ġaudio Data : ĠByteArray ) Ġ{ ĊĊĠĠĠ Ġactual Ġvar Ġmaster Volume Ġ= Ġ 1 f ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlatest Clip . volume Ġ= Ġvolume Ġ* Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġactual Ġvar Ġvolume Ġ= Ġ 1 f ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlatest Clip . volume Ġ= Ġvalue Ġ* Ġmaster Volume ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġactual Ġvar ĠcurrentTime : ĠFloat ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġlatest Clip . currentTime ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlatest Clip . currentTime Ġ= Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġactual Ġval Ġduration : ĠFloat ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġlatest Clip . duration ĊĊĠĠĠ Ġactual Ġval Ġis Ended : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġlatest Clip . clip State Ġ== ĠClip State . STOP PED ĊĊĠĠĠ Ġactual Ġvar Ġloop : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġlatest Clip . loop ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlatest Clip . loop Ġ= Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġactual Ġvar Ġmin Interval Ms : ĠFloat Ġ= ĠMIN _ PLAY _ INTERVAL _ MS ĊĊĠĠĠ Ġprivate Ġval Ġclip Pool Ġ= Ġmutable ListOf ( Clip Wrapper ()) ĊĠĠĠ Ġprivate Ġvar Ġlatest Clip Ġ= Ġclip Pool . first () ĊĠĠĠ Ġprivate Ġvar Ġlast Play Ġ= ĠDouble . NEGATIVE _ INFINITY ĊĊĠĠĠ Ġprivate Ġfun Ġnext Clip (): ĠClip Wrapper Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġclip Pool . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( clip Pool [ i ]. clip State Ġ== ĠClip State . STOP PED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġclip Pool [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( clip Pool . size Ġ< ĠMAX _ CLIP _ POOL _ SIZE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclip Ġ= ĠClip Wrapper () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclip Pool Ġ+= Ġclip ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġclip ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġclip Pool . min By OrNull Ġ{ Ġit . startTime Ġ} !! ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġactual Ġfun Ġplay () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġt Ġ= Ġnow () ĊĠĠĠĠĠĠĠ Ġif Ġ( t Ġ- Ġlast Play Ġ> Ġmin Interval Ms ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Play Ġ= Ġt ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlatest Clip Ġ= Ġnext Clip (). apply Ġ{ Ġplay () Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġactual Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġlatest Clip . stop () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠMIN _ PLAY _ INTERVAL _ MS Ġ= Ġ 1 5 0 f ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠMAX _ CLIP _ POOL _ SIZE Ġ= Ġ 5 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġenum Ġclass ĠClip State Ġ{ ĊĠĠĠĠĠĠĠ ĠSTOP PED , ĊĠĠĠĠĠĠĠ ĠP LAY ING ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinner Ġclass ĠClip Wrapper Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġclip : ĠClip ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġvar Ġvolume : ĠFloat ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgain Control Ġ= Ġclip ?. get Control ( Float Control . Type . MASTER _ GAIN ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( gain Control Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgain Control Ġas ĠFloat Control ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 0 f . pow (( gain Control . value Ġ/ Ġ 2 0 f )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgain Control Ġ= Ġclip ?. get Control ( Float Control . Type . MASTER _ GAIN ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( gain Control Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgain Control Ġas ĠFloat Control ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgain Control . value Ġ= Ġ( 2 0 f Ġ* Ġlog 1 0 ( value )). clamp (- 7 9 . 9 f , Ġ 0 f ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar ĠcurrentTime : ĠFloat ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget () Ġ= Ġ(( clip ?. micro second Position Ġ?: Ġ 0 ) Ġ/ Ġ 1 e 6 ). toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclip ?. micro second Position Ġ= Ġ( value Ġ* Ġ 1 e 6 ). to Long () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġduration : ĠFloat ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget () Ġ= Ġ(( clip ?. micro second Length Ġ?: Ġ 0 ) Ġ/ Ġ 1 e 6 ). toFloat () ĊĊĠĠĠĠĠĠĠ Ġvar Ġloop : ĠBoolean Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclip ?. loop ( Clip . LOOP _ CONT IN UO US LY ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar Ġclip State Ġ= ĠClip State . STOP PED ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠĠĠĠĠ Ġvar ĠstartTime Ġ= Ġ 0 . 0 ĊĊĠĠĠĠĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclip Ġ= ĠAudio System . get Clip () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclip ?. open ( Audio System . get Audio InputStream ( ByteArray InputStream ( audio Data ))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclip ?. add Line Listener Ġ{ Ġline Event Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( line Event . type Ġ== ĠLine Event . Type . STOP ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclip State Ġ= ĠClip State . STOP PED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvolume Ġ= Ġthis @ Audio Clip . volume Ġ* Ġthis @ Audio Clip . master Volume ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog E Ġ{ Ġ" Failed Ġplaying Ġaudio Ġclip : Ġ$ e " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġplay () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclip ?. stop () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠcurrentTime Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclip State Ġ= ĠClip State . PLAY ING ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclip ?. start () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠstartTime Ġ= Ġnow () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclip ?. stop () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }