import Ġkotlinx . coroutines .* Ċ import Ġorg . w 3 c . dom . Document Ċ import Ġorg . w 3 c . dom . HTML Button Element Ċ import Ġorg . w 3 c . dom . HTML InputElement Ċ import Ġkotlin . browser . document Ċ import Ġkotlin . browser . window Ċ Ċ class ĠUi ( doc : ĠDocument ) Ġ{ ĊĊĠĠĠ Ġval Ġstart Btn Ġ= Ġdoc . getElementById (" start Button ") Ġas ĠHTML Button Element ĊĠĠĠ Ġval Ġstop Btn Ġ= Ġdoc . getElementById (" stop Button ") Ġas ĠHTML Button Element ĊĊĠĠĠ Ġval Ġvol D rum Ġ= Ġdoc . getElementById (" dr ums Vol ") Ġas ĠHTML InputElement ĊĠĠĠ Ġval Ġvol B ass Ġ= Ġdoc . getElementById (" b ass Vol ") Ġas ĠHTML InputElement ĊĠĠĠ Ġval Ġvol G uit ar Ġ= Ġdoc . getElementById (" gu itar Vol ") Ġas ĠHTML InputElement ĊĠĠĠ Ġval Ġvol Keys Ġ= Ġdoc . getElementById (" keys Vol ") Ġas ĠHTML InputElement Ċ } Ċ Ċ class ĠAudio Graph ( private Ġval Ġui : ĠUi ) Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġstart Job : ĠJob ? Ġ= Ġnull ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġui . start Btn . onclick Ġ= Ġstart @{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( start Job ?. isActive Ġ== Ġtrue ) Ġreturn @ start Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIt Ġallows Ġto Ġmake Ġstart Ġcancell able ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Job Ġ= ĠGlobal Scope . launch Ġ{ Ġsetup And Play () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġui . stop Btn . onclick Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Job ?. cancel () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġsources : ĠList < Audio Buffer Source Node >? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġcontext : ĠAudio Context ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsetup And Play () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġif Ġ( context Ġ!= Ġnull ) Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġctx Ġ= ĠAudio Context () ĊĊĠĠĠĠĠĠĠ Ġ// ĠPrepare Ġthe Ġtracks : ĊĊĠĠĠĠĠĠĠ Ġval Ġtracks Ġ= Ġcoroutine Scope Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġawait All ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġasync Ġ{ Ġcreate Track (" dr ums . m 4 a ", Ġctx , Ġui . vol D rum ) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġasync Ġ{ Ġcreate Track (" b ass . m 4 a ", Ġctx , Ġui . vol B ass ) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġasync Ġ{ Ġcreate Track (" gu itar . m 4 a ", Ġctx , Ġui . vol G uit ar ) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġasync Ġ{ Ġcreate Track (" keys . m 4 a ", Ġctx , Ġui . vol Keys ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtracks . forEach Ġ{ Ġit . start ( 0 . 0 ) Ġ} ĊĠĠĠĠĠĠĠ Ġsources Ġ= Ġtracks ĊĠĠĠĠĠĠĠ Ġcontext Ġ= Ġctx ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġcreate Track ( ĊĠĠĠĠĠĠĠ Ġclip : ĠString , Ġctx : ĠAudio Context , Ġvol Slider : ĠHTML InputElement ĊĠĠĠ Ġ): ĠAudio Buffer Source Node Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// ĠSetup Ġthe Ġbuffer - source Ġ-> Ġgain Ġ-> Ġaudio Ġout Ġgraph : ĊĊĠĠĠĠĠĠĠ Ġval Ġsource Ġ= Ġctx . create Buffer Source () ĊĠĠĠĠĠĠĠ Ġval Ġgain Ġ= Ġctx . create Gain () ĊĠĠĠĠĠĠĠ Ġsource . connect ( gain ). connect ( ctx . destination ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠHook Ġthe Ġgain Ġvalue Ġto Ġthe Ġprovided Ġslider : ĊĊĠĠĠĠĠĠĠ Ġgain . gain . value Ġ= Ġ 0 . 6 f Ġ// vol Slider . value As Number . toFloat () ĊĊĠĠĠĠĠĠĠ Ġvol Slider . on change Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgain . gain . value Ġ= Ġvol Slider . value As Number . toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUnit ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠLoad Ġthe Ġdesired Ġaudio Ġclip Ġ( GET Ġit Ġand Ġdecode Ġthe Ġraw Ġdata Ġbuffer ): ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġaudio Ġbuffers Ġare Ġre usable , Ġload + decode Ġthem Ġonly Ġonce ĊĊĠĠĠĠĠĠĠ Ġval Ġencoded Data Ġ= Ġwindow . fetch ( clip ). await (). array Buffer (). await () ĊĠĠĠĠĠĠĠ Ġ// Ġonce Ġwe Ġgot Ġthe Ġarray Ġbuffer Ġwith Ġthe Ġclip Ġdata ĊĠĠĠĠĠĠĠ Ġ// Ġwe Ġneed Ġto Ġdecode Ġthat , Ġand Ġset Ġthe Ġresult Ġinto Ġthe ĊĠĠĠĠĠĠĠ Ġ// ĠBuffer Source Node : ĊĠĠĠĠĠĠĠ Ġsource . buffer Ġ= Ġctx . decode Audio Data ( encoded Data ). await () ĊĠĠĠĠĠĠĠ Ġsource . loop Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsource ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġsources ?. forEach Ġ{ Ġit . stop () Ġ} ĊĠĠĠĠĠĠĠ Ġsources Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġcontext ?. close () ĊĠĠĠĠĠĠĠ Ġcontext Ġ= Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġmain () Ġ{ ĊĠĠĠ Ġwindow . onload Ġ= Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġui Ġ= ĠUi ( document ) ĊĠĠĠĠĠĠĠ ĠAudio Graph ( ui ) ĊĠĠĠ Ġ} Ċ }