@pipecat-ai/daily-transport 0.3.6 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/index.module.js +7 -0
- package/dist/index.module.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;
|
|
1
|
+
{"mappings":";;AS8BA;IACE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;IACE,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAED;IACE,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;CACpD;AAoDD,2BAA4B,SAAQ,SAAS;gBAiB/B,EACV,mBAAwB,EACxB,6BAAqC,GACtC,GAAE,gCAAqC;IAoBxC,qBAAqB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IA2B9C,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,IAAI;IAoBxC,UAAU,CACf,OAAO,EAAE,iBAAiB,EAC1B,cAAc,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,GACxC,IAAI;IA8BP,IAAI,eAAe,IAAI,SAAS,CAE/B;IAED,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,OAAO,KAAK,KAAK,QAKhB;IAEK,UAAU;IAKhB,SAAS,CAAC,KAAK,EAAE,MAAM;IAUvB,IAAI,WAAW,4CAEd;IAEK,UAAU;IAKhB,SAAS,CAAC,KAAK,EAAE,MAAM;IAUvB,IAAI,WAAW,4CAEd;IAEK,cAAc;IAKpB,aAAa,CAAC,SAAS,EAAE,MAAM;IAQ/B,IAAI,eAAe,4CAElB;IAED,SAAS,CAAC,MAAM,EAAE,OAAO;IAIzB,IAAI,YAAY,YAEf;IAED,SAAS,CAAC,MAAM,EAAE,OAAO;IAIzB,IAAI,YAAY,YAEf;IAEM,iBAAiB,CAAC,MAAM,EAAE,OAAO;IAQxC,IAAW,eAAe,IAAI,OAAO,CAEpC;IAED,MAAM;IA0CA,OAAO,CAAC,mBAAmB,EAAE,mBAAmB;IAKhD,WAAW;IAgCX,OAAO,CACX,UAAU,EAAE,wBAAwB,EACpC,eAAe,EAAE,eAAe;IAmC5B,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA4DjC,UAAU;IAYT,WAAW,CAAC,OAAO,EAAE,WAAW;CAiLxC","sources":["transports/lib/wavtools/lib/wav_packer.js","transports/lib/wavtools/lib/analysis/constants.js","transports/lib/wavtools/lib/analysis/audio_analysis.js","transports/lib/wavtools/lib/worklets/stream_processor.js","transports/lib/wavtools/lib/wav_stream_player.js","transports/lib/wavtools/lib/worklets/audio_processor.js","transports/lib/wavtools/lib/wav_recorder.js","transports/lib/wavtools/lib/mediastream_recorder.js","transports/lib/wavtools/index.js","transports/daily/src/src/transport.ts","transports/daily/src/src/index.ts","transports/daily/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,"export * from \"./transport\";\n"],"names":[],"version":3,"file":"index.d.ts.map"}
|
package/dist/index.js
CHANGED
|
@@ -1749,6 +1749,7 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
|
|
|
1749
1749
|
this._daily.on("remote-participants-audio-level", this.handleRemoteAudioLevel.bind(this));
|
|
1750
1750
|
this._daily.on("app-message", this.handleAppMessage.bind(this));
|
|
1751
1751
|
this._daily.on("left-meeting", this.handleLeftMeeting.bind(this));
|
|
1752
|
+
this._daily.on("error", this.handleFatalError.bind(this));
|
|
1752
1753
|
this._daily.on("nonfatal-error", this.handleNonFatalError.bind(this));
|
|
1753
1754
|
}
|
|
1754
1755
|
async disconnect() {
|
|
@@ -1854,6 +1855,12 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
|
|
|
1854
1855
|
this._botId = "";
|
|
1855
1856
|
this._callbacks.onDisconnected?.();
|
|
1856
1857
|
}
|
|
1858
|
+
handleFatalError(ev) {
|
|
1859
|
+
(0, $jrPAn$pipecataiclientjs.logger).error("Daily fatal error", ev.errorMsg);
|
|
1860
|
+
this.state = "error";
|
|
1861
|
+
this._botId = "";
|
|
1862
|
+
this._callbacks.onError?.((0, $jrPAn$pipecataiclientjs.RTVIMessage).error(ev.errorMsg, true));
|
|
1863
|
+
}
|
|
1857
1864
|
handleNonFatalError(ev) {
|
|
1858
1865
|
switch(ev.type){
|
|
1859
1866
|
case "screen-share-error":
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AGAA;;;;;;;;CAQC,GAED;;;CAGC,GACM,MAAM;IACX;;;;GAIC,GACD,OAAO,gBAAgB,YAAY,EAAE;QACnC,MAAM,SAAS,IAAI,YAAY,aAAa,MAAM,GAAG;QACrD,MAAM,OAAO,IAAI,SAAS;QAC1B,IAAI,SAAS;QACb,IAAK,IAAI,IAAI,GAAG,IAAI,aAAa,MAAM,EAAE,KAAK,UAAU,EAAG;YACzD,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,GAAG,YAAY,CAAC,EAAE;YAChD,KAAK,QAAQ,CAAC,QAAQ,IAAI,IAAI,IAAI,SAAS,IAAI,QAAQ;QACzD;QACA,OAAO;IACT;IAEA;;;;;GAKC,GACD,OAAO,aAAa,UAAU,EAAE,WAAW,EAAE;QAC3C,MAAM,WAAW,IAAI,WACnB,WAAW,UAAU,GAAG,YAAY,UAAU;QAEhD,SAAS,GAAG,CAAC,IAAI,WAAW,aAAa;QACzC,SAAS,GAAG,CAAC,IAAI,WAAW,cAAc,WAAW,UAAU;QAC/D,OAAO,SAAS,MAAM;IACxB;IAEA;;;;;;GAMC,GACD,UAAU,IAAI,EAAE,GAAG,EAAE;QACnB,OAAO;YACL,IAAI,WAAW;gBAAC;gBAAK,OAAO;aAAE;YAC9B,IAAI,WAAW;gBAAC;gBAAK,OAAO;gBAAG,OAAO;gBAAI,OAAO;aAAG;SACrD,CAAC,KAAK;IACT;IAEA;;;;;GAKC,GACD,KAAK,UAAU,EAAE,KAAK,EAAE;QACtB,IAAI,CAAC,OAAO,eACV,MAAM,IAAI,MAAM,CAAC,uBAAuB,CAAC;aACpC,IAAI,CAAC,OAAO,UACjB,MAAM,IAAI,MAAM,CAAC,kBAAkB,CAAC;aAC/B,IAAI,CAAC,OAAO,MACjB,MAAM,IAAI,MAAM,CAAC,cAAc,CAAC;QAElC,MAAM,iBAAE,aAAa,YAAE,QAAQ,QAAE,IAAI,EAAE,GAAG;QAC1C,MAAM,SAAS;YACb,SAAS;YACT;YACA,IAAI,CAAC,SAAS,CACZ,GACA;YAEF;YACA,UAAU;YACV;YACA,IAAI,CAAC,SAAS,CAAC,GAAG;YAClB,IAAI,CAAC,SAAS,CAAC,GAAG;YAClB,IAAI,CAAC,SAAS,CAAC,GAAG,SAAS,MAAM;YACjC,IAAI,CAAC,SAAS,CAAC,GAAG;YAClB,IAAI,CAAC,SAAS,CAAC,GAAG,AAAC,aAAa,SAAS,MAAM,GAAG,gBAAiB;YACnE,IAAI,CAAC,SAAS,CAAC,GAAG,AAAC,SAAS,MAAM,GAAG,gBAAiB;YACtD,IAAI,CAAC,SAAS,CAAC,GAAG;YAClB,UAAU;YACV;YACA,IAAI,CAAC,SAAS,CACZ,GACA,AAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,GAAG,SAAS,MAAM,GAAG,gBAAiB;YAE3D;SACD;QACD,MAAM,OAAO,IAAI,KAAK,QAAQ;YAAE,MAAM;QAAa;QACnD,MAAM,MAAM,IAAI,eAAe,CAAC;QAChC,OAAO;kBACL;iBACA;YACA,cAAc,SAAS,MAAM;wBAC7B;YACA,UAAU,KAAK,UAAU,GAAI,CAAA,SAAS,MAAM,GAAG,aAAa,CAAA;QAC9D;IACF;AACF;AAEA,WAAW,SAAS,GAAG;;;AEhHvB;;;;;CAKC,GAED,4BAA4B;AAC5B,MAAM,2CAAqB;IACzB;IAAS;IAAS;IAAS;IAAS;IAAS;IAAS;IAAS;IAC/D;IAAS;IAAQ;IAAS;CAC3B;AAED,2CAA2C;AAC3C,MAAM,+CAAyB;IAC7B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAMM,MAAM,4CAAkB,EAAE;AAC1B,MAAM,4CAAsB,EAAE;AACrC,IAAK,IAAI,IAAI,GAAG,KAAK,GAAG,IACtB,IAAK,IAAI,IAAI,GAAG,IAAI,yCAAmB,MAAM,EAAE,IAAK;IAClD,MAAM,OAAO,wCAAkB,CAAC,EAAE;IAClC,0CAAgB,IAAI,CAAC,OAAO,KAAK,GAAG,CAAC,GAAG,IAAI;IAC5C,0CAAoB,IAAI,CAAC,4CAAsB,CAAC,EAAE,GAAG;AACvD;AAGF;;;CAGC,GACD,MAAM,4CAAsB;IAAC;IAAM;CAAO;AACnC,MAAM,4CAAmB,0CAAgB,MAAM,CAAC,CAAC,GAAG;IACzD,OACE,yCAAe,CAAC,EAAE,GAAG,yCAAmB,CAAC,EAAE,IAC3C,yCAAe,CAAC,EAAE,GAAG,yCAAmB,CAAC,EAAE;AAE/C;AACO,MAAM,4CAAuB,0CAAoB,MAAM,CAAC,CAAC,GAAG;IACjE,OACE,yCAAe,CAAC,EAAE,GAAG,yCAAmB,CAAC,EAAE,IAC3C,yCAAe,CAAC,EAAE,GAAG,yCAAmB,CAAC,EAAE;AAE/C;;;ADxCO,MAAM;IACX;;;;;;;;;;GAUC,GACD,OAAO,eACL,QAAQ,EACR,UAAU,EACV,SAAS,EACT,eAAe,WAAW,EAC1B,cAAc,IAAI,EAClB,cAAc,GAAG,EACjB;QACA,IAAI,CAAC,WAAW;YACd,YAAY,IAAI,aAAa,SAAS,iBAAiB;YACvD,SAAS,qBAAqB,CAAC;QACjC;QACA,MAAM,mBAAmB,aAAa;QACtC,MAAM,gBAAgB,AAAC,IAAI,UAAU,MAAM,GAAI;QAC/C,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI,iBAAiB,WAAW,iBAAiB,SAAS;YACxD,MAAM,iBACJ,iBAAiB,UAAU,CAAA,GAAA,yCAAe,IAAI,CAAA,GAAA,yCAAc;YAC9D,MAAM,kBAAkB,MAAM,eAAe,MAAM,EAAE,IAAI,CAAC;YAC1D,IAAK,IAAI,IAAI,GAAG,IAAI,UAAU,MAAM,EAAE,IAAK;gBACzC,MAAM,YAAY,IAAI;gBACtB,MAAM,YAAY,SAAS,CAAC,EAAE;gBAC9B,IAAK,IAAI,IAAI,eAAe,MAAM,GAAG,GAAG,KAAK,GAAG,IAC9C,IAAI,YAAY,cAAc,CAAC,EAAE,EAAE;oBACjC,eAAe,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC,eAAe,CAAC,EAAE,EAAE;oBAClD;gBACF;YAEJ;YACA,eAAe;YACf,cACE,iBAAiB,UAAU,CAAA,GAAA,yCAAe,IAAI,CAAA,GAAA,yCAAc;YAC9D,SACE,iBAAiB,UAAU,CAAA,GAAA,yCAAmB,IAAI,CAAA,GAAA,yCAAkB;QACxE,OAAO;YACL,eAAe,MAAM,IAAI,CAAC;YAC1B,cAAc,aAAa,GAAG,CAAC,CAAC,GAAG,IAAM,gBAAgB;YACzD,SAAS,YAAY,GAAG,CAAC,CAAC,IAAM,GAAG,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC;QACtD;QACA,yBAAyB;QACzB,MAAM,mBAAmB,aAAa,GAAG,CAAC,CAAC;YACzC,OAAO,KAAK,GAAG,CACb,GACA,KAAK,GAAG,CAAC,AAAC,CAAA,IAAI,WAAU,IAAM,CAAA,cAAc,WAAU,GAAI;QAE9D;QACA,MAAM,SAAS,IAAI,aAAa;QAChC,OAAO;oBACL;yBACA;oBACA;QACF;IACF;IAEA;;;;;GAKC,GACD,YAAY,YAAY,EAAE,cAAc,IAAI,CAAE;QAC5C,IAAI,CAAC,UAAU,GAAG,EAAE;QACpB,IAAI,aAAa;YACf;;;;;;;OAOC,GACD,MAAM,UAAE,MAAM,cAAE,UAAU,EAAE,GAAG;YAC/B,MAAM,sBAAsB,IAAI,oBAAoB;wBAClD;4BACA;YACF;YACA,MAAM,SAAS,oBAAoB,kBAAkB;YACrD,OAAO,MAAM,GAAG;YAChB,MAAM,WAAW,oBAAoB,cAAc;YACnD,SAAS,OAAO,GAAG;YACnB,SAAS,qBAAqB,GAAG;YACjC,OAAO,OAAO,CAAC;YACf,gCAAgC;YAChC,2DAA2D;YAC3D,MAAM,yBAAyB,IAAI;YACnC,MAAM,oBAAoB,SAAS;YACnC,MAAM,UAAU,CAAC;gBACf,MAAM,cAAc,yBAAyB;gBAC7C,IAAI,cAAc,mBAChB,oBAAoB,OAAO,CAAC,aAAa,IAAI,CAAC;oBAC5C,MAAM,YAAY,IAAI,aAAa,SAAS,iBAAiB;oBAC7D,SAAS,qBAAqB,CAAC;oBAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;oBACrB,QAAQ,QAAQ;gBAClB;gBAEF,IAAI,UAAU,GACZ,oBAAoB,cAAc;qBAElC,oBAAoB,MAAM;YAE9B;YACA,OAAO,KAAK,CAAC;YACb,QAAQ;YACR,IAAI,CAAC,KAAK,GAAG;YACb,IAAI,CAAC,OAAO,GAAG;YACf,IAAI,CAAC,QAAQ,GAAG;YAChB,IAAI,CAAC,UAAU,GAAG;YAClB,IAAI,CAAC,WAAW,GAAG;QACrB,OAAO;YACL,MAAM,eAAe,IAAI;YACzB,MAAM,QAAQ,aAAa,wBAAwB,CAAC;YACpD,MAAM,WAAW,aAAa,cAAc;YAC5C,SAAS,OAAO,GAAG;YACnB,SAAS,qBAAqB,GAAG;YACjC,MAAM,OAAO,CAAC;YACd,SAAS,OAAO,CAAC,aAAa,WAAW;YACzC,IAAI,CAAC,KAAK,GAAG;YACb,IAAI,CAAC,OAAO,GAAG;YACf,IAAI,CAAC,QAAQ,GAAG;YAChB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU;YACzC,IAAI,CAAC,WAAW,GAAG;QACrB;IACF;IAEA;;;;;;GAMC,GACD,eACE,eAAe,WAAW,EAC1B,cAAc,IAAI,EAClB,cAAc,GAAG,EACjB;QACA,IAAI,YAAY;QAChB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAC9C,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ;YACxD,MAAM,QAAQ,KAAK,GAAG,CACpB,AAAC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,GAAI,GACjC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG;YAE3B,YAAY,IAAI,CAAC,UAAU,CAAC,MAAM;QACpC;QACA,OAAO,0CAAc,cAAc,CACjC,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,UAAU,EACf,WACA,cACA,aACA;IAEJ;IAEA;;;;GAIC,GACD,MAAM,oBAAoB;QACxB,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,aACzB,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM;QAE3B,OAAO;IACT;AACF;AAEA,WAAW,aAAa,GAAG;;;AG1MpB,MAAM,2CAAyB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyFvC,CAAC;AAED,MAAM,+BAAS,IAAI,KAAK;IAAC;CAAuB,EAAE;IAChD,MAAM;AACR;AACA,MAAM,4BAAM,IAAI,eAAe,CAAC;AACzB,MAAM,4CAAqB;;;;ADxF3B,MAAM;IACX;;;;GAIC,GACD,YAAY,cAAE,aAAa,OAAO,GAAG,CAAC,CAAC,CAAE;QACvC,IAAI,CAAC,SAAS,GAAG,CAAA,GAAA,yCAAiB;QAClC,IAAI,CAAC,UAAU,GAAG;QAClB,IAAI,CAAC,OAAO,GAAG;QACf,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,QAAQ,GAAG;QAChB,IAAI,CAAC,kBAAkB,GAAG,CAAC;QAC3B,IAAI,CAAC,mBAAmB,GAAG,CAAC;IAC9B;IAEA;;;GAGC,GACD,MAAM,UAAU;QACd,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa;YAAE,YAAY,IAAI,CAAC,UAAU;QAAC;QAC9D,IAAI,IAAI,CAAC,UAAU,EACjB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU;QAExC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,aACzB,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM;QAE3B,IAAI;YACF,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS;QAC1D,EAAE,OAAO,GAAG;YACV,QAAQ,KAAK,CAAC;YACd,MAAM,IAAI,MAAM,CAAC,mCAAmC,EAAE,IAAI,CAAC,SAAS,EAAE;QACxE;QACA,MAAM,WAAW,IAAI,CAAC,OAAO,CAAC,cAAc;QAC5C,SAAS,OAAO,GAAG;QACnB,SAAS,qBAAqB,GAAG;QACjC,IAAI,CAAC,QAAQ,GAAG;QAChB,OAAO;IACT;IAEA;;;;;;GAMC,GACD,eACE,eAAe,WAAW,EAC1B,cAAc,IAAI,EAClB,cAAc,GAAG,EACjB;QACA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAChB,MAAM,IAAI,MAAM;QAElB,OAAO,CAAA,GAAA,yCAAY,EAAE,cAAc,CACjC,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,UAAU,EACf,MACA,cACA,aACA;IAEJ;IAEA;;GAEC,GACD,MAAM,cAAc,OAAO,EAAE;QAC3B,MAAM,eAAe,IAAI,CAAC,UAAU;QACpC,IAAI,CAAC,UAAU,GAAG;QAClB,IAAI,IAAI,CAAC,OAAO,EACd,IAAI;YACF,IAAI,YAAY,WACd,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS;iBAE5B,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;QAEjC,EAAE,OAAO,GAAG;YACV,QAAQ,KAAK,CAAC,CAAC,wBAAwB,EAAE,QAAQ,EAAE,EAAE,GAAG;YACxD,IAAI,CAAC,UAAU,GAAG;QACpB;IAEJ;IAEA;;;;GAIC,GACD,SAAS;QACP,MAAM,aAAa,IAAI,iBAAiB,IAAI,CAAC,OAAO,EAAE;QACtD,WAAW,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW;QAC3C,WAAW,IAAI,CAAC,SAAS,GAAG,CAAC;YAC3B,MAAM,SAAE,KAAK,EAAE,GAAG,EAAE,IAAI;YACxB,IAAI,UAAU,QAAQ;gBACpB,WAAW,UAAU;gBACrB,IAAI,CAAC,MAAM,GAAG;YAChB,OAAO,IAAI,UAAU,UAAU;gBAC7B,MAAM,aAAE,SAAS,WAAE,OAAO,UAAE,MAAM,EAAE,GAAG,EAAE,IAAI;gBAC7C,MAAM,cAAc,SAAS,IAAI,CAAC,UAAU;gBAC5C,IAAI,CAAC,kBAAkB,CAAC,UAAU,GAAG;6BAAE;4BAAS;iCAAQ;gBAAY;YACtE;QACF;QACA,IAAI,CAAC,QAAQ,CAAC,UAAU;QACxB,WAAW,OAAO,CAAC,IAAI,CAAC,QAAQ;QAChC,IAAI,CAAC,MAAM,GAAG;QACd,OAAO;IACT;IAEA;;;;;;GAMC,GACD,YAAY,WAAW,EAAE,UAAU,SAAS,EAAE;QAC5C,IAAI,OAAO,YAAY,UACrB,MAAM,IAAI,MAAM,CAAC,wBAAwB,CAAC;aACrC,IAAI,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAC1C;QAEF,IAAI,CAAC,IAAI,CAAC,MAAM,EACd,IAAI,CAAC,MAAM;QAEb,IAAI;QACJ,IAAI,uBAAuB,YACzB,SAAS;aACJ,IAAI,uBAAuB,aAChC,SAAS,IAAI,WAAW;aAExB,MAAM,IAAI,MAAM,CAAC,0CAA0C,CAAC;QAE9D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;YAAE,OAAO;oBAAS;qBAAQ;QAAQ;QAC/D,OAAO;IACT;IAEA;;;;GAIC,GACD,MAAM,qBAAqB,YAAY,KAAK,EAAE;QAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,EACd,OAAO;QAET,MAAM,YAAY,OAAO,UAAU;QACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;YAC3B,OAAO,YAAY,cAAc;uBACjC;QACF;QACA,IAAI;QACJ,MAAO,CAAC,kBAAmB;YACzB,oBAAoB,IAAI,CAAC,kBAAkB,CAAC,UAAU;YACtD,MAAM,IAAI,QAAQ,CAAC,IAAM,WAAW,IAAM,KAAK;QACjD;QACA,MAAM,WAAE,OAAO,EAAE,GAAG;QACpB,IAAI,aAAa,SACf,IAAI,CAAC,mBAAmB,CAAC,QAAQ,GAAG;QAEtC,OAAO;IACT;IAEA;;;;GAIC,GACD,MAAM,YAAY;QAChB,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC;AACF;AAEA,WAAW,eAAe,GAAG;;;AGtL7B,MAAM,8CAAwB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+M/B,CAAC;AAED,MAAM,+BAAS,IAAI,KAAK;IAAC;CAAsB,EAAE;IAC/C,MAAM;AACR;AACA,MAAM,4BAAM,IAAI,eAAe,CAAC;AACzB,MAAM,4CAAoB;;;;;ADpM1B,MAAM;IACX;;;;GAIC,GACD,YAAY,cACV,aAAa,yBACb,mBAAmB,cACnB,QAAQ,OACT,GAAG,CAAC,CAAC,CAAE;QACN,gBAAgB;QAChB,IAAI,CAAC,SAAS,GAAG,CAAA,GAAA,yCAAgB;QACjC,SAAS;QACT,IAAI,CAAC,UAAU,GAAG;QAClB,IAAI,CAAC,gBAAgB,GAAG;QACxB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,qBAAqB,GAAG;QAC7B,IAAI,CAAC,QAAQ,GAAG,EAAE;QAClB,IAAI,CAAC,eAAe,GAAG;QACvB,kBAAkB;QAClB,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,SAAS,GAAG;QACjB,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,SAAS,GAAG;QACjB,mCAAmC;QACnC,IAAI,CAAC,YAAY,GAAG;QACpB,IAAI,CAAC,aAAa,GAAG,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG;QACpB,0BAA0B;QAC1B,IAAI,CAAC,eAAe,GAAG,KAAO;QAC9B,IAAI,CAAC,mBAAmB,GAAG,KAAK;QAChC,IAAI,CAAC,qBAAqB,GAAG;YAC3B,KAAK,IAAI,YAAY;YACrB,MAAM,IAAI,YAAY;QACxB;IACF;IAEA;;;;;;GAMC,GACD,aAAa,OAAO,SAAS,EAAE,aAAa,KAAK,EAAE,iBAAiB,EAAE,EAAE;QACtE,MAAM,UAAU,IAAI,aAAa;wBAAE;QAAW;QAC9C,IAAI;QACJ,IAAI;QACJ,IAAI,qBAAqB,MAAM;YAC7B,IAAI,mBAAmB,IACrB,MAAM,IAAI,MACR,CAAC,uDAAuD,CAAC;YAG7D,OAAO;YACP,cAAc,MAAM,KAAK,WAAW;QACtC,OAAO,IAAI,qBAAqB,aAAa;YAC3C,IAAI,mBAAmB,IACrB,MAAM,IAAI,MACR,CAAC,8DAA8D,CAAC;YAGpE,cAAc;YACd,OAAO,IAAI,KAAK;gBAAC;aAAY,EAAE;gBAAE,MAAM;YAAY;QACrD,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,IAAI,qBAAqB,YAAY;gBACnC,OAAO;gBACP,eAAe,IAAI,aAAa,UAAU,MAAM;gBAChD,IAAK,IAAI,IAAI,GAAG,IAAI,UAAU,MAAM,EAAE,IACpC,YAAY,CAAC,EAAE,GAAG,SAAS,CAAC,EAAE,GAAG;YAErC,OAAO,IAAI,qBAAqB,cAC9B,eAAe;iBACV,IAAI,qBAAqB,OAC9B,eAAe,IAAI,aAAa;iBAEhC,MAAM,IAAI,MACR,CAAC,uFAAuF,CAAC;YAG7F,IAAI,mBAAmB,IACrB,MAAM,IAAI,MACR,CAAC,gFAAgF,CAAC;iBAE/E,IAAI,iBAAiB,MAC1B,MAAM,IAAI,MAAM,CAAC,uCAAuC,CAAC;YAE3D,IAAI,CAAC,MACH,OAAO,CAAA,GAAA,yCAAQ,EAAE,eAAe,CAAC;YAEnC,MAAM,QAAQ;gBACZ,eAAe;gBACf,UAAU;oBAAC;iBAAa;sBACxB;YACF;YACA,MAAM,SAAS,IAAI,CAAA,GAAA,yCAAQ;YAC3B,MAAM,SAAS,OAAO,IAAI,CAAC,gBAAgB;YAC3C,OAAO,OAAO,IAAI;YAClB,cAAc,MAAM,KAAK,WAAW;QACtC;QACA,MAAM,cAAc,MAAM,QAAQ,eAAe,CAAC;QAClD,MAAM,SAAS,YAAY,cAAc,CAAC;QAC1C,MAAM,MAAM,IAAI,eAAe,CAAC;QAChC,OAAO;kBACL;iBACA;oBACA;yBACA;QACF;IACF;IAEA;;;;GAIC,GACD,MAAM;QACJ,IAAI,IAAI,CAAC,KAAK,EACZ,IAAI,CAAC,GAAG,IAAI;QAEd,OAAO;IACT;IAEA;;;GAGC,GACD,gBAAgB;QACd,OAAO,IAAI,CAAC,UAAU;IACxB;IAEA;;;GAGC,GACD,YAAY;QACV,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,OAAO;aACF,IAAI,CAAC,IAAI,CAAC,SAAS,EACxB,OAAO;aAEP,OAAO;IAEX;IAEA;;;;;;;GAOC,GACD,MAAM,OAAO,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,aAAa,IAAI,EAAE;QAC/C,aAAa,cAAc,IAAI,CAAC,SAAS;QACzC,IAAI,CAAC,YACH,MAAM,IAAI,MAAM;QAElB,MAAM,UAAU;YACd,OAAO;YACP,IAAI,IAAI,CAAC,YAAY;kBACrB;QACF;QACA,WAAW,IAAI,CAAC,WAAW,CAAC;QAC5B,MAAM,KAAK,IAAI,OAAO,OAAO;QAC7B,MAAO,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAE;YACtC,IAAI,IAAI,OAAO,OAAO,KAAK,KAAK,IAAI,CAAC,YAAY,EAC/C,MAAM,IAAI,MAAM,CAAC,qBAAqB,EAAE,KAAK,OAAO,CAAC;YAEvD,MAAM,IAAI,QAAQ,CAAC,MAAQ,WAAW,IAAM,IAAI,OAAO;QACzD;QACA,MAAM,UAAU,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;QACrC,OAAO;IACT;IAEA;;;;GAIC,GACD,sBAAsB,QAAQ,EAAE;QAC9B,IAAI,aAAa,QAAQ,IAAI,CAAC,qBAAqB,EAAE;YACnD,UAAU,YAAY,CAAC,mBAAmB,CACxC,gBACA,IAAI,CAAC,qBAAqB;YAE5B,IAAI,CAAC,qBAAqB,GAAG;QAC/B,OAAO,IAAI,aAAa,MAAM;YAC5B,0EAA0E;YAC1E,6DAA6D;YAC7D,0CAA0C;YAC1C,IAAI,SAAS;YACb,IAAI,cAAc,EAAE;YACpB,MAAM,mBAAmB,CAAC,UACxB,QACG,GAAG,CAAC,CAAC,IAAM,EAAE,QAAQ,EACrB,IAAI,GACJ,IAAI,CAAC;YACV,MAAM,KAAK;gBACT,IAAI,KAAK,EAAE;gBACX,MAAM,UAAU,MAAM,IAAI,CAAC,WAAW;gBACtC,IAAI,OAAO,QACT;oBAAA,IAAI,iBAAiB,iBAAiB,iBAAiB,UAAU;wBAC/D,cAAc;wBACd,SAAS,QAAQ,KAAK;oBACxB;gBAAA;YAEJ;YACA,UAAU,YAAY,CAAC,gBAAgB,CAAC,gBAAgB;YACxD;YACA,IAAI,CAAC,qBAAqB,GAAG;QAC/B;QACA,OAAO;IACT;IAEA;;;GAGC,GACD,MAAM,oBAAoB;QACxB,MAAM,mBAAmB,MAAM,UAAU,WAAW,CAAC,KAAK,CAAC;YACzD,MAAM;QACR;QACA,IAAI,iBAAiB,KAAK,KAAK,UAC7B,OAAO,KAAK,CAAC;aACR,IAAI,iBAAiB,KAAK,KAAK,UACpC,IAAI;YACF,MAAM,SAAS,MAAM,UAAU,YAAY,CAAC,YAAY,CAAC;gBACvD,OAAO;YACT;YACA,MAAM,SAAS,OAAO,SAAS;YAC/B,OAAO,OAAO,CAAC,CAAC,QAAU,MAAM,IAAI;QACtC,EAAE,OAAO,GAAG;YACV,OAAO,KAAK,CAAC;QACf;QAEF,OAAO;IACT;IAEA;;;GAGC,GACD,MAAM,cAAc;QAClB,IACE,CAAC,UAAU,YAAY,IACvB,CAAE,CAAA,sBAAsB,UAAU,YAAY,AAAD,GAE7C,MAAM,IAAI,MAAM;QAElB,MAAM,IAAI,CAAC,iBAAiB;QAC5B,MAAM,UAAU,MAAM,UAAU,YAAY,CAAC,gBAAgB;QAC7D,MAAM,eAAe,QAAQ,MAAM,CACjC,CAAC,SAAW,OAAO,IAAI,KAAK;QAE9B,OAAO;IACP,qDAAqD;IACrD,8CAA8C;IAC9C,KAAK;IACL,yBAAyB;IACzB,mCAAmC;IACnC,uEAAuE;IACvE,gDAAgD;IAChD,2DAA2D;IAC3D,OAAO;IACP,gCAAgC;IAChC,gEAAgE;IAChE,MAAM;IACN,kCAAkC;IAClC,oCAAoC;IACpC,IAAI;IACJ,0CAA0C;IAC5C;IAEA;;;;;GAKC,GACD,MAAM,MAAM,QAAQ,EAAE;QACpB,IAAI,IAAI,CAAC,SAAS,EAChB,MAAM,IAAI,MACR,CAAC,4DAA4D,CAAC;QAIlE,IACE,CAAC,UAAU,YAAY,IACvB,CAAE,CAAA,kBAAkB,UAAU,YAAY,AAAD,GAEzC,MAAM,IAAI,MAAM;QAElB,WAAW,YAAY,IAAI,CAAC,eAAe,EAAE;QAC7C,IAAI;YACF,MAAM,SAAS;gBAAE,OAAO;YAAK;YAC7B,IAAI,UACF,OAAO,KAAK,GAAG;gBAAE,UAAU;oBAAE,OAAO;gBAAS;YAAE;YAEjD,IAAI,CAAC,MAAM,GAAG,MAAM,UAAU,YAAY,CAAC,YAAY,CAAC;QAC1D,EAAE,OAAO,KAAK;YACZ,MAAM,IAAI,MAAM;QAClB;QAEA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;YACvB,WAAW,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,WAAW,GAAG,QAAQ;YACjE,QAAQ,GAAG,CACT,uBACA,SACA,UACA,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,WAAW;YAE7C,IAAI,CAAC,eAAe,GAAG,QAAQ,IAAI,CAAC,CAAC,IAAM,EAAE,QAAQ,KAAK;YAC1D,QAAQ,GAAG,CAAC,kBAAkB,IAAI,CAAC,eAAe;QACpD;QACA,MAAM,UAAU,IAAI,aAAa;YAAE,YAAY,IAAI,CAAC,UAAU;QAAC;QAC/D,MAAM,SAAS,QAAQ,uBAAuB,CAAC,IAAI,CAAC,MAAM;QAC1D,sCAAsC;QACtC,IAAI;YACF,MAAM,QAAQ,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS;QACrD,EAAE,OAAO,GAAG;YACV,QAAQ,KAAK,CAAC;YACd,MAAM,IAAI,MAAM,CAAC,mCAAmC,EAAE,IAAI,CAAC,SAAS,EAAE;QACxE;QACA,MAAM,YAAY,IAAI,iBAAiB,SAAS;QAChD,UAAU,IAAI,CAAC,SAAS,GAAG,CAAC;YAC1B,MAAM,SAAE,KAAK,MAAE,EAAE,QAAE,IAAI,EAAE,GAAG,EAAE,IAAI;YAClC,IAAI,UAAU,WACZ,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG;iBACpB,IAAI,UAAU;gBACnB,IAAI,IAAI,CAAC,mBAAmB,EAAE;oBAC5B,MAAM,SAAS,IAAI,CAAC,qBAAqB;oBACzC,IAAI,CAAC,qBAAqB,GAAG;wBAC3B,KAAK,CAAA,GAAA,yCAAQ,EAAE,YAAY,CAAC,OAAO,GAAG,EAAE,KAAK,GAAG;wBAChD,MAAM,CAAA,GAAA,yCAAQ,EAAE,YAAY,CAAC,OAAO,IAAI,EAAE,KAAK,IAAI;oBACrD;oBACA,IACE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,IAC1C,IAAI,CAAC,mBAAmB,EACxB;wBACA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,qBAAqB;wBAC/C,IAAI,CAAC,qBAAqB,GAAG;4BAC3B,KAAK,IAAI,YAAY;4BACrB,MAAM,IAAI,YAAY;wBACxB;oBACF;gBACF,OACE,IAAI,CAAC,eAAe,CAAC;;QAG3B;QAEA,MAAM,OAAO,OAAO,OAAO,CAAC;QAC5B,MAAM,WAAW,QAAQ,cAAc;QACvC,SAAS,OAAO,GAAG;QACnB,SAAS,qBAAqB,GAAG;QACjC,KAAK,OAAO,CAAC;QACb,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACzB,sCAAsC;YACtC,QAAQ,IAAI,CACV;YAIF,SAAS,OAAO,CAAC,QAAQ,WAAW;QACtC;QAEA,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,QAAQ,GAAG;QAChB,IAAI,CAAC,SAAS,GAAG;QACjB,QAAQ,GAAG,CAAC;QACZ,OAAO;IACT;IAEA;;;;;;GAMC,GACD,eACE,eAAe,WAAW,EAC1B,cAAc,IAAI,EAClB,cAAc,GAAG,EACjB;QACA,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;QAElB,OAAO,CAAA,GAAA,yCAAY,EAAE,cAAc,CACjC,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,UAAU,EACf,MACA,cACA,aACA;IAEJ;IAEA;;;;GAIC,GACD,MAAM,QAAQ;QACZ,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;aACX,IAAI,CAAC,IAAI,CAAC,SAAS,EACxB,MAAM,IAAI,MAAM;QAElB,IAAI,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,EAC3C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,qBAAqB;QAEjD,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,IAAI,CAAC,MAAM,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG;QACjB,OAAO;IACT;IAEA;;;;;GAKC,GACD,MAAM,OAAO,iBAAiB,KAAO,CAAC,EAAE,YAAY,IAAI,EAAE;QACxD,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;aACX,IAAI,IAAI,CAAC,SAAS,EACvB,MAAM,IAAI,MAAM;aACX,IAAI,OAAO,mBAAmB,YACnC,MAAM,IAAI,MAAM,CAAC,iCAAiC,CAAC;QAErD,IAAI,CAAC,eAAe,GAAG;QACvB,IAAI,CAAC,mBAAmB,GAAG;QAC3B,IAAI,CAAC,qBAAqB,GAAG;YAC3B,KAAK,IAAI,YAAY;YACrB,MAAM,IAAI,YAAY;QACxB;QACA,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,IAAI,CAAC,MAAM,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG;QACjB,OAAO;IACT;IAEA;;;GAGC,GACD,MAAM,QAAQ;QACZ,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;QAElB,MAAM,IAAI,CAAC,MAAM,CAAC;QAClB,OAAO;IACT;IAEA;;;GAGC,GACD,MAAM,OAAO;QACX,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;QAElB,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,SAAS,MAAM,IAAI,CAAC,MAAM,CAAC;QACjC,OAAO;IACT;IAEA;;;;GAIC,GACD,MAAM,KAAK,QAAQ,KAAK,EAAE;QACxB,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;QAElB,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,EAC1B,MAAM,IAAI,MACR;QAGJ,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,aAAa,MAAM,IAAI,CAAC,MAAM,CAAC;QACrC,MAAM,SAAS,IAAI,CAAA,GAAA,yCAAQ;QAC3B,MAAM,SAAS,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,KAAK;QAC5D,OAAO;IACT;IAEA;;;GAGC,GACD,MAAM,MAAM;QACV,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;QAGlB,MAAM,aAAa,IAAI,CAAC,SAAS;QAEjC,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,IAAI,CAAC,MAAM,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG;QACjB,MAAM,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS;QACpC,OAAO,OAAO,CAAC,CAAC,QAAU,MAAM,IAAI;QAEpC,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,aAAa,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG;QAEnD,IAAI,CAAC,SAAS,CAAC,UAAU;QACzB,IAAI,CAAC,MAAM,CAAC,UAAU;QACtB,IAAI,CAAC,IAAI,CAAC,UAAU;QACpB,IAAI,CAAC,QAAQ,CAAC,UAAU;QACxB,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,SAAS,GAAG;QACjB,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,IAAI,GAAG;QAEZ,MAAM,SAAS,IAAI,CAAA,GAAA,yCAAQ;QAC3B,MAAM,SAAS,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,KAAK;QAC5D,OAAO;IACT;IAEA;;;;GAIC,GACD,MAAM,OAAO;QACX,IAAI,CAAC,qBAAqB,CAAC;QAC3B,uEAAuE;QACvE,IAAI,CAAC,eAAe,GAAG;QACvB,IAAI,IAAI,CAAC,SAAS,EAChB,MAAM,IAAI,CAAC,GAAG;QAEhB,OAAO;IACT;AACF;AAEA,WAAW,WAAW,GAAG;;;;;;AEniBlB,MAAM;IACX;;;;GAIC,GACD,YAAY,cACV,aAAa,yBACb,mBAAmB,cACnB,QAAQ,OACT,GAAG,CAAC,CAAC,CAAE;QACN,gBAAgB;QAChB,IAAI,CAAC,SAAS,GAAG,CAAA,GAAA,yCAAgB;QACjC,SAAS;QACT,IAAI,CAAC,UAAU,GAAG;QAClB,IAAI,CAAC,gBAAgB,GAAG;QACxB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,kBAAkB;QAClB,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,SAAS,GAAG;QACjB,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,SAAS,GAAG;QACjB,mCAAmC;QACnC,IAAI,CAAC,YAAY,GAAG;QACpB,IAAI,CAAC,aAAa,GAAG,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG;QACpB,0BAA0B;QAC1B,IAAI,CAAC,eAAe,GAAG,KAAO;QAC9B,IAAI,CAAC,mBAAmB,GAAG,KAAK;QAChC,IAAI,CAAC,qBAAqB,GAAG;YAC3B,KAAK,IAAI,YAAY;YACrB,MAAM,IAAI,YAAY;QACxB;IACF;IAEA;;;;GAIC,GACD,MAAM;QACJ,IAAI,IAAI,CAAC,KAAK,EACZ,IAAI,CAAC,GAAG,IAAI;QAEd,OAAO;IACT;IAEA;;;GAGC,GACD,gBAAgB;QACd,OAAO,IAAI,CAAC,UAAU;IACxB;IAEA;;;GAGC,GACD,YAAY;QACV,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,OAAO;aACF,IAAI,CAAC,IAAI,CAAC,SAAS,EACxB,OAAO;aAEP,OAAO;IAEX;IAEA;;;;;;;GAOC,GACD,MAAM,OAAO,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,aAAa,IAAI,EAAE;QAC/C,aAAa,cAAc,IAAI,CAAC,SAAS;QACzC,IAAI,CAAC,YACH,MAAM,IAAI,MAAM;QAElB,MAAM,UAAU;YACd,OAAO;YACP,IAAI,IAAI,CAAC,YAAY;kBACrB;QACF;QACA,WAAW,IAAI,CAAC,WAAW,CAAC;QAC5B,MAAM,KAAK,IAAI,OAAO,OAAO;QAC7B,MAAO,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAE;YACtC,IAAI,IAAI,OAAO,OAAO,KAAK,KAAK,IAAI,CAAC,YAAY,EAC/C,MAAM,IAAI,MAAM,CAAC,qBAAqB,EAAE,KAAK,OAAO,CAAC;YAEvD,MAAM,IAAI,QAAQ,CAAC,MAAQ,WAAW,IAAM,IAAI,OAAO;QACzD;QACA,MAAM,UAAU,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;QACrC,OAAO;IACT;IAEA;;;;;GAKC,GACD,MAAM,MAAM,UAAU,EAAE;QACtB,IAAI,IAAI,CAAC,SAAS,EAChB,MAAM,IAAI,MACR,CAAC,4DAA4D,CAAC;QAIlE,IAAI,CAAC,cAAc,WAAW,IAAI,KAAK,SACrC,MAAM,IAAI,MAAM;QAGlB,IAAI,CAAC,MAAM,GAAG,IAAI,YAAY;YAAC;SAAW;QAE1C,MAAM,UAAU,IAAI,aAAa;YAAE,YAAY,IAAI,CAAC,UAAU;QAAC;QAC/D,MAAM,SAAS,QAAQ,uBAAuB,CAAC,IAAI,CAAC,MAAM;QAC1D,sCAAsC;QACtC,IAAI;YACF,MAAM,QAAQ,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS;QACrD,EAAE,OAAO,GAAG;YACV,QAAQ,KAAK,CAAC;YACd,MAAM,IAAI,MAAM,CAAC,mCAAmC,EAAE,IAAI,CAAC,SAAS,EAAE;QACxE;QACA,MAAM,YAAY,IAAI,iBAAiB,SAAS;QAChD,UAAU,IAAI,CAAC,SAAS,GAAG,CAAC;YAC1B,MAAM,SAAE,KAAK,MAAE,EAAE,QAAE,IAAI,EAAE,GAAG,EAAE,IAAI;YAClC,IAAI,UAAU,WACZ,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG;iBACpB,IAAI,UAAU;gBACnB,IAAI,IAAI,CAAC,mBAAmB,EAAE;oBAC5B,MAAM,SAAS,IAAI,CAAC,qBAAqB;oBACzC,IAAI,CAAC,qBAAqB,GAAG;wBAC3B,KAAK,CAAA,GAAA,yCAAQ,EAAE,YAAY,CAAC,OAAO,GAAG,EAAE,KAAK,GAAG;wBAChD,MAAM,CAAA,GAAA,yCAAQ,EAAE,YAAY,CAAC,OAAO,IAAI,EAAE,KAAK,IAAI;oBACrD;oBACA,IACE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,IAC1C,IAAI,CAAC,mBAAmB,EACxB;wBACA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,qBAAqB;wBAC/C,IAAI,CAAC,qBAAqB,GAAG;4BAC3B,KAAK,IAAI,YAAY;4BACrB,MAAM,IAAI,YAAY;wBACxB;oBACF;gBACF,OACE,IAAI,CAAC,eAAe,CAAC;;QAG3B;QAEA,MAAM,OAAO,OAAO,OAAO,CAAC;QAC5B,MAAM,WAAW,QAAQ,cAAc;QACvC,SAAS,OAAO,GAAG;QACnB,SAAS,qBAAqB,GAAG;QACjC,KAAK,OAAO,CAAC;QACb,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACzB,sCAAsC;YACtC,QAAQ,IAAI,CACV;YAIF,SAAS,OAAO,CAAC,QAAQ,WAAW;QACtC;QAEA,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,QAAQ,GAAG;QAChB,IAAI,CAAC,SAAS,GAAG;QACjB,OAAO;IACT;IAEA;;;;;;GAMC,GACD,eACE,eAAe,WAAW,EAC1B,cAAc,IAAI,EAClB,cAAc,GAAG,EACjB;QACA,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;QAElB,OAAO,CAAA,GAAA,yCAAY,EAAE,cAAc,CACjC,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,UAAU,EACf,MACA,cACA,aACA;IAEJ;IAEA;;;;GAIC,GACD,MAAM,QAAQ;QACZ,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;aACX,IAAI,CAAC,IAAI,CAAC,SAAS,EACxB,MAAM,IAAI,MAAM;QAElB,IAAI,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,EAC3C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,qBAAqB;QAEjD,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,IAAI,CAAC,MAAM,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG;QACjB,OAAO;IACT;IAEA;;;;;GAKC,GACD,MAAM,OAAO,iBAAiB,KAAO,CAAC,EAAE,YAAY,IAAI,EAAE;QACxD,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;aACX,IAAI,IAAI,CAAC,SAAS,EACvB,MAAM,IAAI,MAAM;aACX,IAAI,OAAO,mBAAmB,YACnC,MAAM,IAAI,MAAM,CAAC,iCAAiC,CAAC;QAErD,IAAI,CAAC,eAAe,GAAG;QACvB,IAAI,CAAC,mBAAmB,GAAG;QAC3B,IAAI,CAAC,qBAAqB,GAAG;YAC3B,KAAK,IAAI,YAAY;YACrB,MAAM,IAAI,YAAY;QACxB;QACA,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,IAAI,CAAC,MAAM,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG;QACjB,OAAO;IACT;IAEA;;;GAGC,GACD,MAAM,QAAQ;QACZ,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;QAElB,MAAM,IAAI,CAAC,MAAM,CAAC;QAClB,OAAO;IACT;IAEA;;;GAGC,GACD,MAAM,OAAO;QACX,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;QAElB,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,SAAS,MAAM,IAAI,CAAC,MAAM,CAAC;QACjC,OAAO;IACT;IAEA;;;;GAIC,GACD,MAAM,KAAK,QAAQ,KAAK,EAAE;QACxB,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;QAElB,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,EAC1B,MAAM,IAAI,MACR;QAGJ,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,aAAa,MAAM,IAAI,CAAC,MAAM,CAAC;QACrC,MAAM,SAAS,IAAI,CAAA,GAAA,yCAAQ;QAC3B,MAAM,SAAS,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,KAAK;QAC5D,OAAO;IACT;IAEA;;;GAGC,GACD,MAAM,MAAM;QACV,IAAI,CAAC,IAAI,CAAC,SAAS,EACjB,MAAM,IAAI,MAAM;QAGlB,MAAM,aAAa,IAAI,CAAC,SAAS;QAEjC,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,IAAI,CAAC,MAAM,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG;QAEjB,IAAI,CAAC,GAAG,CAAC;QACT,MAAM,aAAa,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG;QAEnD,IAAI,CAAC,SAAS,CAAC,UAAU;QACzB,IAAI,CAAC,MAAM,CAAC,UAAU;QACtB,IAAI,CAAC,IAAI,CAAC,UAAU;QACpB,IAAI,CAAC,QAAQ,CAAC,UAAU;QACxB,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,SAAS,GAAG;QACjB,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,IAAI,GAAG;QAEZ,MAAM,SAAS,IAAI,CAAA,GAAA,yCAAQ;QAC3B,MAAM,SAAS,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,KAAK;QAC5D,OAAO;IACT;IAEA;;;;GAIC,GACD,MAAM,OAAO;QACX,IAAI,CAAC,qBAAqB,CAAC;QAC3B,IAAI,IAAI,CAAC,SAAS,EAChB,MAAM,IAAI,CAAC,GAAG;QAEhB,OAAO;IACT;AACF;AAEA,WAAW,WAAW,GAAG;;;;;AThUzB,IAAY;AAAZ,CAAA,SAAY,oBAAoB;IAC9B,oBAAA,CAAA,0BAAA,GAAA;IACA,oBAAA,CAAA,0BAAA,GAAA;AACF,CAAA,EAHY,6CAAA,CAAA,4CAAoB,CAAA,CAAA;AAKhC,MAAM;IAIJ,YAAY,KAAgB,CAA5B;QACE,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE;YACnC,KAAK,CAAC,QAAQ,MAAM;gBAClB,IAAI,OAAO,MAAM,CAAC,KAAwB,KAAK,YAAY;oBACzD,IAAI;oBACJ,OAAQ,OAAO;wBACb,0EAA0E;wBAC1E,0EAA0E;wBAC1E,KAAK;4BACH,SAAS,CAAA,+DAAA,CAAiE;4BAC1E;wBACF,KAAK;4BACH,SAAS,CAAA,mGAAA,CAAqG;4BAC9G;wBACF,KAAK;4BACH,SAAS,CAAA,6DAAA,CAA+D;4BACxE;wBACF,KAAK;4BACH,SAAS,CAAA,iEAAA,CAAmE;4BAC5E;wBACF,KAAK;4BACH,SAAS,CAAA,gCAAA,CAAkC;4BAC3C;oBACJ;oBACA,IAAI,QACF,OAAO;wBACL,MAAM,IAAI,MAAM;oBAClB;oBAEF,6BAA6B;oBAC7B,OAAO,CAAC,GAAG;wBACT,OAAQ,MAAM,CAAC,KAAqC,IAAI;oBAC1D;gBACF;gBACA,0BAA0B;gBAC1B,OAAO,QAAQ,GAAG,CAAC,QAAQ,MAAM;YACnC;QACD;IACH;IAEA,IAAI,QAAJ;QACE,OAAO,IAAI,CAAC,MAAM;IACpB;AACD;AAEK,MAAO,kDAAuB,CAAA,GAAA,kCAAA;IAiBlC,YAAY,uBACV,sBAAsB,CAAA,kCACtB,gCAAgC,OAAK,GACD,CAAA,CAAE,CAHxC;QAIE,KAAK;QAfC,IAAA,CAAA,MAAM,GAAW;QACjB,IAAA,CAAA,YAAY,GAA4C,CAAA;QACxD,IAAA,CAAA,YAAY,GAA4C,CAAA;QACxD,IAAA,CAAA,gBAAgB,GAA4C,CAAA;QAI5D,IAAA,CAAA,kBAAkB,GAA4B;QAC9C,IAAA,CAAA,WAAW,GAAkB,EAAE;QAQrC,IAAI,CAAC,UAAU,GAAG,CAAA;QAElB,IAAI,CAAC,oBAAoB,GAAG;QAC5B,IAAI,CAAC,8BAA8B,GAAG;QAEtC,IAAI,CAAC,MAAM,GAAG,CAAA,GAAA,+CAAA,EAAM,gBAAgB,CAAC;YACnC,GAAG,IAAI,CAAC,oBAAoB;YAC5B,4BAA4B;QAC7B;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,uCAAiB,IAAI,CAAC,MAAM;IACvD;IAEQ,gBAAA;QACN,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAA,GAAA,yCAAA,EAAoB;YAClD,YAAY,0CAAe,oBAAoB;QAChD;IACH;IAEA,sBAAsB,IAAiB,EAAvC;QACE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACxB;IAEQ,kBAAA;QACN,MAAM,YAAY,IAAI,2CAA2C;QACjE,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,GAC9B;QAGF,CAAA,GAAA,+BAAA,EAAO,KAAK,CAAC,CAAA,wBAAA,EAA2B,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;QAEjE,MAAO,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,EAAG;YAClC,MAAM,QAAuB,EAAE;YAE/B,kCAAkC;YAClC,MAAO,MAAM,MAAM,GAAG,aAAa,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,EAAG;gBAC9D,MAAM,aAAa,IAAI,CAAC,WAAW,CAAC,KAAK;gBACzC,IAAI,YAAY,MAAM,IAAI,CAAC;YAC7B;YAEA,IAAI,MAAM,MAAM,GAAG,GACjB,IAAI,CAAC,eAAe,CAAC;QAEzB;IACF;IAEA,gBAAgB,SAAwB,EAAxC;QACE,MAAM,eAAe,UAAU,GAAG,CAAC,CAAC;YAClC,MAAM,eAAe,IAAI,WAAW;YACpC,OAAO,KAAK,OAAO,YAAY,IAAI;QACrC;QAEA,MAAM,cAA2B;YAC/B,IAAI;YACJ,OAAO;YACP,MAAM;YACN,MAAM;gBACJ,kBAAkB;gBAClB,YAAY,0CAAe,oBAAoB;gBAC/C,aAAa;YACd;QACF;QAED,IAAI,CAAC,WAAW,CAAC;IACnB;IAEO,WACL,OAA0B,EAC1B,cAAyC,EAFpC;QAIL,IAAI,IAAI,CAAC,8BAA8B,EACrC,IAAI,CAAC,aAAa;QAGpB,IAAI,CAAC,UAAU,GAAG,QAAQ,SAAS,IAAI,CAAA;QACvC,IAAI,CAAC,UAAU,GAAG;QAElB,IACE,IAAI,CAAC,oBAAoB,CAAC,aAAa,IAAI,QAC3C,QAAQ,SAAS,IAAI,MAErB,qBAAqB;QACrB,IAAI,CAAC,oBAAoB,CAAC,aAAa,GAAG,CAAE,CAAA,QAAQ,SAAS,IAAI,KAAA;QAEnE,IACE,IAAI,CAAC,oBAAoB,CAAC,aAAa,IAAI,QAC3C,QAAQ,SAAS,IAAI,MAErB,oBAAoB;QACpB,IAAI,CAAC,oBAAoB,CAAC,aAAa,GAAG,CAAE,CAAA,QAAQ,SAAS,IAAI,IAAA;QAGnE,IAAI,CAAC,oBAAoB;QAEzB,IAAI,CAAC,KAAK,GAAG;QAEb,CAAA,GAAA,+BAAA,EAAO,KAAK,CAAC;IACf;IAEA,IAAI,kBAAJ;QACE,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK;IACjC;IAEA,IAAI,QAAJ;QACE,OAAO,IAAI,CAAC,MAAM;IACpB;IAEA,IAAY,MAAM,KAAqB,EAAvC;QACE,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO;QAE3B,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,UAAU,CAAC,uBAAuB,GAAG;IAC5C;IAEA,MAAM,aAAN;QACE,MAAM,WAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB;QACtD,OAAO,QAAQ,MAAM,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;IAC1C;IAEA,UAAU,KAAa,EAAvB;QACE,IAAI,CAAC,MAAM,CACR,oBAAoB,CAAC;YACpB,eAAe;QAChB,GACA,IAAI,CAAC,CAAC;YACL,IAAI,CAAC,YAAY,GAAG,MAAM,MAAM;QAClC;IACJ;IAEA,IAAI,cAAJ;QACE,OAAO,IAAI,CAAC,YAAY;IAC1B;IAEA,MAAM,aAAN;QACE,MAAM,WAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB;QACtD,OAAO,QAAQ,MAAM,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;IAC1C;IAEA,UAAU,KAAa,EAAvB;QACE,IAAI,CAAC,MAAM,CACR,oBAAoB,CAAC;YACpB,eAAe;QAChB,GACA,IAAI,CAAC,CAAC;YACL,IAAI,CAAC,YAAY,GAAG,MAAM,GAAG;QAC/B;IACJ;IAEA,IAAI,cAAJ;QACE,OAAO,IAAI,CAAC,YAAY;IAC1B;IAEA,MAAM,iBAAN;QACE,MAAM,WAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB;QACtD,OAAO,QAAQ,MAAM,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;IAC1C;IAEA,cAAc,SAAiB,EAA/B;QACE,IAAI,CAAC,MAAM,CACR,oBAAoB,CAAC;YAAE,gBAAgB;QAAS,GAChD,IAAI,CAAC,CAAC;YACL,IAAI,CAAC,gBAAgB,GAAG,MAAM,OAAO;QACvC;IACJ;IAEA,IAAI,kBAAJ;QACE,OAAO,IAAI,CAAC,gBAAgB;IAC9B;IAEA,UAAU,MAAe,EAAzB;QACE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;IAC5B;IAEA,IAAI,eAAJ;QACE,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU;IAC/B;IAEA,UAAU,MAAe,EAAzB;QACE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;IAC5B;IAEA,IAAI,eAAJ;QACE,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU;IAC/B;IAEO,kBAAkB,MAAe,EAAjC;QACL,IAAI,QACF,IAAI,CAAC,MAAM,CAAC,gBAAgB;aAE5B,IAAI,CAAC,MAAM,CAAC,eAAe;IAE/B;IAEA,IAAW,kBAAX;QACE,OAAO,IAAI,CAAC,MAAM,CAAC,gBAAgB,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB;IACvE;IAEA,SAAA;QACE,MAAM,eAAe,IAAI,CAAC,MAAM,CAAC,YAAY,MAAM,CAAA;QACnD,MAAM,MAAM,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;QAEvC,MAAM,SAAiB;YACrB,OAAO;gBACL,OAAO,cAAc,OAAO,QAAQ,OAAO;gBAC3C,aAAa,cAAc,OAAO,QAAQ,aAAa;gBACvD,aAAa,cAAc,OAAO,QAAQ,aAAa;gBACvD,OAAO,cAAc,OAAO,QAAQ,OAAO;YAC5C;QACF;QAED,IAAI,KACF,OAAO,GAAG,GAAG;YACX,OAAO,KAAK,QAAQ,OAAO;YAC3B,OAAO,KAAK,QAAQ,OAAO;QAC5B;QAGH,OAAO;IACT;IAEQ,MAAM,iBAAN;QACN,IAAI;YACF,CAAA,GAAA,+BAAA,EAAO,IAAI,CAAC;YACZ,MAAM,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;gBACtC,IAAI,CAAC,qBAAqB,CAAC,KAAK,IAAI;YACtC,GAAG,0CAAe,mBAAmB;YACrC,IAAI,CAAC,UAAU,CAAC;gBACd,MAAM,0CAAqB,uBAAuB;gBAClD,MAAM,CAAA;YACQ;YAChB,CAAA,GAAA,+BAAA,EAAO,IAAI,CAAC;QACd,EAAE,OAAO,GAAG;YACV,MAAM,MAAM;YACZ,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,sBACxB,CAAA,GAAA,+BAAA,EAAO,KAAK,CAAC,4BAA4B;QAE7C;IACF;IAEA,MAAM,QAAQ,mBAAwC,EAAtD;QACE,IAAI,CAAC,oBAAoB,GAAG;QAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IAC5B;IAEA,MAAM,cAAN;QACE,IAAI,CAAC,IAAI,CAAC,MAAM,EACd,MAAM,IAAI,CAAA,GAAA,kCAAA,EAAU;QAGtB,IAAI,CAAC,KAAK,GAAG;QAEb,MAAM,QAAQ,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW;QAC3C,MAAM,WAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB;QACtD,MAAM,OAAO,QAAQ,MAAM,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;QAC9C,MAAM,OAAO,QAAQ,MAAM,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;QAC9C,MAAM,WAAW,QAAQ,MAAM,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;QAClD,IAAI,CAAC,YAAY,GAAG,MAAM,MAAM;QAChC,IAAI,CAAC,YAAY,GAAG,MAAM,GAAG;QAC7B,IAAI,CAAC,gBAAgB,GAAG,MAAM,OAAO;QAErC,IAAI,CAAC,UAAU,CAAC,sBAAsB,GAAG;QACzC,IAAI,CAAC,UAAU,CAAC,sBAAsB,GAAG;QACzC,IAAI,CAAC,UAAU,CAAC,0BAA0B,GAAG;QAC7C,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,MAAM,MAAyB;QAC9D,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,MAAM,GAAsB;QAC3D,IAAI,CAAC,UAAU,CAAC,gBAAgB,GAAG,MAAM,OAA0B;QAEnE,8BAA8B;QAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,gCAAgC,IAC/C,MAAM,IAAI,CAAC,MAAM,CAAC,4BAA4B,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,6CAA6C,IAC5D,MAAM,IAAI,CAAC,MAAM,CAAC,yCAAyC,CAAC;QAE9D,IAAI,CAAC,KAAK,GAAG;IACf;IAEA,MAAM,QACJ,UAAoC,EACpC,eAAgC,EAFlC;QAIE,IAAI,CAAC,IAAI,CAAC,MAAM,EACd,MAAM,IAAI,CAAA,GAAA,kCAAA,EAAU;QAGtB,IAAI,gBAAgB,MAAM,CAAC,OAAO,EAAE;QAEpC,IAAI,CAAC,KAAK,GAAG;QAEb,MAAM,OAAO,IAAI,CAAC,oBAAoB;QACtC,KAAK,GAAG,GAAG,WAAW,QAAQ,IAAI,KAAK,GAAG;QAC1C,IAAI,WAAW,KAAK,IAAI,MACtB,KAAK,KAAK,GAAG,WAAW,KAAK;QAE/B,IAAI;YACF,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YAEvB,MAAM,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI;YACnC,IAAI,QAAQ,QAAQ,MAClB,IAAI,CAAC,OAAO,GAAG,KAAK,MAAM,EAAE;QAEhC,EAAE,OAAO,GAAG;YACV,CAAA,GAAA,+BAAA,EAAO,KAAK,CAAC,uBAAuB;YACpC,IAAI,CAAC,KAAK,GAAG;YACb,MAAM,IAAI,CAAA,GAAA,4CAAA;QACZ;QAEA,IAAI,gBAAgB,MAAM,CAAC,OAAO,EAAE;QAEpC,IAAI,CAAC,KAAK,GAAG;QAEb,IAAI,CAAC,UAAU,CAAC,WAAW;IAC7B;IAEA,MAAM,mBAAN;QACE,OAAO,IAAI,QAAc,CAAC;YACvB,CAAA;gBACC,MAAM,eAAe,CAAC;oBACpB,IAAI,CAAC,GAAG,WAAW,EAAE,OAAO;wBAC1B,IAAI,CAAC,KAAK,GAAG;wBACb,IAAI,CAAC,eAAe;wBACpB,IAAI,CAAC,WAAW,CAAC,CAAA,GAAA,oCAAA,EAAY,WAAW;wBACxC,IAAI,CAAC,aAAa;wBAClB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB;wBACjC;oBACF;gBACF;gBACA,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB;YAClC,CAAA;QACF;IACF;IAEQ,gBAAA;QACN,IACE,IAAI,CAAC,oBAAoB,IACzB,IAAI,CAAC,oBAAoB,CAAC,SAAS,OAAO,SAC1C;YACA,iDAAiD;YAC5C,IAAI,CAAC,oBAAoB,CAAC,GAAG;YAClC,IAAI,CAAC,UAAU,CAAC;gBACd,MAAM,0CAAqB,uBAAuB;gBAClD,MAAM,CAAA;YACQ;QAClB;IACF;IAEQ,uBAAA;QACN,IAAI,CAAC,MAAM,CAAC,EAAE,CACZ,6BACA,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,IAAI;QAE9C,IAAI,CAAC,MAAM,CAAC,EAAE,CACZ,4BACA,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI;QAG7C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI;QACjE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI;QACjE,IAAI,CAAC,MAAM,CAAC,EAAE,CACZ,sBACA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI;QAExC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,oBAAoB,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI;QACvE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,qBAAqB,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI;QACxE,IAAI,CAAC,MAAM,CAAC,EAAE,CACZ,mCACA,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI;QAEvC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI;QAC7D,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,gBAAgB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI;QAC/D,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,kBAAkB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI;IACrE;IAEA,MAAM,aAAN;QACE,IAAI,CAAC,KAAK,GAAG;QACb,IAAI,CAAC,MAAM,CAAC,2BAA2B;QACvC,IAAI,CAAC,MAAM,CAAC,wCAAwC;QAEpD,IAAI,CAAC,WAAW,GAAG,EAAE;QACrB,IAAI,CAAC,kBAAkB,GAAG;QAC1B,IAAI,CAAC,aAAa;QAElB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK;IACzB;IAEO,YAAY,OAAoB,EAAhC;QACL,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,SAAS;IACtC;IAEQ,iBAAiB,EAA8B,EAA/C;QACN,yCAAyC;QACzC,IAAI,GAAG,IAAI,CAAC,KAAK,KAAK,WACpB,IAAI,CAAC,UAAU,CAAC;YACd,IAAI,GAAG,IAAI,CAAC,EAAE;YACd,MAAM,GAAG,IAAI,CAAC,IAAI;YAClB,MAAM,GAAG,IAAI,CAAC,IAAI;QACJ;IAEpB;IAEQ,8BACN,EAA2C,EADrC;QAGN,IAAI,CAAC,UAAU,CAAC,sBAAsB,GACpC,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;QAE/C,IAAI,CAAC,UAAU,CAAC,sBAAsB,GACpC,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;QAE/C,IAAI,CAAC,UAAU,CAAC,0BAA0B,GACxC,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;IAEjD;IAEQ,6BACN,EAA0C,EADpC;QAGN,IAAI,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE;YACrD,IAAI,CAAC,YAAY,GAAG,GAAG,OAAO,CAAC,MAAM;YACrC,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,GAAG,OAAO,CAAC,MAAyB;QACrE;QACA,IAAI,IAAI,CAAC,YAAY,EAAE,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE;YAClD,IAAI,CAAC,YAAY,GAAG,GAAG,OAAO,CAAC,GAAG;YAClC,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,GAAG,OAAO,CAAC,GAAsB;QAClE;QACA,IAAI,IAAI,CAAC,gBAAgB,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,EAAE;YAC1D,IAAI,CAAC,gBAAgB,GAAG,GAAG,OAAO,CAAC,OAAO;YAC1C,IAAI,CAAC,UAAU,CAAC,gBAAgB,GAAG,GAAG,OAAO,CAAC,OAA0B;QAC1E;IACF;IAEQ,MAAM,sBAAsB,KAAuB,EAAnD;QACN,IAAI,IAAI,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,8BAA8B,EAC/D;QAEF,MAAM,SAAS,IAAI,CAAC,oBAAoB,CAAC,SAAS;QAClD,OAAQ;YACN,KAAK;gBACH,MAAM,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;gBACtC,MAAM,IAAI,CAAC,cAAc;gBACzB;YACF,KAAK;gBACH,MAAM,IAAI,CAAC,cAAc;gBACzB;YACF,KAAK;YACL;gBACE,IAAI,IAAI,CAAC,kBAAkB,KAAK,OAAO;oBACrC,MAAM,IAAI,CAAC,oBAAoB,CAAC,GAAG;oBACnC,MAAM,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;oBACtC,MAAM,IAAI,CAAC,cAAc;gBAC3B,OACE,CAAA,GAAA,+BAAA,EAAO,IAAI,CACT;gBAGJ;QACJ;QACA,IAAI,CAAC,kBAAkB,GAAG;IAC5B;IAEQ,mBAAmB,EAAyB,EAA5C;QACN,IAAI,GAAG,IAAI,KAAK,iBAAiB,GAAG,IAAI,KAAK,eAC3C,IAAI,CAAC,UAAU,CAAC,oBAAoB,GAClC,GAAG,KAAK,EACR,GAAG,WAAW,GACV,oDAA8B,GAAG,WAAW,IAC5C;aAED;YACL,IAAI,GAAG,WAAW,EAAE,SAAS,GAAG,KAAK,CAAC,IAAI,KAAK,SACxC,IAAI,CAAC,qBAAqB,CAAC,GAAG,KAAK;YAE1C,IAAI,CAAC,UAAU,CAAC,cAAc,GAC5B,GAAG,KAAK,EACR,GAAG,WAAW,GACV,oDAA8B,GAAG,WAAW,IAC5C;QAER;IACF;IAEQ,mBAAmB,EAAyB,EAA5C;QACN,IAAI,GAAG,IAAI,KAAK,iBAAiB,GAAG,IAAI,KAAK,eAC3C,IAAI,CAAC,UAAU,CAAC,oBAAoB,GAClC,GAAG,KAAK,EACR,GAAG,WAAW,GACV,oDAA8B,GAAG,WAAW,IAC5C;aAGN,IAAI,CAAC,UAAU,CAAC,cAAc,GAC5B,GAAG,KAAK,EACR,GAAG,WAAW,GACV,oDAA8B,GAAG,WAAW,IAC5C;IAGV;IAEQ,wBAAwB,EAA+B,EAAvD;QACN,MAAM,IAAI,oDAA8B,GAAG,WAAW;QAEtD,IAAI,CAAC,UAAU,CAAC,mBAAmB,GAAG;QAEtC,IAAI,EAAE,KAAK,EAAE;QAEb,IAAI,CAAC,MAAM,GAAG,GAAG,WAAW,CAAC,UAAU;QAEvC,IAAI,CAAC,UAAU,CAAC,cAAc,GAAG;IACnC;IAEQ,sBAAsB,EAAmC,EAAzD;QACN,MAAM,IAAI,oDAA8B,GAAG,WAAW;QAEtD,IAAI,CAAC,UAAU,CAAC,iBAAiB,GAAG;QAEpC,IAAI,EAAE,KAAK,EAAE;QAEb,IAAI,CAAC,MAAM,GAAG;QAEd,IAAI,CAAC,UAAU,CAAC,iBAAiB,GAAG;IACtC;IAEQ,sBAAsB,EAAmC,EAAzD;QACN,IAAI,CAAC,UAAU,CAAC,iBAAiB,GAAG,GAAG,UAAU;IACnD;IAEQ,uBACN,EAAgD,EAD1C;QAGN,MAAM,eAAe,IAAI,CAAC,MAAM,CAAC,YAAY;QAC7C,MAAM,MAAM,OAAO,IAAI,CAAC,GAAG,sBAAsB;QACjD,IAAK,IAAI,IAAI,GAAG,IAAI,IAAI,MAAM,EAAE,IAAK;YACnC,MAAM,KAAK,GAAG,CAAC,EAAE;YACjB,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG;YAC3C,IAAI,CAAC,UAAU,CAAC,kBAAkB,GAChC,OACA,oDAA8B,YAAY,CAAC,GAAG;QAElD;IACF;IAEQ,oBAAA;QACN,IAAI,CAAC,KAAK,GAAG;QACb,IAAI,CAAC,MAAM,GAAG;QACd,IAAI,CAAC,UAAU,CAAC,cAAc;IAChC;IAEQ,oBAAoB,EAAiC,EAArD;QACN,OAAQ,GAAG,IAAI;YACb,KAAK;gBACH,IAAI,CAAC,UAAU,CAAC,kBAAkB,GAAG,GAAG,QAAQ;gBAChD;QACJ;IACF;A;AAnjBe,0CAAA,oBAAoB,GAAG;AACvB,0CAAA,mBAAmB,GAAG;AAqjBvC,MAAM,sDAAgC,CAAC,IAAsC,CAAA;QAC3E,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,SAAS;IAClB,CAAA","sources":["transports/daily/src/index.ts","transports/daily/src/transport.ts","lib/wavtools/index.js","lib/wavtools/lib/wav_packer.js","lib/wavtools/lib/analysis/audio_analysis.js","lib/wavtools/lib/analysis/constants.js","lib/wavtools/lib/wav_stream_player.js","lib/wavtools/lib/worklets/stream_processor.js","lib/wavtools/lib/wav_recorder.js","lib/wavtools/lib/worklets/audio_processor.js","lib/wavtools/lib/mediastream_recorder.js"],"sourcesContent":["export * from \"./transport\";\n","import Daily, {\n DailyCall,\n DailyEventObjectAppMessage,\n DailyEventObjectAvailableDevicesUpdated,\n DailyEventObjectLocalAudioLevel,\n DailyEventObjectNonFatalError,\n DailyEventObjectParticipant,\n DailyEventObjectParticipantLeft,\n DailyEventObjectRemoteParticipantsAudioLevel,\n DailyEventObjectSelectedDevicesUpdated,\n DailyEventObjectTrack,\n DailyFactoryOptions,\n DailyParticipant,\n} from \"@daily-co/daily-js\";\nimport {\n Participant,\n RTVIClientOptions,\n RTVIError,\n RTVIEventCallbacks,\n RTVIMessage,\n Tracks,\n Transport,\n TransportStartError,\n TransportState,\n logger,\n} from \"@pipecat-ai/client-js\";\n\nimport { MediaStreamRecorder } from \"../../../lib/wavtools\";\n\nexport interface DailyTransportAuthBundle {\n room_url: string;\n token: string;\n}\n\nexport interface DailyTransportConstructorOptions {\n bufferLocalAudioUntilBotReady?: boolean;\n dailyFactoryOptions?: DailyFactoryOptions;\n}\n\nexport enum DailyRTVIMessageType {\n AUDIO_BUFFERING_STARTED = \"audio-buffering-started\",\n AUDIO_BUFFERING_STOPPED = \"audio-buffering-stopped\",\n}\n\nclass DailyCallWrapper {\n private _daily: DailyCall;\n private _proxy: DailyCall;\n\n constructor(daily: DailyCall) {\n this._daily = daily;\n this._proxy = new Proxy(this._daily, {\n get: (target, prop, receiver) => {\n if (typeof target[prop as keyof DailyCall] === \"function\") {\n let errMsg;\n switch (String(prop)) {\n // Disable methods that modify the lifecycle of the call. These operations\n // should be performed via the RTVI client in order to keep state in sync.\n case \"preAuth\":\n errMsg = `Calls to preAuth() are disabled. Please use Transport.preAuth()`;\n break;\n case \"startCamera\":\n errMsg = `Calls to startCamera() are disabled. Please use RTVIClient.initDevices() or Transport.initDevices()`;\n break;\n case \"join\":\n errMsg = `Calls to join() are disabled. Please use RTVIClient.connect()`;\n break;\n case \"leave\":\n errMsg = `Calls to leave() are disabled. Please use RTVIClient.disconnect()`;\n break;\n case \"destroy\":\n errMsg = `Calls to destroy() are disabled.`;\n break;\n }\n if (errMsg) {\n return () => {\n throw new Error(errMsg);\n };\n }\n // Forward other method calls\n return (...args: any[]) => {\n return (target[prop as keyof DailyCall] as Function)(...args);\n };\n }\n // Forward property access\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n\n get proxy(): DailyCall {\n return this._proxy;\n }\n}\n\nexport class DailyTransport extends Transport {\n private declare _dailyWrapper: DailyCallWrapper;\n private declare _daily: DailyCall;\n private _dailyFactoryOptions: DailyFactoryOptions;\n\n private _bufferLocalAudioUntilBotReady: boolean;\n private _botId: string = \"\";\n private _selectedCam: MediaDeviceInfo | Record<string, never> = {};\n private _selectedMic: MediaDeviceInfo | Record<string, never> = {};\n private _selectedSpeaker: MediaDeviceInfo | Record<string, never> = {};\n\n private static RECORDER_SAMPLE_RATE = 16_000;\n private static RECORDER_CHUNK_SIZE = 512;\n private _currentAudioTrack: MediaStreamTrack | null = null;\n private _audioQueue: ArrayBuffer[] = [];\n private declare _mediaStreamRecorder: MediaStreamRecorder;\n\n constructor({\n dailyFactoryOptions = {},\n bufferLocalAudioUntilBotReady = false,\n }: DailyTransportConstructorOptions = {}) {\n super();\n this._callbacks = {} as RTVIEventCallbacks;\n\n this._dailyFactoryOptions = dailyFactoryOptions;\n this._bufferLocalAudioUntilBotReady = bufferLocalAudioUntilBotReady;\n\n this._daily = Daily.createCallObject({\n ...this._dailyFactoryOptions,\n allowMultipleCallInstances: true,\n });\n this._dailyWrapper = new DailyCallWrapper(this._daily);\n }\n\n private setupRecorder(): void {\n this._mediaStreamRecorder = new MediaStreamRecorder({\n sampleRate: DailyTransport.RECORDER_SAMPLE_RATE,\n });\n }\n\n handleUserAudioStream(data: ArrayBuffer): void {\n this._audioQueue.push(data);\n }\n\n private flushAudioQueue(): void {\n const batchSize = 10; // Number of buffers to send in one message\n if (this._audioQueue.length === 0) {\n return;\n }\n\n logger.debug(`Will flush audio queue: ${this._audioQueue.length}`);\n\n while (this._audioQueue.length > 0) {\n const batch: ArrayBuffer[] = [];\n\n // Collect up to `batchSize` items\n while (batch.length < batchSize && this._audioQueue.length > 0) {\n const queuedData = this._audioQueue.shift();\n if (queuedData) batch.push(queuedData);\n }\n\n if (batch.length > 0) {\n this._sendAudioBatch(batch);\n }\n }\n }\n\n _sendAudioBatch(dataBatch: ArrayBuffer[]): void {\n const encodedBatch = dataBatch.map((data) => {\n const pcmByteArray = new Uint8Array(data);\n return btoa(String.fromCharCode(...pcmByteArray));\n });\n\n const rtviMessage: RTVIMessage = {\n id: \"raw-audio-batch\",\n label: \"rtvi-ai\",\n type: \"raw-audio-batch\",\n data: {\n base64AudioBatch: encodedBatch, // Sending an array of base64 strings\n sampleRate: DailyTransport.RECORDER_SAMPLE_RATE,\n numChannels: 1,\n },\n };\n\n this.sendMessage(rtviMessage);\n }\n\n public initialize(\n options: RTVIClientOptions,\n messageHandler: (ev: RTVIMessage) => void\n ): void {\n if (this._bufferLocalAudioUntilBotReady) {\n this.setupRecorder();\n }\n\n this._callbacks = options.callbacks ?? {};\n this._onMessage = messageHandler;\n\n if (\n this._dailyFactoryOptions.startVideoOff == null ||\n options.enableCam != null\n ) {\n // Default is cam off\n this._dailyFactoryOptions.startVideoOff = !(options.enableCam ?? false);\n }\n if (\n this._dailyFactoryOptions.startAudioOff == null ||\n options.enableMic != null\n ) {\n // Default is mic on\n this._dailyFactoryOptions.startAudioOff = !(options.enableMic ?? true);\n }\n\n this.attachEventListeners();\n\n this.state = \"disconnected\";\n\n logger.debug(\"[RTVI Transport] Initialized\");\n }\n\n get dailyCallClient(): DailyCall {\n return this._dailyWrapper.proxy;\n }\n\n get state(): TransportState {\n return this._state;\n }\n\n private set state(state: TransportState) {\n if (this._state === state) return;\n\n this._state = state;\n this._callbacks.onTransportStateChanged?.(state);\n }\n\n async getAllCams() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"videoinput\");\n }\n\n updateCam(camId: string) {\n this._daily\n .setInputDevicesAsync({\n videoDeviceId: camId,\n })\n .then((infos) => {\n this._selectedCam = infos.camera;\n });\n }\n\n get selectedCam() {\n return this._selectedCam;\n }\n\n async getAllMics() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"audioinput\");\n }\n\n updateMic(micId: string) {\n this._daily\n .setInputDevicesAsync({\n audioDeviceId: micId,\n })\n .then((infos) => {\n this._selectedMic = infos.mic;\n });\n }\n\n get selectedMic() {\n return this._selectedMic;\n }\n\n async getAllSpeakers() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"audiooutput\");\n }\n\n updateSpeaker(speakerId: string) {\n this._daily\n .setOutputDeviceAsync({ outputDeviceId: speakerId })\n .then((infos) => {\n this._selectedSpeaker = infos.speaker;\n });\n }\n\n get selectedSpeaker() {\n return this._selectedSpeaker;\n }\n\n enableMic(enable: boolean) {\n this._daily.setLocalAudio(enable);\n }\n\n get isMicEnabled() {\n return this._daily.localAudio();\n }\n\n enableCam(enable: boolean) {\n this._daily.setLocalVideo(enable);\n }\n\n get isCamEnabled() {\n return this._daily.localVideo();\n }\n\n public enableScreenShare(enable: boolean) {\n if (enable) {\n this._daily.startScreenShare();\n } else {\n this._daily.stopScreenShare();\n }\n }\n\n public get isSharingScreen(): boolean {\n return this._daily.localScreenAudio() || this._daily.localScreenVideo();\n }\n\n tracks() {\n const participants = this._daily.participants() ?? {};\n const bot = participants?.[this._botId];\n\n const tracks: Tracks = {\n local: {\n audio: participants?.local?.tracks?.audio?.persistentTrack,\n screenAudio: participants?.local?.tracks?.screenAudio?.persistentTrack,\n screenVideo: participants?.local?.tracks?.screenVideo?.persistentTrack,\n video: participants?.local?.tracks?.video?.persistentTrack,\n },\n };\n\n if (bot) {\n tracks.bot = {\n audio: bot?.tracks?.audio?.persistentTrack,\n video: bot?.tracks?.video?.persistentTrack,\n };\n }\n\n return tracks;\n }\n\n private async startRecording(): Promise<void> {\n try {\n logger.info(\"[RTVI Transport] Initializing recording\");\n await this._mediaStreamRecorder.record((data) => {\n this.handleUserAudioStream(data.mono);\n }, DailyTransport.RECORDER_CHUNK_SIZE);\n this._onMessage({\n type: DailyRTVIMessageType.AUDIO_BUFFERING_STARTED,\n data: {},\n } as RTVIMessage);\n logger.info(\"[RTVI Transport] Recording Initialized\");\n } catch (e) {\n const err = e as Error;\n if (!err.message.includes(\"Already recording\")) {\n logger.error(\"Error starting recording\", e);\n }\n }\n }\n\n async preAuth(dailyFactoryOptions: DailyFactoryOptions) {\n this._dailyFactoryOptions = dailyFactoryOptions;\n await this._daily.preAuth(dailyFactoryOptions);\n }\n\n async initDevices() {\n if (!this._daily) {\n throw new RTVIError(\"Transport instance not initialized\");\n }\n\n this.state = \"initializing\";\n\n const infos = await this._daily.startCamera();\n const { devices } = await this._daily.enumerateDevices();\n const cams = devices.filter((d) => d.kind === \"videoinput\");\n const mics = devices.filter((d) => d.kind === \"audioinput\");\n const speakers = devices.filter((d) => d.kind === \"audiooutput\");\n this._selectedCam = infos.camera;\n this._selectedMic = infos.mic;\n this._selectedSpeaker = infos.speaker;\n\n this._callbacks.onAvailableCamsUpdated?.(cams);\n this._callbacks.onAvailableMicsUpdated?.(mics);\n this._callbacks.onAvailableSpeakersUpdated?.(speakers);\n this._callbacks.onCamUpdated?.(infos.camera as MediaDeviceInfo);\n this._callbacks.onMicUpdated?.(infos.mic as MediaDeviceInfo);\n this._callbacks.onSpeakerUpdated?.(infos.speaker as MediaDeviceInfo);\n\n // Instantiate audio observers\n if (!this._daily.isLocalAudioLevelObserverRunning())\n await this._daily.startLocalAudioLevelObserver(100);\n if (!this._daily.isRemoteParticipantsAudioLevelObserverRunning())\n await this._daily.startRemoteParticipantsAudioLevelObserver(100);\n\n this.state = \"initialized\";\n }\n\n async connect(\n authBundle: DailyTransportAuthBundle,\n abortController: AbortController\n ) {\n if (!this._daily) {\n throw new RTVIError(\"Transport instance not initialized\");\n }\n\n if (abortController.signal.aborted) return;\n\n this.state = \"connecting\";\n\n const opts = this._dailyFactoryOptions;\n opts.url = authBundle.room_url ?? opts.url;\n if (authBundle.token != null) {\n opts.token = authBundle.token;\n }\n try {\n await this._daily.join(opts);\n\n const room = await this._daily.room();\n if (room && \"id\" in room) {\n this._expiry = room.config?.exp;\n }\n } catch (e) {\n logger.error(\"Failed to join room\", e);\n this.state = \"error\";\n throw new TransportStartError();\n }\n\n if (abortController.signal.aborted) return;\n\n this.state = \"connected\";\n\n this._callbacks.onConnected?.();\n }\n\n async sendReadyMessage(): Promise<void> {\n return new Promise<void>((resolve) => {\n (async () => {\n const readyHandler = (ev: DailyEventObjectTrack) => {\n if (!ev.participant?.local) {\n this.state = \"ready\";\n this.flushAudioQueue();\n this.sendMessage(RTVIMessage.clientReady());\n this.stopRecording();\n this._daily.off(\"track-started\", readyHandler);\n resolve();\n }\n };\n this._daily.on(\"track-started\", readyHandler);\n })();\n });\n }\n\n private stopRecording() {\n if (\n this._mediaStreamRecorder &&\n this._mediaStreamRecorder.getStatus() !== \"ended\"\n ) {\n // disconnecting, we don't need to record anymore\n void this._mediaStreamRecorder.end();\n this._onMessage({\n type: DailyRTVIMessageType.AUDIO_BUFFERING_STOPPED,\n data: {},\n } as RTVIMessage);\n }\n }\n\n private attachEventListeners() {\n this._daily.on(\n \"available-devices-updated\",\n this.handleAvailableDevicesUpdated.bind(this)\n );\n this._daily.on(\n \"selected-devices-updated\",\n this.handleSelectedDevicesUpdated.bind(this)\n );\n\n this._daily.on(\"track-started\", this.handleTrackStarted.bind(this));\n this._daily.on(\"track-stopped\", this.handleTrackStopped.bind(this));\n this._daily.on(\n \"participant-joined\",\n this.handleParticipantJoined.bind(this)\n );\n this._daily.on(\"participant-left\", this.handleParticipantLeft.bind(this));\n this._daily.on(\"local-audio-level\", this.handleLocalAudioLevel.bind(this));\n this._daily.on(\n \"remote-participants-audio-level\",\n this.handleRemoteAudioLevel.bind(this)\n );\n this._daily.on(\"app-message\", this.handleAppMessage.bind(this));\n this._daily.on(\"left-meeting\", this.handleLeftMeeting.bind(this));\n this._daily.on(\"nonfatal-error\", this.handleNonFatalError.bind(this));\n }\n\n async disconnect() {\n this.state = \"disconnecting\";\n this._daily.stopLocalAudioLevelObserver();\n this._daily.stopRemoteParticipantsAudioLevelObserver();\n\n this._audioQueue = [];\n this._currentAudioTrack = null;\n this.stopRecording();\n\n await this._daily.leave();\n }\n\n public sendMessage(message: RTVIMessage) {\n this._daily.sendAppMessage(message, \"*\");\n }\n\n private handleAppMessage(ev: DailyEventObjectAppMessage) {\n // Bubble any messages with rtvi-ai label\n if (ev.data.label === \"rtvi-ai\") {\n this._onMessage({\n id: ev.data.id,\n type: ev.data.type,\n data: ev.data.data,\n } as RTVIMessage);\n }\n }\n\n private handleAvailableDevicesUpdated(\n ev: DailyEventObjectAvailableDevicesUpdated\n ) {\n this._callbacks.onAvailableCamsUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"videoinput\")\n );\n this._callbacks.onAvailableMicsUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"audioinput\")\n );\n this._callbacks.onAvailableSpeakersUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"audiooutput\")\n );\n }\n\n private handleSelectedDevicesUpdated(\n ev: DailyEventObjectSelectedDevicesUpdated\n ) {\n if (this._selectedCam?.deviceId !== ev.devices.camera) {\n this._selectedCam = ev.devices.camera;\n this._callbacks.onCamUpdated?.(ev.devices.camera as MediaDeviceInfo);\n }\n if (this._selectedMic?.deviceId !== ev.devices.mic) {\n this._selectedMic = ev.devices.mic;\n this._callbacks.onMicUpdated?.(ev.devices.mic as MediaDeviceInfo);\n }\n if (this._selectedSpeaker?.deviceId !== ev.devices.speaker) {\n this._selectedSpeaker = ev.devices.speaker;\n this._callbacks.onSpeakerUpdated?.(ev.devices.speaker as MediaDeviceInfo);\n }\n }\n\n private async handleLocalAudioTrack(track: MediaStreamTrack) {\n if (this.state == \"ready\" || !this._bufferLocalAudioUntilBotReady) {\n return;\n }\n const status = this._mediaStreamRecorder.getStatus();\n switch (status) {\n case \"ended\":\n await this._mediaStreamRecorder.begin(track);\n await this.startRecording();\n break;\n case \"paused\":\n await this.startRecording();\n break;\n case \"recording\":\n default:\n if (this._currentAudioTrack !== track) {\n await this._mediaStreamRecorder.end();\n await this._mediaStreamRecorder.begin(track);\n await this.startRecording();\n } else {\n logger.warn(\n \"track-started event received for current track and already recording\"\n );\n }\n break;\n }\n this._currentAudioTrack = track;\n }\n\n private handleTrackStarted(ev: DailyEventObjectTrack) {\n if (ev.type === \"screenAudio\" || ev.type === \"screenVideo\") {\n this._callbacks.onScreenTrackStarted?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n } else {\n if (ev.participant?.local && ev.track.kind === \"audio\") {\n void this.handleLocalAudioTrack(ev.track);\n }\n this._callbacks.onTrackStarted?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n }\n }\n\n private handleTrackStopped(ev: DailyEventObjectTrack) {\n if (ev.type === \"screenAudio\" || ev.type === \"screenVideo\") {\n this._callbacks.onScreenTrackStopped?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n } else {\n this._callbacks.onTrackStopped?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n }\n }\n\n private handleParticipantJoined(ev: DailyEventObjectParticipant) {\n const p = dailyParticipantToParticipant(ev.participant);\n\n this._callbacks.onParticipantJoined?.(p);\n\n if (p.local) return;\n\n this._botId = ev.participant.session_id;\n\n this._callbacks.onBotConnected?.(p);\n }\n\n private handleParticipantLeft(ev: DailyEventObjectParticipantLeft) {\n const p = dailyParticipantToParticipant(ev.participant);\n\n this._callbacks.onParticipantLeft?.(p);\n\n if (p.local) return;\n\n this._botId = \"\";\n\n this._callbacks.onBotDisconnected?.(p);\n }\n\n private handleLocalAudioLevel(ev: DailyEventObjectLocalAudioLevel) {\n this._callbacks.onLocalAudioLevel?.(ev.audioLevel);\n }\n\n private handleRemoteAudioLevel(\n ev: DailyEventObjectRemoteParticipantsAudioLevel\n ) {\n const participants = this._daily.participants();\n const ids = Object.keys(ev.participantsAudioLevel);\n for (let i = 0; i < ids.length; i++) {\n const id = ids[i];\n const level = ev.participantsAudioLevel[id];\n this._callbacks.onRemoteAudioLevel?.(\n level,\n dailyParticipantToParticipant(participants[id])\n );\n }\n }\n\n private handleLeftMeeting() {\n this.state = \"disconnected\";\n this._botId = \"\";\n this._callbacks.onDisconnected?.();\n }\n\n private handleNonFatalError(ev: DailyEventObjectNonFatalError) {\n switch (ev.type) {\n case \"screen-share-error\":\n this._callbacks.onScreenShareError?.(ev.errorMsg);\n break;\n }\n }\n}\n\nconst dailyParticipantToParticipant = (p: DailyParticipant): Participant => ({\n id: p.user_id,\n local: p.local,\n name: p.user_name,\n});\n","import { WavPacker } from './lib/wav_packer.js';\nimport { AudioAnalysis } from './lib/analysis/audio_analysis.js';\nimport { WavStreamPlayer } from './lib/wav_stream_player.js';\nimport { WavRecorder } from './lib/wav_recorder.js';\nimport { MediaStreamRecorder } from './lib/mediastream_recorder.js';\n\nexport {\n AudioAnalysis,\n MediaStreamRecorder,\n WavPacker,\n WavStreamPlayer,\n WavRecorder,\n};\n","/**\n * Raw wav audio file contents\n * @typedef {Object} WavPackerAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {number} channelCount\n * @property {number} sampleRate\n * @property {number} duration\n */\n\n/**\n * Utility class for assembling PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavPacker {\n /**\n * Converts Float32Array of amplitude data to ArrayBuffer in Int16Array format\n * @param {Float32Array} float32Array\n * @returns {ArrayBuffer}\n */\n static floatTo16BitPCM(float32Array) {\n const buffer = new ArrayBuffer(float32Array.length * 2);\n const view = new DataView(buffer);\n let offset = 0;\n for (let i = 0; i < float32Array.length; i++, offset += 2) {\n let s = Math.max(-1, Math.min(1, float32Array[i]));\n view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n }\n return buffer;\n }\n\n /**\n * Concatenates two ArrayBuffers\n * @param {ArrayBuffer} leftBuffer\n * @param {ArrayBuffer} rightBuffer\n * @returns {ArrayBuffer}\n */\n static mergeBuffers(leftBuffer, rightBuffer) {\n const tmpArray = new Uint8Array(\n leftBuffer.byteLength + rightBuffer.byteLength\n );\n tmpArray.set(new Uint8Array(leftBuffer), 0);\n tmpArray.set(new Uint8Array(rightBuffer), leftBuffer.byteLength);\n return tmpArray.buffer;\n }\n\n /**\n * Packs data into an Int16 format\n * @private\n * @param {number} size 0 = 1x Int16, 1 = 2x Int16\n * @param {number} arg value to pack\n * @returns\n */\n _packData(size, arg) {\n return [\n new Uint8Array([arg, arg >> 8]),\n new Uint8Array([arg, arg >> 8, arg >> 16, arg >> 24]),\n ][size];\n }\n\n /**\n * Packs audio into \"audio/wav\" Blob\n * @param {number} sampleRate\n * @param {{bitsPerSample: number, channels: Array<Float32Array>, data: Int16Array}} audio\n * @returns {WavPackerAudioType}\n */\n pack(sampleRate, audio) {\n if (!audio?.bitsPerSample) {\n throw new Error(`Missing \"bitsPerSample\"`);\n } else if (!audio?.channels) {\n throw new Error(`Missing \"channels\"`);\n } else if (!audio?.data) {\n throw new Error(`Missing \"data\"`);\n }\n const { bitsPerSample, channels, data } = audio;\n const output = [\n // Header\n 'RIFF',\n this._packData(\n 1,\n 4 + (8 + 24) /* chunk 1 length */ + (8 + 8) /* chunk 2 length */\n ), // Length\n 'WAVE',\n // chunk 1\n 'fmt ', // Sub-chunk identifier\n this._packData(1, 16), // Chunk length\n this._packData(0, 1), // Audio format (1 is linear quantization)\n this._packData(0, channels.length),\n this._packData(1, sampleRate),\n this._packData(1, (sampleRate * channels.length * bitsPerSample) / 8), // Byte rate\n this._packData(0, (channels.length * bitsPerSample) / 8),\n this._packData(0, bitsPerSample),\n // chunk 2\n 'data', // Sub-chunk identifier\n this._packData(\n 1,\n (channels[0].length * channels.length * bitsPerSample) / 8\n ), // Chunk length\n data,\n ];\n const blob = new Blob(output, { type: 'audio/mpeg' });\n const url = URL.createObjectURL(blob);\n return {\n blob,\n url,\n channelCount: channels.length,\n sampleRate,\n duration: data.byteLength / (channels.length * sampleRate * 2),\n };\n }\n}\n\nglobalThis.WavPacker = WavPacker;\n","import {\n noteFrequencies,\n noteFrequencyLabels,\n voiceFrequencies,\n voiceFrequencyLabels,\n} from './constants.js';\n\n/**\n * Output of AudioAnalysis for the frequency domain of the audio\n * @typedef {Object} AudioAnalysisOutputType\n * @property {Float32Array} values Amplitude of this frequency between {0, 1} inclusive\n * @property {number[]} frequencies Raw frequency bucket values\n * @property {string[]} labels Labels for the frequency bucket values\n */\n\n/**\n * Analyzes audio for visual output\n * @class\n */\nexport class AudioAnalysis {\n /**\n * Retrieves frequency domain data from an AnalyserNode adjusted to a decibel range\n * returns human-readable formatting and labels\n * @param {AnalyserNode} analyser\n * @param {number} sampleRate\n * @param {Float32Array} [fftResult]\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {AudioAnalysisOutputType}\n */\n static getFrequencies(\n analyser,\n sampleRate,\n fftResult,\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30,\n ) {\n if (!fftResult) {\n fftResult = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(fftResult);\n }\n const nyquistFrequency = sampleRate / 2;\n const frequencyStep = (1 / fftResult.length) * nyquistFrequency;\n let outputValues;\n let frequencies;\n let labels;\n if (analysisType === 'music' || analysisType === 'voice') {\n const useFrequencies =\n analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n const aggregateOutput = Array(useFrequencies.length).fill(minDecibels);\n for (let i = 0; i < fftResult.length; i++) {\n const frequency = i * frequencyStep;\n const amplitude = fftResult[i];\n for (let n = useFrequencies.length - 1; n >= 0; n--) {\n if (frequency > useFrequencies[n]) {\n aggregateOutput[n] = Math.max(aggregateOutput[n], amplitude);\n break;\n }\n }\n }\n outputValues = aggregateOutput;\n frequencies =\n analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n labels =\n analysisType === 'voice' ? voiceFrequencyLabels : noteFrequencyLabels;\n } else {\n outputValues = Array.from(fftResult);\n frequencies = outputValues.map((_, i) => frequencyStep * i);\n labels = frequencies.map((f) => `${f.toFixed(2)} Hz`);\n }\n // We normalize to {0, 1}\n const normalizedOutput = outputValues.map((v) => {\n return Math.max(\n 0,\n Math.min((v - minDecibels) / (maxDecibels - minDecibels), 1),\n );\n });\n const values = new Float32Array(normalizedOutput);\n return {\n values,\n frequencies,\n labels,\n };\n }\n\n /**\n * Creates a new AudioAnalysis instance for an HTMLAudioElement\n * @param {HTMLAudioElement} audioElement\n * @param {AudioBuffer|null} [audioBuffer] If provided, will cache all frequency domain data from the buffer\n * @returns {AudioAnalysis}\n */\n constructor(audioElement, audioBuffer = null) {\n this.fftResults = [];\n if (audioBuffer) {\n /**\n * Modified from\n * https://stackoverflow.com/questions/75063715/using-the-web-audio-api-to-analyze-a-song-without-playing\n *\n * We do this to populate FFT values for the audio if provided an `audioBuffer`\n * The reason to do this is that Safari fails when using `createMediaElementSource`\n * This has a non-zero RAM cost so we only opt-in to run it on Safari, Chrome is better\n */\n const { length, sampleRate } = audioBuffer;\n const offlineAudioContext = new OfflineAudioContext({\n length,\n sampleRate,\n });\n const source = offlineAudioContext.createBufferSource();\n source.buffer = audioBuffer;\n const analyser = offlineAudioContext.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n source.connect(analyser);\n // limit is :: 128 / sampleRate;\n // but we just want 60fps - cuts ~1s from 6MB to 1MB of RAM\n const renderQuantumInSeconds = 1 / 60;\n const durationInSeconds = length / sampleRate;\n const analyze = (index) => {\n const suspendTime = renderQuantumInSeconds * index;\n if (suspendTime < durationInSeconds) {\n offlineAudioContext.suspend(suspendTime).then(() => {\n const fftResult = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(fftResult);\n this.fftResults.push(fftResult);\n analyze(index + 1);\n });\n }\n if (index === 1) {\n offlineAudioContext.startRendering();\n } else {\n offlineAudioContext.resume();\n }\n };\n source.start(0);\n analyze(1);\n this.audio = audioElement;\n this.context = offlineAudioContext;\n this.analyser = analyser;\n this.sampleRate = sampleRate;\n this.audioBuffer = audioBuffer;\n } else {\n const audioContext = new AudioContext();\n const track = audioContext.createMediaElementSource(audioElement);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n track.connect(analyser);\n analyser.connect(audioContext.destination);\n this.audio = audioElement;\n this.context = audioContext;\n this.analyser = analyser;\n this.sampleRate = this.context.sampleRate;\n this.audioBuffer = null;\n }\n }\n\n /**\n * Gets the current frequency domain data from the playing audio track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30,\n ) {\n let fftResult = null;\n if (this.audioBuffer && this.fftResults.length) {\n const pct = this.audio.currentTime / this.audio.duration;\n const index = Math.min(\n (pct * this.fftResults.length) | 0,\n this.fftResults.length - 1,\n );\n fftResult = this.fftResults[index];\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n fftResult,\n analysisType,\n minDecibels,\n maxDecibels,\n );\n }\n\n /**\n * Resume the internal AudioContext if it was suspended due to the lack of\n * user interaction when the AudioAnalysis was instantiated.\n * @returns {Promise<true>}\n */\n async resumeIfSuspended() {\n if (this.context.state === 'suspended') {\n await this.context.resume();\n }\n return true;\n }\n}\n\nglobalThis.AudioAnalysis = AudioAnalysis;\n","/**\n * Constants for help with visualization\n * Helps map frequency ranges from Fast Fourier Transform\n * to human-interpretable ranges, notably music ranges and\n * human vocal ranges.\n */\n\n// Eighth octave frequencies\nconst octave8Frequencies = [\n 4186.01, 4434.92, 4698.63, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93,\n 6644.88, 7040.0, 7458.62, 7902.13,\n];\n\n// Labels for each of the above frequencies\nconst octave8FrequencyLabels = [\n 'C',\n 'C#',\n 'D',\n 'D#',\n 'E',\n 'F',\n 'F#',\n 'G',\n 'G#',\n 'A',\n 'A#',\n 'B',\n];\n\n/**\n * All note frequencies from 1st to 8th octave\n * in format \"A#8\" (A#, 8th octave)\n */\nexport const noteFrequencies = [];\nexport const noteFrequencyLabels = [];\nfor (let i = 1; i <= 8; i++) {\n for (let f = 0; f < octave8Frequencies.length; f++) {\n const freq = octave8Frequencies[f];\n noteFrequencies.push(freq / Math.pow(2, 8 - i));\n noteFrequencyLabels.push(octave8FrequencyLabels[f] + i);\n }\n}\n\n/**\n * Subset of the note frequencies between 32 and 2000 Hz\n * 6 octave range: C1 to B6\n */\nconst voiceFrequencyRange = [32.0, 2000.0];\nexport const voiceFrequencies = noteFrequencies.filter((_, i) => {\n return (\n noteFrequencies[i] > voiceFrequencyRange[0] &&\n noteFrequencies[i] < voiceFrequencyRange[1]\n );\n});\nexport const voiceFrequencyLabels = noteFrequencyLabels.filter((_, i) => {\n return (\n noteFrequencies[i] > voiceFrequencyRange[0] &&\n noteFrequencies[i] < voiceFrequencyRange[1]\n );\n});\n","import { StreamProcessorSrc } from \"./worklets/stream_processor.js\";\nimport { AudioAnalysis } from \"./analysis/audio_analysis.js\";\n\n/**\n * Plays audio streams received in raw PCM16 chunks from the browser\n * @class\n */\nexport class WavStreamPlayer {\n /**\n * Creates a new WavStreamPlayer instance\n * @param {{sampleRate?: number}} options\n * @returns {WavStreamPlayer}\n */\n constructor({ sampleRate = 44100 } = {}) {\n this.scriptSrc = StreamProcessorSrc;\n this.sampleRate = sampleRate;\n this.context = null;\n this.stream = null;\n this.analyser = null;\n this.trackSampleOffsets = {};\n this.interruptedTrackIds = {};\n }\n\n /**\n * Connects the audio context and enables output to speakers\n * @returns {Promise<true>}\n */\n async connect() {\n this.context = new AudioContext({ sampleRate: this.sampleRate });\n if (this._speakerID) {\n this.context.setSinkId(this._speakerID);\n }\n if (this.context.state === \"suspended\") {\n await this.context.resume();\n }\n try {\n await this.context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const analyser = this.context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n this.analyser = analyser;\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the playing track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = \"frequency\",\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.analyser) {\n throw new Error(\"Not connected, please call .connect() first\");\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * @param {string} speaker deviceId\n */\n async updateSpeaker(speaker) {\n const _prevSpeaker = this._speakerID;\n this._speakerID = speaker;\n if (this.context) {\n try {\n if (speaker === \"default\") {\n await this.context.setSinkId();\n } else {\n await this.context.setSinkId(speaker);\n }\n } catch (e) {\n console.error(`Could not set sinkId to ${speaker}: ${e}`);\n this._speakerID = _prevSpeaker;\n }\n }\n }\n\n /**\n * Starts audio streaming\n * @private\n * @returns {Promise<true>}\n */\n _start() {\n const streamNode = new AudioWorkletNode(this.context, \"stream_processor\");\n streamNode.connect(this.context.destination);\n streamNode.port.onmessage = (e) => {\n const { event } = e.data;\n if (event === \"stop\") {\n streamNode.disconnect();\n this.stream = null;\n } else if (event === \"offset\") {\n const { requestId, trackId, offset } = e.data;\n const currentTime = offset / this.sampleRate;\n this.trackSampleOffsets[requestId] = { trackId, offset, currentTime };\n }\n };\n this.analyser.disconnect();\n streamNode.connect(this.analyser);\n this.stream = streamNode;\n return true;\n }\n\n /**\n * Adds 16BitPCM data to the currently playing audio stream\n * You can add chunks beyond the current play point and they will be queued for play\n * @param {ArrayBuffer|Int16Array} arrayBuffer\n * @param {string} [trackId]\n * @returns {Int16Array}\n */\n add16BitPCM(arrayBuffer, trackId = \"default\") {\n if (typeof trackId !== \"string\") {\n throw new Error(`trackId must be a string`);\n } else if (this.interruptedTrackIds[trackId]) {\n return;\n }\n if (!this.stream) {\n this._start();\n }\n let buffer;\n if (arrayBuffer instanceof Int16Array) {\n buffer = arrayBuffer;\n } else if (arrayBuffer instanceof ArrayBuffer) {\n buffer = new Int16Array(arrayBuffer);\n } else {\n throw new Error(`argument must be Int16Array or ArrayBuffer`);\n }\n this.stream.port.postMessage({ event: \"write\", buffer, trackId });\n return buffer;\n }\n\n /**\n * Gets the offset (sample count) of the currently playing stream\n * @param {boolean} [interrupt]\n * @returns {{trackId: string|null, offset: number, currentTime: number}}\n */\n async getTrackSampleOffset(interrupt = false) {\n if (!this.stream) {\n return null;\n }\n const requestId = crypto.randomUUID();\n this.stream.port.postMessage({\n event: interrupt ? \"interrupt\" : \"offset\",\n requestId,\n });\n let trackSampleOffset;\n while (!trackSampleOffset) {\n trackSampleOffset = this.trackSampleOffsets[requestId];\n await new Promise((r) => setTimeout(() => r(), 1));\n }\n const { trackId } = trackSampleOffset;\n if (interrupt && trackId) {\n this.interruptedTrackIds[trackId] = true;\n }\n return trackSampleOffset;\n }\n\n /**\n * Strips the current stream and returns the sample offset of the audio\n * @param {boolean} [interrupt]\n * @returns {{trackId: string|null, offset: number, currentTime: number}}\n */\n async interrupt() {\n return this.getTrackSampleOffset(true);\n }\n}\n\nglobalThis.WavStreamPlayer = WavStreamPlayer;\n","export const StreamProcessorWorklet = `\nclass StreamProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.hasStarted = false;\n this.hasInterrupted = false;\n this.outputBuffers = [];\n this.bufferLength = 128;\n this.write = { buffer: new Float32Array(this.bufferLength), trackId: null };\n this.writeOffset = 0;\n this.trackSampleOffsets = {};\n this.port.onmessage = (event) => {\n if (event.data) {\n const payload = event.data;\n if (payload.event === 'write') {\n const int16Array = payload.buffer;\n const float32Array = new Float32Array(int16Array.length);\n for (let i = 0; i < int16Array.length; i++) {\n float32Array[i] = int16Array[i] / 0x8000; // Convert Int16 to Float32\n }\n this.writeData(float32Array, payload.trackId);\n } else if (\n payload.event === 'offset' ||\n payload.event === 'interrupt'\n ) {\n const requestId = payload.requestId;\n const trackId = this.write.trackId;\n const offset = this.trackSampleOffsets[trackId] || 0;\n this.port.postMessage({\n event: 'offset',\n requestId,\n trackId,\n offset,\n });\n if (payload.event === 'interrupt') {\n this.hasInterrupted = true;\n }\n } else {\n throw new Error(\\`Unhandled event \"\\${payload.event}\"\\`);\n }\n }\n };\n }\n\n writeData(float32Array, trackId = null) {\n let { buffer } = this.write;\n let offset = this.writeOffset;\n for (let i = 0; i < float32Array.length; i++) {\n buffer[offset++] = float32Array[i];\n if (offset >= buffer.length) {\n this.outputBuffers.push(this.write);\n this.write = { buffer: new Float32Array(this.bufferLength), trackId };\n buffer = this.write.buffer;\n offset = 0;\n }\n }\n this.writeOffset = offset;\n return true;\n }\n\n process(inputs, outputs, parameters) {\n const output = outputs[0];\n const outputChannelData = output[0];\n const outputBuffers = this.outputBuffers;\n if (this.hasInterrupted) {\n this.port.postMessage({ event: 'stop' });\n return false;\n } else if (outputBuffers.length) {\n this.hasStarted = true;\n const { buffer, trackId } = outputBuffers.shift();\n for (let i = 0; i < outputChannelData.length; i++) {\n outputChannelData[i] = buffer[i] || 0;\n }\n if (trackId) {\n this.trackSampleOffsets[trackId] =\n this.trackSampleOffsets[trackId] || 0;\n this.trackSampleOffsets[trackId] += buffer.length;\n }\n return true;\n } else if (this.hasStarted) {\n this.port.postMessage({ event: 'stop' });\n return false;\n } else {\n return true;\n }\n }\n}\n\nregisterProcessor('stream_processor', StreamProcessor);\n`;\n\nconst script = new Blob([StreamProcessorWorklet], {\n type: 'application/javascript',\n});\nconst src = URL.createObjectURL(script);\nexport const StreamProcessorSrc = src;\n","import { AudioProcessorSrc } from './worklets/audio_processor.js';\nimport { AudioAnalysis } from './analysis/audio_analysis.js';\nimport { WavPacker } from './wav_packer.js';\n\n/**\n * Decodes audio into a wav file\n * @typedef {Object} DecodedAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {Float32Array} values\n * @property {AudioBuffer} audioBuffer\n */\n\n/**\n * Records live stream of user audio as PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavRecorder {\n /**\n * Create a new WavRecorder instance\n * @param {{sampleRate?: number, outputToSpeakers?: boolean, debug?: boolean}} [options]\n * @returns {WavRecorder}\n */\n constructor({\n sampleRate = 44100,\n outputToSpeakers = false,\n debug = false,\n } = {}) {\n // Script source\n this.scriptSrc = AudioProcessorSrc;\n // Config\n this.sampleRate = sampleRate;\n this.outputToSpeakers = outputToSpeakers;\n this.debug = !!debug;\n this._deviceChangeCallback = null;\n this._devices = [];\n this.deviceSelection = null;\n // State variables\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n this.recording = false;\n // Event handling with AudioWorklet\n this._lastEventId = 0;\n this.eventReceipts = {};\n this.eventTimeout = 5000;\n // Process chunks of audio\n this._chunkProcessor = () => {};\n this._chunkProcessorSize = void 0;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n\n /**\n * Decodes audio data from multiple formats to a Blob, url, Float32Array and AudioBuffer\n * @param {Blob|Float32Array|Int16Array|ArrayBuffer|number[]} audioData\n * @param {number} sampleRate\n * @param {number} fromSampleRate\n * @returns {Promise<DecodedAudioType>}\n */\n static async decode(audioData, sampleRate = 44100, fromSampleRate = -1) {\n const context = new AudioContext({ sampleRate });\n let arrayBuffer;\n let blob;\n if (audioData instanceof Blob) {\n if (fromSampleRate !== -1) {\n throw new Error(\n `Can not specify \"fromSampleRate\" when reading from Blob`\n );\n }\n blob = audioData;\n arrayBuffer = await blob.arrayBuffer();\n } else if (audioData instanceof ArrayBuffer) {\n if (fromSampleRate !== -1) {\n throw new Error(\n `Can not specify \"fromSampleRate\" when reading from ArrayBuffer`\n );\n }\n arrayBuffer = audioData;\n blob = new Blob([arrayBuffer], { type: 'audio/wav' });\n } else {\n let float32Array;\n let data;\n if (audioData instanceof Int16Array) {\n data = audioData;\n float32Array = new Float32Array(audioData.length);\n for (let i = 0; i < audioData.length; i++) {\n float32Array[i] = audioData[i] / 0x8000;\n }\n } else if (audioData instanceof Float32Array) {\n float32Array = audioData;\n } else if (audioData instanceof Array) {\n float32Array = new Float32Array(audioData);\n } else {\n throw new Error(\n `\"audioData\" must be one of: Blob, Float32Arrray, Int16Array, ArrayBuffer, Array<number>`\n );\n }\n if (fromSampleRate === -1) {\n throw new Error(\n `Must specify \"fromSampleRate\" when reading from Float32Array, In16Array or Array`\n );\n } else if (fromSampleRate < 3000) {\n throw new Error(`Minimum \"fromSampleRate\" is 3000 (3kHz)`);\n }\n if (!data) {\n data = WavPacker.floatTo16BitPCM(float32Array);\n }\n const audio = {\n bitsPerSample: 16,\n channels: [float32Array],\n data,\n };\n const packer = new WavPacker();\n const result = packer.pack(fromSampleRate, audio);\n blob = result.blob;\n arrayBuffer = await blob.arrayBuffer();\n }\n const audioBuffer = await context.decodeAudioData(arrayBuffer);\n const values = audioBuffer.getChannelData(0);\n const url = URL.createObjectURL(blob);\n return {\n blob,\n url,\n values,\n audioBuffer,\n };\n }\n\n /**\n * Logs data in debug mode\n * @param {...any} arguments\n * @returns {true}\n */\n log() {\n if (this.debug) {\n this.log(...arguments);\n }\n return true;\n }\n\n /**\n * Retrieves the current sampleRate for the recorder\n * @returns {number}\n */\n getSampleRate() {\n return this.sampleRate;\n }\n\n /**\n * Retrieves the current status of the recording\n * @returns {\"ended\"|\"paused\"|\"recording\"}\n */\n getStatus() {\n if (!this.processor) {\n return 'ended';\n } else if (!this.recording) {\n return 'paused';\n } else {\n return 'recording';\n }\n }\n\n /**\n * Sends an event to the AudioWorklet\n * @private\n * @param {string} name\n * @param {{[key: string]: any}} data\n * @param {AudioWorkletNode} [_processor]\n * @returns {Promise<{[key: string]: any}>}\n */\n async _event(name, data = {}, _processor = null) {\n _processor = _processor || this.processor;\n if (!_processor) {\n throw new Error('Can not send events without recording first');\n }\n const message = {\n event: name,\n id: this._lastEventId++,\n data,\n };\n _processor.port.postMessage(message);\n const t0 = new Date().valueOf();\n while (!this.eventReceipts[message.id]) {\n if (new Date().valueOf() - t0 > this.eventTimeout) {\n throw new Error(`Timeout waiting for \"${name}\" event`);\n }\n await new Promise((res) => setTimeout(() => res(true), 1));\n }\n const payload = this.eventReceipts[message.id];\n delete this.eventReceipts[message.id];\n return payload;\n }\n\n /**\n * Sets device change callback, remove if callback provided is `null`\n * @param {(Array<MediaDeviceInfo & {default: boolean}>): void|null} callback\n * @returns {true}\n */\n listenForDeviceChange(callback) {\n if (callback === null && this._deviceChangeCallback) {\n navigator.mediaDevices.removeEventListener(\n 'devicechange',\n this._deviceChangeCallback\n );\n this._deviceChangeCallback = null;\n } else if (callback !== null) {\n // Basically a debounce; we only want this called once when devices change\n // And we only want the most recent callback() to be executed\n // if a few are operating at the same time\n let lastId = 0;\n let lastDevices = [];\n const serializeDevices = (devices) =>\n devices\n .map((d) => d.deviceId)\n .sort()\n .join(',');\n const cb = async () => {\n let id = ++lastId;\n const devices = await this.listDevices();\n if (id === lastId) {\n if (serializeDevices(lastDevices) !== serializeDevices(devices)) {\n lastDevices = devices;\n callback(devices.slice());\n }\n }\n };\n navigator.mediaDevices.addEventListener('devicechange', cb);\n cb();\n this._deviceChangeCallback = cb;\n }\n return true;\n }\n\n /**\n * Manually request permission to use the microphone\n * @returns {Promise<true>}\n */\n async requestPermission() {\n const permissionStatus = await navigator.permissions.query({\n name: 'microphone',\n });\n if (permissionStatus.state === 'denied') {\n window.alert('You must grant microphone access to use this feature.');\n } else if (permissionStatus.state === 'prompt') {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n const tracks = stream.getTracks();\n tracks.forEach((track) => track.stop());\n } catch (e) {\n window.alert('You must grant microphone access to use this feature.');\n }\n }\n return true;\n }\n\n /**\n * List all eligible devices for recording, will request permission to use microphone\n * @returns {Promise<Array<MediaDeviceInfo & {default: boolean}>>}\n */\n async listDevices() {\n if (\n !navigator.mediaDevices ||\n !('enumerateDevices' in navigator.mediaDevices)\n ) {\n throw new Error('Could not request user devices');\n }\n await this.requestPermission();\n const devices = await navigator.mediaDevices.enumerateDevices();\n const audioDevices = devices.filter(\n (device) => device.kind === 'audioinput'\n );\n return audioDevices;\n // const defaultDeviceIndex = audioDevices.findIndex(\n // (device) => device.deviceId === 'default'\n // );\n // const deviceList = [];\n // if (defaultDeviceIndex !== -1) {\n // let defaultDevice = audioDevices.splice(defaultDeviceIndex, 1)[0];\n // let existingIndex = audioDevices.findIndex(\n // (device) => device.groupId === defaultDevice.groupId\n // );\n // if (existingIndex !== -1) {\n // defaultDevice = audioDevices.splice(existingIndex, 1)[0];\n // }\n // defaultDevice.default = true;\n // deviceList.push(defaultDevice);\n // }\n // return deviceList.concat(audioDevices);\n }\n\n /**\n * Begins a recording session and requests microphone permissions if not already granted\n * Microphone recording indicator will appear on browser tab but status will be \"paused\"\n * @param {string} [deviceId] if no device provided, default device will be used\n * @returns {Promise<true>}\n */\n async begin(deviceId) {\n if (this.processor) {\n throw new Error(\n `Already connected: please call .end() to start a new session`\n );\n }\n\n if (\n !navigator.mediaDevices ||\n !('getUserMedia' in navigator.mediaDevices)\n ) {\n throw new Error('Could not request user media');\n }\n deviceId = deviceId ?? this.deviceSelection?.deviceId;\n try {\n const config = { audio: true };\n if (deviceId) {\n config.audio = { deviceId: { exact: deviceId } };\n }\n this.stream = await navigator.mediaDevices.getUserMedia(config);\n } catch (err) {\n throw new Error('Could not start media stream');\n }\n\n this.listDevices().then((devices) => {\n deviceId = this.stream.getAudioTracks()[0].getSettings().deviceId;\n console.log(\n 'find current device',\n devices,\n deviceId,\n this.stream.getAudioTracks()[0].getSettings()\n );\n this.deviceSelection = devices.find((d) => d.deviceId === deviceId);\n console.log('current device', this.deviceSelection);\n });\n const context = new AudioContext({ sampleRate: this.sampleRate });\n const source = context.createMediaStreamSource(this.stream);\n // Load and execute the module script.\n try {\n await context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const processor = new AudioWorkletNode(context, 'audio_processor');\n processor.port.onmessage = (e) => {\n const { event, id, data } = e.data;\n if (event === 'receipt') {\n this.eventReceipts[id] = data;\n } else if (event === 'chunk') {\n if (this._chunkProcessorSize) {\n const buffer = this._chunkProcessorBuffer;\n this._chunkProcessorBuffer = {\n raw: WavPacker.mergeBuffers(buffer.raw, data.raw),\n mono: WavPacker.mergeBuffers(buffer.mono, data.mono),\n };\n if (\n this._chunkProcessorBuffer.mono.byteLength >=\n this._chunkProcessorSize\n ) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n } else {\n this._chunkProcessor(data);\n }\n }\n };\n\n const node = source.connect(processor);\n const analyser = context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n node.connect(analyser);\n if (this.outputToSpeakers) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Warning: Output to speakers may affect sound quality,\\n' +\n 'especially due to system audio feedback preventative measures.\\n' +\n 'use only for debugging'\n );\n analyser.connect(context.destination);\n }\n\n this.source = source;\n this.node = node;\n this.analyser = analyser;\n this.processor = processor;\n console.log('begin completed');\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the recording track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * Pauses the recording\n * Keeps microphone stream open but halts storage of audio\n * @returns {Promise<true>}\n */\n async pause() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n } else if (!this.recording) {\n throw new Error('Already paused: please call .record() first');\n }\n if (this._chunkProcessorBuffer.raw.byteLength) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n }\n this.log('Pausing ...');\n await this._event('stop');\n this.recording = false;\n return true;\n }\n\n /**\n * Start recording stream and storing to memory from the connected audio source\n * @param {(data: { mono: Int16Array; raw: Int16Array }) => any} [chunkProcessor]\n * @param {number} [chunkSize] chunkProcessor will not be triggered until this size threshold met in mono audio\n * @returns {Promise<true>}\n */\n async record(chunkProcessor = () => {}, chunkSize = 8192) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n } else if (this.recording) {\n throw new Error('Already recording: please call .pause() first');\n } else if (typeof chunkProcessor !== 'function') {\n throw new Error(`chunkProcessor must be a function`);\n }\n this._chunkProcessor = chunkProcessor;\n this._chunkProcessorSize = chunkSize;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n this.log('Recording ...');\n await this._event('start');\n this.recording = true;\n return true;\n }\n\n /**\n * Clears the audio buffer, empties stored recording\n * @returns {Promise<true>}\n */\n async clear() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n await this._event('clear');\n return true;\n }\n\n /**\n * Reads the current audio stream data\n * @returns {Promise<{meanValues: Float32Array, channels: Array<Float32Array>}>}\n */\n async read() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n this.log('Reading ...');\n const result = await this._event('read');\n return result;\n }\n\n /**\n * Saves the current audio stream to a file\n * @param {boolean} [force] Force saving while still recording\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async save(force = false) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n if (!force && this.recording) {\n throw new Error(\n 'Currently recording: please call .pause() first, or call .save(true) to force'\n );\n }\n this.log('Exporting ...');\n const exportData = await this._event('export');\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Ends the current recording session and saves the result\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async end() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n\n const _processor = this.processor;\n\n this.log('Stopping ...');\n await this._event('stop');\n this.recording = false;\n const tracks = this.stream.getTracks();\n tracks.forEach((track) => track.stop());\n\n this.log('Exporting ...');\n const exportData = await this._event('export', {}, _processor);\n\n this.processor.disconnect();\n this.source.disconnect();\n this.node.disconnect();\n this.analyser.disconnect();\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Performs a full cleanup of WavRecorder instance\n * Stops actively listening via microphone and removes existing listeners\n * @returns {Promise<true>}\n */\n async quit() {\n this.listenForDeviceChange(null);\n // we do not reset this on end so that selections persist across starts\n this.deviceSelection = null;\n if (this.processor) {\n await this.end();\n }\n return true;\n }\n}\n\nglobalThis.WavRecorder = WavRecorder;\n","const AudioProcessorWorklet = `\nclass AudioProcessor extends AudioWorkletProcessor {\n\n constructor() {\n super();\n this.port.onmessage = this.receive.bind(this);\n this.initialize();\n }\n\n initialize() {\n this.foundAudio = false;\n this.recording = false;\n this.chunks = [];\n }\n\n /**\n * Concatenates sampled chunks into channels\n * Format is chunk[Left[], Right[]]\n */\n readChannelData(chunks, channel = -1, maxChannels = 9) {\n let channelLimit;\n if (channel !== -1) {\n if (chunks[0] && chunks[0].length - 1 < channel) {\n throw new Error(\n \\`Channel \\${channel} out of range: max \\${chunks[0].length}\\`\n );\n }\n channelLimit = channel + 1;\n } else {\n channel = 0;\n channelLimit = Math.min(chunks[0] ? chunks[0].length : 1, maxChannels);\n }\n const channels = [];\n for (let n = channel; n < channelLimit; n++) {\n const length = chunks.reduce((sum, chunk) => {\n return sum + chunk[n].length;\n }, 0);\n const buffers = chunks.map((chunk) => chunk[n]);\n const result = new Float32Array(length);\n let offset = 0;\n for (let i = 0; i < buffers.length; i++) {\n result.set(buffers[i], offset);\n offset += buffers[i].length;\n }\n channels[n] = result;\n }\n return channels;\n }\n\n /**\n * Combines parallel audio data into correct format,\n * channels[Left[], Right[]] to float32Array[LRLRLRLR...]\n */\n formatAudioData(channels) {\n if (channels.length === 1) {\n // Simple case is only one channel\n const float32Array = channels[0].slice();\n const meanValues = channels[0].slice();\n return { float32Array, meanValues };\n } else {\n const float32Array = new Float32Array(\n channels[0].length * channels.length\n );\n const meanValues = new Float32Array(channels[0].length);\n for (let i = 0; i < channels[0].length; i++) {\n const offset = i * channels.length;\n let meanValue = 0;\n for (let n = 0; n < channels.length; n++) {\n float32Array[offset + n] = channels[n][i];\n meanValue += channels[n][i];\n }\n meanValues[i] = meanValue / channels.length;\n }\n return { float32Array, meanValues };\n }\n }\n\n /**\n * Converts 32-bit float data to 16-bit integers\n */\n floatTo16BitPCM(float32Array) {\n const buffer = new ArrayBuffer(float32Array.length * 2);\n const view = new DataView(buffer);\n let offset = 0;\n for (let i = 0; i < float32Array.length; i++, offset += 2) {\n let s = Math.max(-1, Math.min(1, float32Array[i]));\n view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n }\n return buffer;\n }\n\n /**\n * Retrieves the most recent amplitude values from the audio stream\n * @param {number} channel\n */\n getValues(channel = -1) {\n const channels = this.readChannelData(this.chunks, channel);\n const { meanValues } = this.formatAudioData(channels);\n return { meanValues, channels };\n }\n\n /**\n * Exports chunks as an audio/wav file\n */\n export() {\n const channels = this.readChannelData(this.chunks);\n const { float32Array, meanValues } = this.formatAudioData(channels);\n const audioData = this.floatTo16BitPCM(float32Array);\n return {\n meanValues: meanValues,\n audio: {\n bitsPerSample: 16,\n channels: channels,\n data: audioData,\n },\n };\n }\n\n receive(e) {\n const { event, id } = e.data;\n let receiptData = {};\n switch (event) {\n case 'start':\n this.recording = true;\n break;\n case 'stop':\n this.recording = false;\n break;\n case 'clear':\n this.initialize();\n break;\n case 'export':\n receiptData = this.export();\n break;\n case 'read':\n receiptData = this.getValues();\n break;\n default:\n break;\n }\n // Always send back receipt\n this.port.postMessage({ event: 'receipt', id, data: receiptData });\n }\n\n sendChunk(chunk) {\n const channels = this.readChannelData([chunk]);\n const { float32Array, meanValues } = this.formatAudioData(channels);\n const rawAudioData = this.floatTo16BitPCM(float32Array);\n const monoAudioData = this.floatTo16BitPCM(meanValues);\n this.port.postMessage({\n event: 'chunk',\n data: {\n mono: monoAudioData,\n raw: rawAudioData,\n },\n });\n }\n\n process(inputList, outputList, parameters) {\n // Copy input to output (e.g. speakers)\n // Note that this creates choppy sounds with Mac products\n const sourceLimit = Math.min(inputList.length, outputList.length);\n for (let inputNum = 0; inputNum < sourceLimit; inputNum++) {\n const input = inputList[inputNum];\n const output = outputList[inputNum];\n const channelCount = Math.min(input.length, output.length);\n for (let channelNum = 0; channelNum < channelCount; channelNum++) {\n input[channelNum].forEach((sample, i) => {\n output[channelNum][i] = sample;\n });\n }\n }\n const inputs = inputList[0];\n // There's latency at the beginning of a stream before recording starts\n // Make sure we actually receive audio data before we start storing chunks\n let sliceIndex = 0;\n if (!this.foundAudio) {\n for (const channel of inputs) {\n sliceIndex = 0; // reset for each channel\n if (this.foundAudio) {\n break;\n }\n if (channel) {\n for (const value of channel) {\n if (value !== 0) {\n // find only one non-zero entry in any channel\n this.foundAudio = true;\n break;\n } else {\n sliceIndex++;\n }\n }\n }\n }\n }\n if (inputs && inputs[0] && this.foundAudio && this.recording) {\n // We need to copy the TypedArray, because the \\`process\\`\n // internals will reuse the same buffer to hold each input\n const chunk = inputs.map((input) => input.slice(sliceIndex));\n this.chunks.push(chunk);\n this.sendChunk(chunk);\n }\n return true;\n }\n}\n\nregisterProcessor('audio_processor', AudioProcessor);\n`;\n\nconst script = new Blob([AudioProcessorWorklet], {\n type: 'application/javascript',\n});\nconst src = URL.createObjectURL(script);\nexport const AudioProcessorSrc = src;\n","import { AudioProcessorSrc } from \"./worklets/audio_processor.js\";\nimport { AudioAnalysis } from \"./analysis/audio_analysis.js\";\nimport { WavPacker } from \"./wav_packer.js\";\n\n/**\n * Decodes audio into a wav file\n * @typedef {Object} DecodedAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {Float32Array} values\n * @property {AudioBuffer} audioBuffer\n */\n\n/**\n * Records live stream of user audio as PCM16 \"audio/wav\" data\n * @class\n */\nexport class MediaStreamRecorder {\n /**\n * Create a new MediaStreamRecorder instance\n * @param {{sampleRate?: number, outputToSpeakers?: boolean, debug?: boolean}} [options]\n * @returns {MediaStreamRecorder}\n */\n constructor({\n sampleRate = 44100,\n outputToSpeakers = false,\n debug = false,\n } = {}) {\n // Script source\n this.scriptSrc = AudioProcessorSrc;\n // Config\n this.sampleRate = sampleRate;\n this.outputToSpeakers = outputToSpeakers;\n this.debug = !!debug;\n // State variables\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n this.recording = false;\n // Event handling with AudioWorklet\n this._lastEventId = 0;\n this.eventReceipts = {};\n this.eventTimeout = 5000;\n // Process chunks of audio\n this._chunkProcessor = () => {};\n this._chunkProcessorSize = void 0;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n\n /**\n * Logs data in debug mode\n * @param {...any} arguments\n * @returns {true}\n */\n log() {\n if (this.debug) {\n this.log(...arguments);\n }\n return true;\n }\n\n /**\n * Retrieves the current sampleRate for the recorder\n * @returns {number}\n */\n getSampleRate() {\n return this.sampleRate;\n }\n\n /**\n * Retrieves the current status of the recording\n * @returns {\"ended\"|\"paused\"|\"recording\"}\n */\n getStatus() {\n if (!this.processor) {\n return \"ended\";\n } else if (!this.recording) {\n return \"paused\";\n } else {\n return \"recording\";\n }\n }\n\n /**\n * Sends an event to the AudioWorklet\n * @private\n * @param {string} name\n * @param {{[key: string]: any}} data\n * @param {AudioWorkletNode} [_processor]\n * @returns {Promise<{[key: string]: any}>}\n */\n async _event(name, data = {}, _processor = null) {\n _processor = _processor || this.processor;\n if (!_processor) {\n throw new Error(\"Can not send events without recording first\");\n }\n const message = {\n event: name,\n id: this._lastEventId++,\n data,\n };\n _processor.port.postMessage(message);\n const t0 = new Date().valueOf();\n while (!this.eventReceipts[message.id]) {\n if (new Date().valueOf() - t0 > this.eventTimeout) {\n throw new Error(`Timeout waiting for \"${name}\" event`);\n }\n await new Promise((res) => setTimeout(() => res(true), 1));\n }\n const payload = this.eventReceipts[message.id];\n delete this.eventReceipts[message.id];\n return payload;\n }\n\n /**\n * Begins a recording session for the given audioTrack\n * Microphone recording indicator will appear on browser tab but status will be \"paused\"\n * @param {MediaStreamTrack} [audioTrack] if no device provided, default device will be used\n * @returns {Promise<true>}\n */\n async begin(audioTrack) {\n if (this.processor) {\n throw new Error(\n `Already connected: please call .end() to start a new session`\n );\n }\n\n if (!audioTrack || audioTrack.kind !== \"audio\") {\n throw new Error(\"No audio track provided\");\n }\n\n this.stream = new MediaStream([audioTrack]);\n\n const context = new AudioContext({ sampleRate: this.sampleRate });\n const source = context.createMediaStreamSource(this.stream);\n // Load and execute the module script.\n try {\n await context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const processor = new AudioWorkletNode(context, \"audio_processor\");\n processor.port.onmessage = (e) => {\n const { event, id, data } = e.data;\n if (event === \"receipt\") {\n this.eventReceipts[id] = data;\n } else if (event === \"chunk\") {\n if (this._chunkProcessorSize) {\n const buffer = this._chunkProcessorBuffer;\n this._chunkProcessorBuffer = {\n raw: WavPacker.mergeBuffers(buffer.raw, data.raw),\n mono: WavPacker.mergeBuffers(buffer.mono, data.mono),\n };\n if (\n this._chunkProcessorBuffer.mono.byteLength >=\n this._chunkProcessorSize\n ) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n } else {\n this._chunkProcessor(data);\n }\n }\n };\n\n const node = source.connect(processor);\n const analyser = context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n node.connect(analyser);\n if (this.outputToSpeakers) {\n // eslint-disable-next-line no-console\n console.warn(\n \"Warning: Output to speakers may affect sound quality,\\n\" +\n \"especially due to system audio feedback preventative measures.\\n\" +\n \"use only for debugging\"\n );\n analyser.connect(context.destination);\n }\n\n this.source = source;\n this.node = node;\n this.analyser = analyser;\n this.processor = processor;\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the recording track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = \"frequency\",\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * Pauses the recording\n * Keeps microphone stream open but halts storage of audio\n * @returns {Promise<true>}\n */\n async pause() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n } else if (!this.recording) {\n throw new Error(\"Already paused: please call .record() first\");\n }\n if (this._chunkProcessorBuffer.raw.byteLength) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n }\n this.log(\"Pausing ...\");\n await this._event(\"stop\");\n this.recording = false;\n return true;\n }\n\n /**\n * Start recording stream and storing to memory from the connected audio source\n * @param {(data: { mono: Int16Array; raw: Int16Array }) => any} [chunkProcessor]\n * @param {number} [chunkSize] chunkProcessor will not be triggered until this size threshold met in mono audio\n * @returns {Promise<true>}\n */\n async record(chunkProcessor = () => {}, chunkSize = 8192) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n } else if (this.recording) {\n throw new Error(\"Already recording: HELLO please call .pause() first\");\n } else if (typeof chunkProcessor !== \"function\") {\n throw new Error(`chunkProcessor must be a function`);\n }\n this._chunkProcessor = chunkProcessor;\n this._chunkProcessorSize = chunkSize;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n this.log(\"Recording ...\");\n await this._event(\"start\");\n this.recording = true;\n return true;\n }\n\n /**\n * Clears the audio buffer, empties stored recording\n * @returns {Promise<true>}\n */\n async clear() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n await this._event(\"clear\");\n return true;\n }\n\n /**\n * Reads the current audio stream data\n * @returns {Promise<{meanValues: Float32Array, channels: Array<Float32Array>}>}\n */\n async read() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n this.log(\"Reading ...\");\n const result = await this._event(\"read\");\n return result;\n }\n\n /**\n * Saves the current audio stream to a file\n * @param {boolean} [force] Force saving while still recording\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async save(force = false) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n if (!force && this.recording) {\n throw new Error(\n \"Currently recording: please call .pause() first, or call .save(true) to force\"\n );\n }\n this.log(\"Exporting ...\");\n const exportData = await this._event(\"export\");\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Ends the current recording session and saves the result\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async end() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n\n const _processor = this.processor;\n\n this.log(\"Stopping ...\");\n await this._event(\"stop\");\n this.recording = false;\n\n this.log(\"Exporting ...\");\n const exportData = await this._event(\"export\", {}, _processor);\n\n this.processor.disconnect();\n this.source.disconnect();\n this.node.disconnect();\n this.analyser.disconnect();\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Performs a full cleanup of WavRecorder instance\n * Stops actively listening via microphone and removes existing listeners\n * @returns {Promise<true>}\n */\n async quit() {\n this.listenForDeviceChange(null);\n if (this.processor) {\n await this.end();\n }\n return true;\n }\n}\n\nglobalThis.WavRecorder = WavRecorder;\n"],"names":[],"version":3,"file":"index.js.map"}
|
|
1
|
+
{"mappings":"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","sources":["transports/daily/src/index.ts","transports/daily/src/transport.ts","lib/wavtools/index.js","lib/wavtools/lib/wav_packer.js","lib/wavtools/lib/analysis/audio_analysis.js","lib/wavtools/lib/analysis/constants.js","lib/wavtools/lib/wav_stream_player.js","lib/wavtools/lib/worklets/stream_processor.js","lib/wavtools/lib/wav_recorder.js","lib/wavtools/lib/worklets/audio_processor.js","lib/wavtools/lib/mediastream_recorder.js"],"sourcesContent":["export * from \"./transport\";\n","import Daily, {\n DailyCall,\n DailyEventObjectAppMessage,\n DailyEventObjectAvailableDevicesUpdated,\n DailyEventObjectFatalError,\n DailyEventObjectLocalAudioLevel,\n DailyEventObjectNonFatalError,\n DailyEventObjectParticipant,\n DailyEventObjectParticipantLeft,\n DailyEventObjectRemoteParticipantsAudioLevel,\n DailyEventObjectSelectedDevicesUpdated,\n DailyEventObjectTrack,\n DailyFactoryOptions,\n DailyParticipant,\n} from \"@daily-co/daily-js\";\nimport {\n Participant,\n RTVIClientOptions,\n RTVIError,\n RTVIEventCallbacks,\n RTVIMessage,\n Tracks,\n Transport,\n TransportStartError,\n TransportState,\n logger,\n} from \"@pipecat-ai/client-js\";\n\nimport { MediaStreamRecorder } from \"../../../lib/wavtools\";\n\nexport interface DailyTransportAuthBundle {\n room_url: string;\n token: string;\n}\n\nexport interface DailyTransportConstructorOptions {\n bufferLocalAudioUntilBotReady?: boolean;\n dailyFactoryOptions?: DailyFactoryOptions;\n}\n\nexport enum DailyRTVIMessageType {\n AUDIO_BUFFERING_STARTED = \"audio-buffering-started\",\n AUDIO_BUFFERING_STOPPED = \"audio-buffering-stopped\",\n}\n\nclass DailyCallWrapper {\n private _daily: DailyCall;\n private _proxy: DailyCall;\n\n constructor(daily: DailyCall) {\n this._daily = daily;\n this._proxy = new Proxy(this._daily, {\n get: (target, prop, receiver) => {\n if (typeof target[prop as keyof DailyCall] === \"function\") {\n let errMsg;\n switch (String(prop)) {\n // Disable methods that modify the lifecycle of the call. These operations\n // should be performed via the RTVI client in order to keep state in sync.\n case \"preAuth\":\n errMsg = `Calls to preAuth() are disabled. Please use Transport.preAuth()`;\n break;\n case \"startCamera\":\n errMsg = `Calls to startCamera() are disabled. Please use RTVIClient.initDevices() or Transport.initDevices()`;\n break;\n case \"join\":\n errMsg = `Calls to join() are disabled. Please use RTVIClient.connect()`;\n break;\n case \"leave\":\n errMsg = `Calls to leave() are disabled. Please use RTVIClient.disconnect()`;\n break;\n case \"destroy\":\n errMsg = `Calls to destroy() are disabled.`;\n break;\n }\n if (errMsg) {\n return () => {\n throw new Error(errMsg);\n };\n }\n // Forward other method calls\n return (...args: any[]) => {\n return (target[prop as keyof DailyCall] as Function)(...args);\n };\n }\n // Forward property access\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n\n get proxy(): DailyCall {\n return this._proxy;\n }\n}\n\nexport class DailyTransport extends Transport {\n private declare _dailyWrapper: DailyCallWrapper;\n private declare _daily: DailyCall;\n private _dailyFactoryOptions: DailyFactoryOptions;\n\n private _bufferLocalAudioUntilBotReady: boolean;\n private _botId: string = \"\";\n private _selectedCam: MediaDeviceInfo | Record<string, never> = {};\n private _selectedMic: MediaDeviceInfo | Record<string, never> = {};\n private _selectedSpeaker: MediaDeviceInfo | Record<string, never> = {};\n\n private static RECORDER_SAMPLE_RATE = 16_000;\n private static RECORDER_CHUNK_SIZE = 512;\n private _currentAudioTrack: MediaStreamTrack | null = null;\n private _audioQueue: ArrayBuffer[] = [];\n private declare _mediaStreamRecorder: MediaStreamRecorder;\n\n constructor({\n dailyFactoryOptions = {},\n bufferLocalAudioUntilBotReady = false,\n }: DailyTransportConstructorOptions = {}) {\n super();\n this._callbacks = {} as RTVIEventCallbacks;\n\n this._dailyFactoryOptions = dailyFactoryOptions;\n this._bufferLocalAudioUntilBotReady = bufferLocalAudioUntilBotReady;\n\n this._daily = Daily.createCallObject({\n ...this._dailyFactoryOptions,\n allowMultipleCallInstances: true,\n });\n this._dailyWrapper = new DailyCallWrapper(this._daily);\n }\n\n private setupRecorder(): void {\n this._mediaStreamRecorder = new MediaStreamRecorder({\n sampleRate: DailyTransport.RECORDER_SAMPLE_RATE,\n });\n }\n\n handleUserAudioStream(data: ArrayBuffer): void {\n this._audioQueue.push(data);\n }\n\n private flushAudioQueue(): void {\n const batchSize = 10; // Number of buffers to send in one message\n if (this._audioQueue.length === 0) {\n return;\n }\n\n logger.debug(`Will flush audio queue: ${this._audioQueue.length}`);\n\n while (this._audioQueue.length > 0) {\n const batch: ArrayBuffer[] = [];\n\n // Collect up to `batchSize` items\n while (batch.length < batchSize && this._audioQueue.length > 0) {\n const queuedData = this._audioQueue.shift();\n if (queuedData) batch.push(queuedData);\n }\n\n if (batch.length > 0) {\n this._sendAudioBatch(batch);\n }\n }\n }\n\n _sendAudioBatch(dataBatch: ArrayBuffer[]): void {\n const encodedBatch = dataBatch.map((data) => {\n const pcmByteArray = new Uint8Array(data);\n return btoa(String.fromCharCode(...pcmByteArray));\n });\n\n const rtviMessage: RTVIMessage = {\n id: \"raw-audio-batch\",\n label: \"rtvi-ai\",\n type: \"raw-audio-batch\",\n data: {\n base64AudioBatch: encodedBatch, // Sending an array of base64 strings\n sampleRate: DailyTransport.RECORDER_SAMPLE_RATE,\n numChannels: 1,\n },\n };\n\n this.sendMessage(rtviMessage);\n }\n\n public initialize(\n options: RTVIClientOptions,\n messageHandler: (ev: RTVIMessage) => void\n ): void {\n if (this._bufferLocalAudioUntilBotReady) {\n this.setupRecorder();\n }\n\n this._callbacks = options.callbacks ?? {};\n this._onMessage = messageHandler;\n\n if (\n this._dailyFactoryOptions.startVideoOff == null ||\n options.enableCam != null\n ) {\n // Default is cam off\n this._dailyFactoryOptions.startVideoOff = !(options.enableCam ?? false);\n }\n if (\n this._dailyFactoryOptions.startAudioOff == null ||\n options.enableMic != null\n ) {\n // Default is mic on\n this._dailyFactoryOptions.startAudioOff = !(options.enableMic ?? true);\n }\n\n this.attachEventListeners();\n\n this.state = \"disconnected\";\n\n logger.debug(\"[RTVI Transport] Initialized\");\n }\n\n get dailyCallClient(): DailyCall {\n return this._dailyWrapper.proxy;\n }\n\n get state(): TransportState {\n return this._state;\n }\n\n private set state(state: TransportState) {\n if (this._state === state) return;\n\n this._state = state;\n this._callbacks.onTransportStateChanged?.(state);\n }\n\n async getAllCams() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"videoinput\");\n }\n\n updateCam(camId: string) {\n this._daily\n .setInputDevicesAsync({\n videoDeviceId: camId,\n })\n .then((infos) => {\n this._selectedCam = infos.camera;\n });\n }\n\n get selectedCam() {\n return this._selectedCam;\n }\n\n async getAllMics() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"audioinput\");\n }\n\n updateMic(micId: string) {\n this._daily\n .setInputDevicesAsync({\n audioDeviceId: micId,\n })\n .then((infos) => {\n this._selectedMic = infos.mic;\n });\n }\n\n get selectedMic() {\n return this._selectedMic;\n }\n\n async getAllSpeakers() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"audiooutput\");\n }\n\n updateSpeaker(speakerId: string) {\n this._daily\n .setOutputDeviceAsync({ outputDeviceId: speakerId })\n .then((infos) => {\n this._selectedSpeaker = infos.speaker;\n });\n }\n\n get selectedSpeaker() {\n return this._selectedSpeaker;\n }\n\n enableMic(enable: boolean) {\n this._daily.setLocalAudio(enable);\n }\n\n get isMicEnabled() {\n return this._daily.localAudio();\n }\n\n enableCam(enable: boolean) {\n this._daily.setLocalVideo(enable);\n }\n\n get isCamEnabled() {\n return this._daily.localVideo();\n }\n\n public enableScreenShare(enable: boolean) {\n if (enable) {\n this._daily.startScreenShare();\n } else {\n this._daily.stopScreenShare();\n }\n }\n\n public get isSharingScreen(): boolean {\n return this._daily.localScreenAudio() || this._daily.localScreenVideo();\n }\n\n tracks() {\n const participants = this._daily.participants() ?? {};\n const bot = participants?.[this._botId];\n\n const tracks: Tracks = {\n local: {\n audio: participants?.local?.tracks?.audio?.persistentTrack,\n screenAudio: participants?.local?.tracks?.screenAudio?.persistentTrack,\n screenVideo: participants?.local?.tracks?.screenVideo?.persistentTrack,\n video: participants?.local?.tracks?.video?.persistentTrack,\n },\n };\n\n if (bot) {\n tracks.bot = {\n audio: bot?.tracks?.audio?.persistentTrack,\n video: bot?.tracks?.video?.persistentTrack,\n };\n }\n\n return tracks;\n }\n\n private async startRecording(): Promise<void> {\n try {\n logger.info(\"[RTVI Transport] Initializing recording\");\n await this._mediaStreamRecorder.record((data) => {\n this.handleUserAudioStream(data.mono);\n }, DailyTransport.RECORDER_CHUNK_SIZE);\n this._onMessage({\n type: DailyRTVIMessageType.AUDIO_BUFFERING_STARTED,\n data: {},\n } as RTVIMessage);\n logger.info(\"[RTVI Transport] Recording Initialized\");\n } catch (e) {\n const err = e as Error;\n if (!err.message.includes(\"Already recording\")) {\n logger.error(\"Error starting recording\", e);\n }\n }\n }\n\n async preAuth(dailyFactoryOptions: DailyFactoryOptions) {\n this._dailyFactoryOptions = dailyFactoryOptions;\n await this._daily.preAuth(dailyFactoryOptions);\n }\n\n async initDevices() {\n if (!this._daily) {\n throw new RTVIError(\"Transport instance not initialized\");\n }\n\n this.state = \"initializing\";\n\n const infos = await this._daily.startCamera();\n const { devices } = await this._daily.enumerateDevices();\n const cams = devices.filter((d) => d.kind === \"videoinput\");\n const mics = devices.filter((d) => d.kind === \"audioinput\");\n const speakers = devices.filter((d) => d.kind === \"audiooutput\");\n this._selectedCam = infos.camera;\n this._selectedMic = infos.mic;\n this._selectedSpeaker = infos.speaker;\n\n this._callbacks.onAvailableCamsUpdated?.(cams);\n this._callbacks.onAvailableMicsUpdated?.(mics);\n this._callbacks.onAvailableSpeakersUpdated?.(speakers);\n this._callbacks.onCamUpdated?.(infos.camera as MediaDeviceInfo);\n this._callbacks.onMicUpdated?.(infos.mic as MediaDeviceInfo);\n this._callbacks.onSpeakerUpdated?.(infos.speaker as MediaDeviceInfo);\n\n // Instantiate audio observers\n if (!this._daily.isLocalAudioLevelObserverRunning())\n await this._daily.startLocalAudioLevelObserver(100);\n if (!this._daily.isRemoteParticipantsAudioLevelObserverRunning())\n await this._daily.startRemoteParticipantsAudioLevelObserver(100);\n\n this.state = \"initialized\";\n }\n\n async connect(\n authBundle: DailyTransportAuthBundle,\n abortController: AbortController\n ) {\n if (!this._daily) {\n throw new RTVIError(\"Transport instance not initialized\");\n }\n\n if (abortController.signal.aborted) return;\n\n this.state = \"connecting\";\n\n const opts = this._dailyFactoryOptions;\n opts.url = authBundle.room_url ?? opts.url;\n if (authBundle.token != null) {\n opts.token = authBundle.token;\n }\n try {\n await this._daily.join(opts);\n\n const room = await this._daily.room();\n if (room && \"id\" in room) {\n this._expiry = room.config?.exp;\n }\n } catch (e) {\n logger.error(\"Failed to join room\", e);\n this.state = \"error\";\n throw new TransportStartError();\n }\n\n if (abortController.signal.aborted) return;\n\n this.state = \"connected\";\n\n this._callbacks.onConnected?.();\n }\n\n async sendReadyMessage(): Promise<void> {\n return new Promise<void>((resolve) => {\n (async () => {\n const readyHandler = (ev: DailyEventObjectTrack) => {\n if (!ev.participant?.local) {\n this.state = \"ready\";\n this.flushAudioQueue();\n this.sendMessage(RTVIMessage.clientReady());\n this.stopRecording();\n this._daily.off(\"track-started\", readyHandler);\n resolve();\n }\n };\n this._daily.on(\"track-started\", readyHandler);\n })();\n });\n }\n\n private stopRecording() {\n if (\n this._mediaStreamRecorder &&\n this._mediaStreamRecorder.getStatus() !== \"ended\"\n ) {\n // disconnecting, we don't need to record anymore\n void this._mediaStreamRecorder.end();\n this._onMessage({\n type: DailyRTVIMessageType.AUDIO_BUFFERING_STOPPED,\n data: {},\n } as RTVIMessage);\n }\n }\n\n private attachEventListeners() {\n this._daily.on(\n \"available-devices-updated\",\n this.handleAvailableDevicesUpdated.bind(this)\n );\n this._daily.on(\n \"selected-devices-updated\",\n this.handleSelectedDevicesUpdated.bind(this)\n );\n\n this._daily.on(\"track-started\", this.handleTrackStarted.bind(this));\n this._daily.on(\"track-stopped\", this.handleTrackStopped.bind(this));\n this._daily.on(\n \"participant-joined\",\n this.handleParticipantJoined.bind(this)\n );\n this._daily.on(\"participant-left\", this.handleParticipantLeft.bind(this));\n this._daily.on(\"local-audio-level\", this.handleLocalAudioLevel.bind(this));\n this._daily.on(\n \"remote-participants-audio-level\",\n this.handleRemoteAudioLevel.bind(this)\n );\n this._daily.on(\"app-message\", this.handleAppMessage.bind(this));\n this._daily.on(\"left-meeting\", this.handleLeftMeeting.bind(this));\n this._daily.on(\"error\", this.handleFatalError.bind(this));\n this._daily.on(\"nonfatal-error\", this.handleNonFatalError.bind(this));\n }\n\n async disconnect() {\n this.state = \"disconnecting\";\n this._daily.stopLocalAudioLevelObserver();\n this._daily.stopRemoteParticipantsAudioLevelObserver();\n\n this._audioQueue = [];\n this._currentAudioTrack = null;\n this.stopRecording();\n\n await this._daily.leave();\n }\n\n public sendMessage(message: RTVIMessage) {\n this._daily.sendAppMessage(message, \"*\");\n }\n\n private handleAppMessage(ev: DailyEventObjectAppMessage) {\n // Bubble any messages with rtvi-ai label\n if (ev.data.label === \"rtvi-ai\") {\n this._onMessage({\n id: ev.data.id,\n type: ev.data.type,\n data: ev.data.data,\n } as RTVIMessage);\n }\n }\n\n private handleAvailableDevicesUpdated(\n ev: DailyEventObjectAvailableDevicesUpdated\n ) {\n this._callbacks.onAvailableCamsUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"videoinput\")\n );\n this._callbacks.onAvailableMicsUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"audioinput\")\n );\n this._callbacks.onAvailableSpeakersUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"audiooutput\")\n );\n }\n\n private handleSelectedDevicesUpdated(\n ev: DailyEventObjectSelectedDevicesUpdated\n ) {\n if (this._selectedCam?.deviceId !== ev.devices.camera) {\n this._selectedCam = ev.devices.camera;\n this._callbacks.onCamUpdated?.(ev.devices.camera as MediaDeviceInfo);\n }\n if (this._selectedMic?.deviceId !== ev.devices.mic) {\n this._selectedMic = ev.devices.mic;\n this._callbacks.onMicUpdated?.(ev.devices.mic as MediaDeviceInfo);\n }\n if (this._selectedSpeaker?.deviceId !== ev.devices.speaker) {\n this._selectedSpeaker = ev.devices.speaker;\n this._callbacks.onSpeakerUpdated?.(ev.devices.speaker as MediaDeviceInfo);\n }\n }\n\n private async handleLocalAudioTrack(track: MediaStreamTrack) {\n if (this.state == \"ready\" || !this._bufferLocalAudioUntilBotReady) {\n return;\n }\n const status = this._mediaStreamRecorder.getStatus();\n switch (status) {\n case \"ended\":\n await this._mediaStreamRecorder.begin(track);\n await this.startRecording();\n break;\n case \"paused\":\n await this.startRecording();\n break;\n case \"recording\":\n default:\n if (this._currentAudioTrack !== track) {\n await this._mediaStreamRecorder.end();\n await this._mediaStreamRecorder.begin(track);\n await this.startRecording();\n } else {\n logger.warn(\n \"track-started event received for current track and already recording\"\n );\n }\n break;\n }\n this._currentAudioTrack = track;\n }\n\n private handleTrackStarted(ev: DailyEventObjectTrack) {\n if (ev.type === \"screenAudio\" || ev.type === \"screenVideo\") {\n this._callbacks.onScreenTrackStarted?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n } else {\n if (ev.participant?.local && ev.track.kind === \"audio\") {\n void this.handleLocalAudioTrack(ev.track);\n }\n this._callbacks.onTrackStarted?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n }\n }\n\n private handleTrackStopped(ev: DailyEventObjectTrack) {\n if (ev.type === \"screenAudio\" || ev.type === \"screenVideo\") {\n this._callbacks.onScreenTrackStopped?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n } else {\n this._callbacks.onTrackStopped?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n }\n }\n\n private handleParticipantJoined(ev: DailyEventObjectParticipant) {\n const p = dailyParticipantToParticipant(ev.participant);\n\n this._callbacks.onParticipantJoined?.(p);\n\n if (p.local) return;\n\n this._botId = ev.participant.session_id;\n\n this._callbacks.onBotConnected?.(p);\n }\n\n private handleParticipantLeft(ev: DailyEventObjectParticipantLeft) {\n const p = dailyParticipantToParticipant(ev.participant);\n\n this._callbacks.onParticipantLeft?.(p);\n\n if (p.local) return;\n\n this._botId = \"\";\n\n this._callbacks.onBotDisconnected?.(p);\n }\n\n private handleLocalAudioLevel(ev: DailyEventObjectLocalAudioLevel) {\n this._callbacks.onLocalAudioLevel?.(ev.audioLevel);\n }\n\n private handleRemoteAudioLevel(\n ev: DailyEventObjectRemoteParticipantsAudioLevel\n ) {\n const participants = this._daily.participants();\n const ids = Object.keys(ev.participantsAudioLevel);\n for (let i = 0; i < ids.length; i++) {\n const id = ids[i];\n const level = ev.participantsAudioLevel[id];\n this._callbacks.onRemoteAudioLevel?.(\n level,\n dailyParticipantToParticipant(participants[id])\n );\n }\n }\n\n private handleLeftMeeting() {\n this.state = \"disconnected\";\n this._botId = \"\";\n this._callbacks.onDisconnected?.();\n }\n\n private handleFatalError(ev: DailyEventObjectFatalError) {\n logger.error(\"Daily fatal error\", ev.errorMsg);\n this.state = \"error\";\n this._botId = \"\";\n this._callbacks.onError?.(RTVIMessage.error(ev.errorMsg, true));\n }\n\n private handleNonFatalError(ev: DailyEventObjectNonFatalError) {\n switch (ev.type) {\n case \"screen-share-error\":\n this._callbacks.onScreenShareError?.(ev.errorMsg);\n break;\n }\n }\n}\n\nconst dailyParticipantToParticipant = (p: DailyParticipant): Participant => ({\n id: p.user_id,\n local: p.local,\n name: p.user_name,\n});\n","import { WavPacker } from './lib/wav_packer.js';\nimport { AudioAnalysis } from './lib/analysis/audio_analysis.js';\nimport { WavStreamPlayer } from './lib/wav_stream_player.js';\nimport { WavRecorder } from './lib/wav_recorder.js';\nimport { MediaStreamRecorder } from './lib/mediastream_recorder.js';\n\nexport {\n AudioAnalysis,\n MediaStreamRecorder,\n WavPacker,\n WavStreamPlayer,\n WavRecorder,\n};\n","/**\n * Raw wav audio file contents\n * @typedef {Object} WavPackerAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {number} channelCount\n * @property {number} sampleRate\n * @property {number} duration\n */\n\n/**\n * Utility class for assembling PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavPacker {\n /**\n * Converts Float32Array of amplitude data to ArrayBuffer in Int16Array format\n * @param {Float32Array} float32Array\n * @returns {ArrayBuffer}\n */\n static floatTo16BitPCM(float32Array) {\n const buffer = new ArrayBuffer(float32Array.length * 2);\n const view = new DataView(buffer);\n let offset = 0;\n for (let i = 0; i < float32Array.length; i++, offset += 2) {\n let s = Math.max(-1, Math.min(1, float32Array[i]));\n view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n }\n return buffer;\n }\n\n /**\n * Concatenates two ArrayBuffers\n * @param {ArrayBuffer} leftBuffer\n * @param {ArrayBuffer} rightBuffer\n * @returns {ArrayBuffer}\n */\n static mergeBuffers(leftBuffer, rightBuffer) {\n const tmpArray = new Uint8Array(\n leftBuffer.byteLength + rightBuffer.byteLength\n );\n tmpArray.set(new Uint8Array(leftBuffer), 0);\n tmpArray.set(new Uint8Array(rightBuffer), leftBuffer.byteLength);\n return tmpArray.buffer;\n }\n\n /**\n * Packs data into an Int16 format\n * @private\n * @param {number} size 0 = 1x Int16, 1 = 2x Int16\n * @param {number} arg value to pack\n * @returns\n */\n _packData(size, arg) {\n return [\n new Uint8Array([arg, arg >> 8]),\n new Uint8Array([arg, arg >> 8, arg >> 16, arg >> 24]),\n ][size];\n }\n\n /**\n * Packs audio into \"audio/wav\" Blob\n * @param {number} sampleRate\n * @param {{bitsPerSample: number, channels: Array<Float32Array>, data: Int16Array}} audio\n * @returns {WavPackerAudioType}\n */\n pack(sampleRate, audio) {\n if (!audio?.bitsPerSample) {\n throw new Error(`Missing \"bitsPerSample\"`);\n } else if (!audio?.channels) {\n throw new Error(`Missing \"channels\"`);\n } else if (!audio?.data) {\n throw new Error(`Missing \"data\"`);\n }\n const { bitsPerSample, channels, data } = audio;\n const output = [\n // Header\n 'RIFF',\n this._packData(\n 1,\n 4 + (8 + 24) /* chunk 1 length */ + (8 + 8) /* chunk 2 length */\n ), // Length\n 'WAVE',\n // chunk 1\n 'fmt ', // Sub-chunk identifier\n this._packData(1, 16), // Chunk length\n this._packData(0, 1), // Audio format (1 is linear quantization)\n this._packData(0, channels.length),\n this._packData(1, sampleRate),\n this._packData(1, (sampleRate * channels.length * bitsPerSample) / 8), // Byte rate\n this._packData(0, (channels.length * bitsPerSample) / 8),\n this._packData(0, bitsPerSample),\n // chunk 2\n 'data', // Sub-chunk identifier\n this._packData(\n 1,\n (channels[0].length * channels.length * bitsPerSample) / 8\n ), // Chunk length\n data,\n ];\n const blob = new Blob(output, { type: 'audio/mpeg' });\n const url = URL.createObjectURL(blob);\n return {\n blob,\n url,\n channelCount: channels.length,\n sampleRate,\n duration: data.byteLength / (channels.length * sampleRate * 2),\n };\n }\n}\n\nglobalThis.WavPacker = WavPacker;\n","import {\n noteFrequencies,\n noteFrequencyLabels,\n voiceFrequencies,\n voiceFrequencyLabels,\n} from './constants.js';\n\n/**\n * Output of AudioAnalysis for the frequency domain of the audio\n * @typedef {Object} AudioAnalysisOutputType\n * @property {Float32Array} values Amplitude of this frequency between {0, 1} inclusive\n * @property {number[]} frequencies Raw frequency bucket values\n * @property {string[]} labels Labels for the frequency bucket values\n */\n\n/**\n * Analyzes audio for visual output\n * @class\n */\nexport class AudioAnalysis {\n /**\n * Retrieves frequency domain data from an AnalyserNode adjusted to a decibel range\n * returns human-readable formatting and labels\n * @param {AnalyserNode} analyser\n * @param {number} sampleRate\n * @param {Float32Array} [fftResult]\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {AudioAnalysisOutputType}\n */\n static getFrequencies(\n analyser,\n sampleRate,\n fftResult,\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30,\n ) {\n if (!fftResult) {\n fftResult = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(fftResult);\n }\n const nyquistFrequency = sampleRate / 2;\n const frequencyStep = (1 / fftResult.length) * nyquistFrequency;\n let outputValues;\n let frequencies;\n let labels;\n if (analysisType === 'music' || analysisType === 'voice') {\n const useFrequencies =\n analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n const aggregateOutput = Array(useFrequencies.length).fill(minDecibels);\n for (let i = 0; i < fftResult.length; i++) {\n const frequency = i * frequencyStep;\n const amplitude = fftResult[i];\n for (let n = useFrequencies.length - 1; n >= 0; n--) {\n if (frequency > useFrequencies[n]) {\n aggregateOutput[n] = Math.max(aggregateOutput[n], amplitude);\n break;\n }\n }\n }\n outputValues = aggregateOutput;\n frequencies =\n analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n labels =\n analysisType === 'voice' ? voiceFrequencyLabels : noteFrequencyLabels;\n } else {\n outputValues = Array.from(fftResult);\n frequencies = outputValues.map((_, i) => frequencyStep * i);\n labels = frequencies.map((f) => `${f.toFixed(2)} Hz`);\n }\n // We normalize to {0, 1}\n const normalizedOutput = outputValues.map((v) => {\n return Math.max(\n 0,\n Math.min((v - minDecibels) / (maxDecibels - minDecibels), 1),\n );\n });\n const values = new Float32Array(normalizedOutput);\n return {\n values,\n frequencies,\n labels,\n };\n }\n\n /**\n * Creates a new AudioAnalysis instance for an HTMLAudioElement\n * @param {HTMLAudioElement} audioElement\n * @param {AudioBuffer|null} [audioBuffer] If provided, will cache all frequency domain data from the buffer\n * @returns {AudioAnalysis}\n */\n constructor(audioElement, audioBuffer = null) {\n this.fftResults = [];\n if (audioBuffer) {\n /**\n * Modified from\n * https://stackoverflow.com/questions/75063715/using-the-web-audio-api-to-analyze-a-song-without-playing\n *\n * We do this to populate FFT values for the audio if provided an `audioBuffer`\n * The reason to do this is that Safari fails when using `createMediaElementSource`\n * This has a non-zero RAM cost so we only opt-in to run it on Safari, Chrome is better\n */\n const { length, sampleRate } = audioBuffer;\n const offlineAudioContext = new OfflineAudioContext({\n length,\n sampleRate,\n });\n const source = offlineAudioContext.createBufferSource();\n source.buffer = audioBuffer;\n const analyser = offlineAudioContext.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n source.connect(analyser);\n // limit is :: 128 / sampleRate;\n // but we just want 60fps - cuts ~1s from 6MB to 1MB of RAM\n const renderQuantumInSeconds = 1 / 60;\n const durationInSeconds = length / sampleRate;\n const analyze = (index) => {\n const suspendTime = renderQuantumInSeconds * index;\n if (suspendTime < durationInSeconds) {\n offlineAudioContext.suspend(suspendTime).then(() => {\n const fftResult = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(fftResult);\n this.fftResults.push(fftResult);\n analyze(index + 1);\n });\n }\n if (index === 1) {\n offlineAudioContext.startRendering();\n } else {\n offlineAudioContext.resume();\n }\n };\n source.start(0);\n analyze(1);\n this.audio = audioElement;\n this.context = offlineAudioContext;\n this.analyser = analyser;\n this.sampleRate = sampleRate;\n this.audioBuffer = audioBuffer;\n } else {\n const audioContext = new AudioContext();\n const track = audioContext.createMediaElementSource(audioElement);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n track.connect(analyser);\n analyser.connect(audioContext.destination);\n this.audio = audioElement;\n this.context = audioContext;\n this.analyser = analyser;\n this.sampleRate = this.context.sampleRate;\n this.audioBuffer = null;\n }\n }\n\n /**\n * Gets the current frequency domain data from the playing audio track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30,\n ) {\n let fftResult = null;\n if (this.audioBuffer && this.fftResults.length) {\n const pct = this.audio.currentTime / this.audio.duration;\n const index = Math.min(\n (pct * this.fftResults.length) | 0,\n this.fftResults.length - 1,\n );\n fftResult = this.fftResults[index];\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n fftResult,\n analysisType,\n minDecibels,\n maxDecibels,\n );\n }\n\n /**\n * Resume the internal AudioContext if it was suspended due to the lack of\n * user interaction when the AudioAnalysis was instantiated.\n * @returns {Promise<true>}\n */\n async resumeIfSuspended() {\n if (this.context.state === 'suspended') {\n await this.context.resume();\n }\n return true;\n }\n}\n\nglobalThis.AudioAnalysis = AudioAnalysis;\n","/**\n * Constants for help with visualization\n * Helps map frequency ranges from Fast Fourier Transform\n * to human-interpretable ranges, notably music ranges and\n * human vocal ranges.\n */\n\n// Eighth octave frequencies\nconst octave8Frequencies = [\n 4186.01, 4434.92, 4698.63, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93,\n 6644.88, 7040.0, 7458.62, 7902.13,\n];\n\n// Labels for each of the above frequencies\nconst octave8FrequencyLabels = [\n 'C',\n 'C#',\n 'D',\n 'D#',\n 'E',\n 'F',\n 'F#',\n 'G',\n 'G#',\n 'A',\n 'A#',\n 'B',\n];\n\n/**\n * All note frequencies from 1st to 8th octave\n * in format \"A#8\" (A#, 8th octave)\n */\nexport const noteFrequencies = [];\nexport const noteFrequencyLabels = [];\nfor (let i = 1; i <= 8; i++) {\n for (let f = 0; f < octave8Frequencies.length; f++) {\n const freq = octave8Frequencies[f];\n noteFrequencies.push(freq / Math.pow(2, 8 - i));\n noteFrequencyLabels.push(octave8FrequencyLabels[f] + i);\n }\n}\n\n/**\n * Subset of the note frequencies between 32 and 2000 Hz\n * 6 octave range: C1 to B6\n */\nconst voiceFrequencyRange = [32.0, 2000.0];\nexport const voiceFrequencies = noteFrequencies.filter((_, i) => {\n return (\n noteFrequencies[i] > voiceFrequencyRange[0] &&\n noteFrequencies[i] < voiceFrequencyRange[1]\n );\n});\nexport const voiceFrequencyLabels = noteFrequencyLabels.filter((_, i) => {\n return (\n noteFrequencies[i] > voiceFrequencyRange[0] &&\n noteFrequencies[i] < voiceFrequencyRange[1]\n );\n});\n","import { StreamProcessorSrc } from \"./worklets/stream_processor.js\";\nimport { AudioAnalysis } from \"./analysis/audio_analysis.js\";\n\n/**\n * Plays audio streams received in raw PCM16 chunks from the browser\n * @class\n */\nexport class WavStreamPlayer {\n /**\n * Creates a new WavStreamPlayer instance\n * @param {{sampleRate?: number}} options\n * @returns {WavStreamPlayer}\n */\n constructor({ sampleRate = 44100 } = {}) {\n this.scriptSrc = StreamProcessorSrc;\n this.sampleRate = sampleRate;\n this.context = null;\n this.stream = null;\n this.analyser = null;\n this.trackSampleOffsets = {};\n this.interruptedTrackIds = {};\n }\n\n /**\n * Connects the audio context and enables output to speakers\n * @returns {Promise<true>}\n */\n async connect() {\n this.context = new AudioContext({ sampleRate: this.sampleRate });\n if (this._speakerID) {\n this.context.setSinkId(this._speakerID);\n }\n if (this.context.state === \"suspended\") {\n await this.context.resume();\n }\n try {\n await this.context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const analyser = this.context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n this.analyser = analyser;\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the playing track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = \"frequency\",\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.analyser) {\n throw new Error(\"Not connected, please call .connect() first\");\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * @param {string} speaker deviceId\n */\n async updateSpeaker(speaker) {\n const _prevSpeaker = this._speakerID;\n this._speakerID = speaker;\n if (this.context) {\n try {\n if (speaker === \"default\") {\n await this.context.setSinkId();\n } else {\n await this.context.setSinkId(speaker);\n }\n } catch (e) {\n console.error(`Could not set sinkId to ${speaker}: ${e}`);\n this._speakerID = _prevSpeaker;\n }\n }\n }\n\n /**\n * Starts audio streaming\n * @private\n * @returns {Promise<true>}\n */\n _start() {\n const streamNode = new AudioWorkletNode(this.context, \"stream_processor\");\n streamNode.connect(this.context.destination);\n streamNode.port.onmessage = (e) => {\n const { event } = e.data;\n if (event === \"stop\") {\n streamNode.disconnect();\n this.stream = null;\n } else if (event === \"offset\") {\n const { requestId, trackId, offset } = e.data;\n const currentTime = offset / this.sampleRate;\n this.trackSampleOffsets[requestId] = { trackId, offset, currentTime };\n }\n };\n this.analyser.disconnect();\n streamNode.connect(this.analyser);\n this.stream = streamNode;\n return true;\n }\n\n /**\n * Adds 16BitPCM data to the currently playing audio stream\n * You can add chunks beyond the current play point and they will be queued for play\n * @param {ArrayBuffer|Int16Array} arrayBuffer\n * @param {string} [trackId]\n * @returns {Int16Array}\n */\n add16BitPCM(arrayBuffer, trackId = \"default\") {\n if (typeof trackId !== \"string\") {\n throw new Error(`trackId must be a string`);\n } else if (this.interruptedTrackIds[trackId]) {\n return;\n }\n if (!this.stream) {\n this._start();\n }\n let buffer;\n if (arrayBuffer instanceof Int16Array) {\n buffer = arrayBuffer;\n } else if (arrayBuffer instanceof ArrayBuffer) {\n buffer = new Int16Array(arrayBuffer);\n } else {\n throw new Error(`argument must be Int16Array or ArrayBuffer`);\n }\n this.stream.port.postMessage({ event: \"write\", buffer, trackId });\n return buffer;\n }\n\n /**\n * Gets the offset (sample count) of the currently playing stream\n * @param {boolean} [interrupt]\n * @returns {{trackId: string|null, offset: number, currentTime: number}}\n */\n async getTrackSampleOffset(interrupt = false) {\n if (!this.stream) {\n return null;\n }\n const requestId = crypto.randomUUID();\n this.stream.port.postMessage({\n event: interrupt ? \"interrupt\" : \"offset\",\n requestId,\n });\n let trackSampleOffset;\n while (!trackSampleOffset) {\n trackSampleOffset = this.trackSampleOffsets[requestId];\n await new Promise((r) => setTimeout(() => r(), 1));\n }\n const { trackId } = trackSampleOffset;\n if (interrupt && trackId) {\n this.interruptedTrackIds[trackId] = true;\n }\n return trackSampleOffset;\n }\n\n /**\n * Strips the current stream and returns the sample offset of the audio\n * @param {boolean} [interrupt]\n * @returns {{trackId: string|null, offset: number, currentTime: number}}\n */\n async interrupt() {\n return this.getTrackSampleOffset(true);\n }\n}\n\nglobalThis.WavStreamPlayer = WavStreamPlayer;\n","export const StreamProcessorWorklet = `\nclass StreamProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.hasStarted = false;\n this.hasInterrupted = false;\n this.outputBuffers = [];\n this.bufferLength = 128;\n this.write = { buffer: new Float32Array(this.bufferLength), trackId: null };\n this.writeOffset = 0;\n this.trackSampleOffsets = {};\n this.port.onmessage = (event) => {\n if (event.data) {\n const payload = event.data;\n if (payload.event === 'write') {\n const int16Array = payload.buffer;\n const float32Array = new Float32Array(int16Array.length);\n for (let i = 0; i < int16Array.length; i++) {\n float32Array[i] = int16Array[i] / 0x8000; // Convert Int16 to Float32\n }\n this.writeData(float32Array, payload.trackId);\n } else if (\n payload.event === 'offset' ||\n payload.event === 'interrupt'\n ) {\n const requestId = payload.requestId;\n const trackId = this.write.trackId;\n const offset = this.trackSampleOffsets[trackId] || 0;\n this.port.postMessage({\n event: 'offset',\n requestId,\n trackId,\n offset,\n });\n if (payload.event === 'interrupt') {\n this.hasInterrupted = true;\n }\n } else {\n throw new Error(\\`Unhandled event \"\\${payload.event}\"\\`);\n }\n }\n };\n }\n\n writeData(float32Array, trackId = null) {\n let { buffer } = this.write;\n let offset = this.writeOffset;\n for (let i = 0; i < float32Array.length; i++) {\n buffer[offset++] = float32Array[i];\n if (offset >= buffer.length) {\n this.outputBuffers.push(this.write);\n this.write = { buffer: new Float32Array(this.bufferLength), trackId };\n buffer = this.write.buffer;\n offset = 0;\n }\n }\n this.writeOffset = offset;\n return true;\n }\n\n process(inputs, outputs, parameters) {\n const output = outputs[0];\n const outputChannelData = output[0];\n const outputBuffers = this.outputBuffers;\n if (this.hasInterrupted) {\n this.port.postMessage({ event: 'stop' });\n return false;\n } else if (outputBuffers.length) {\n this.hasStarted = true;\n const { buffer, trackId } = outputBuffers.shift();\n for (let i = 0; i < outputChannelData.length; i++) {\n outputChannelData[i] = buffer[i] || 0;\n }\n if (trackId) {\n this.trackSampleOffsets[trackId] =\n this.trackSampleOffsets[trackId] || 0;\n this.trackSampleOffsets[trackId] += buffer.length;\n }\n return true;\n } else if (this.hasStarted) {\n this.port.postMessage({ event: 'stop' });\n return false;\n } else {\n return true;\n }\n }\n}\n\nregisterProcessor('stream_processor', StreamProcessor);\n`;\n\nconst script = new Blob([StreamProcessorWorklet], {\n type: 'application/javascript',\n});\nconst src = URL.createObjectURL(script);\nexport const StreamProcessorSrc = src;\n","import { AudioProcessorSrc } from './worklets/audio_processor.js';\nimport { AudioAnalysis } from './analysis/audio_analysis.js';\nimport { WavPacker } from './wav_packer.js';\n\n/**\n * Decodes audio into a wav file\n * @typedef {Object} DecodedAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {Float32Array} values\n * @property {AudioBuffer} audioBuffer\n */\n\n/**\n * Records live stream of user audio as PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavRecorder {\n /**\n * Create a new WavRecorder instance\n * @param {{sampleRate?: number, outputToSpeakers?: boolean, debug?: boolean}} [options]\n * @returns {WavRecorder}\n */\n constructor({\n sampleRate = 44100,\n outputToSpeakers = false,\n debug = false,\n } = {}) {\n // Script source\n this.scriptSrc = AudioProcessorSrc;\n // Config\n this.sampleRate = sampleRate;\n this.outputToSpeakers = outputToSpeakers;\n this.debug = !!debug;\n this._deviceChangeCallback = null;\n this._devices = [];\n this.deviceSelection = null;\n // State variables\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n this.recording = false;\n // Event handling with AudioWorklet\n this._lastEventId = 0;\n this.eventReceipts = {};\n this.eventTimeout = 5000;\n // Process chunks of audio\n this._chunkProcessor = () => {};\n this._chunkProcessorSize = void 0;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n\n /**\n * Decodes audio data from multiple formats to a Blob, url, Float32Array and AudioBuffer\n * @param {Blob|Float32Array|Int16Array|ArrayBuffer|number[]} audioData\n * @param {number} sampleRate\n * @param {number} fromSampleRate\n * @returns {Promise<DecodedAudioType>}\n */\n static async decode(audioData, sampleRate = 44100, fromSampleRate = -1) {\n const context = new AudioContext({ sampleRate });\n let arrayBuffer;\n let blob;\n if (audioData instanceof Blob) {\n if (fromSampleRate !== -1) {\n throw new Error(\n `Can not specify \"fromSampleRate\" when reading from Blob`\n );\n }\n blob = audioData;\n arrayBuffer = await blob.arrayBuffer();\n } else if (audioData instanceof ArrayBuffer) {\n if (fromSampleRate !== -1) {\n throw new Error(\n `Can not specify \"fromSampleRate\" when reading from ArrayBuffer`\n );\n }\n arrayBuffer = audioData;\n blob = new Blob([arrayBuffer], { type: 'audio/wav' });\n } else {\n let float32Array;\n let data;\n if (audioData instanceof Int16Array) {\n data = audioData;\n float32Array = new Float32Array(audioData.length);\n for (let i = 0; i < audioData.length; i++) {\n float32Array[i] = audioData[i] / 0x8000;\n }\n } else if (audioData instanceof Float32Array) {\n float32Array = audioData;\n } else if (audioData instanceof Array) {\n float32Array = new Float32Array(audioData);\n } else {\n throw new Error(\n `\"audioData\" must be one of: Blob, Float32Arrray, Int16Array, ArrayBuffer, Array<number>`\n );\n }\n if (fromSampleRate === -1) {\n throw new Error(\n `Must specify \"fromSampleRate\" when reading from Float32Array, In16Array or Array`\n );\n } else if (fromSampleRate < 3000) {\n throw new Error(`Minimum \"fromSampleRate\" is 3000 (3kHz)`);\n }\n if (!data) {\n data = WavPacker.floatTo16BitPCM(float32Array);\n }\n const audio = {\n bitsPerSample: 16,\n channels: [float32Array],\n data,\n };\n const packer = new WavPacker();\n const result = packer.pack(fromSampleRate, audio);\n blob = result.blob;\n arrayBuffer = await blob.arrayBuffer();\n }\n const audioBuffer = await context.decodeAudioData(arrayBuffer);\n const values = audioBuffer.getChannelData(0);\n const url = URL.createObjectURL(blob);\n return {\n blob,\n url,\n values,\n audioBuffer,\n };\n }\n\n /**\n * Logs data in debug mode\n * @param {...any} arguments\n * @returns {true}\n */\n log() {\n if (this.debug) {\n this.log(...arguments);\n }\n return true;\n }\n\n /**\n * Retrieves the current sampleRate for the recorder\n * @returns {number}\n */\n getSampleRate() {\n return this.sampleRate;\n }\n\n /**\n * Retrieves the current status of the recording\n * @returns {\"ended\"|\"paused\"|\"recording\"}\n */\n getStatus() {\n if (!this.processor) {\n return 'ended';\n } else if (!this.recording) {\n return 'paused';\n } else {\n return 'recording';\n }\n }\n\n /**\n * Sends an event to the AudioWorklet\n * @private\n * @param {string} name\n * @param {{[key: string]: any}} data\n * @param {AudioWorkletNode} [_processor]\n * @returns {Promise<{[key: string]: any}>}\n */\n async _event(name, data = {}, _processor = null) {\n _processor = _processor || this.processor;\n if (!_processor) {\n throw new Error('Can not send events without recording first');\n }\n const message = {\n event: name,\n id: this._lastEventId++,\n data,\n };\n _processor.port.postMessage(message);\n const t0 = new Date().valueOf();\n while (!this.eventReceipts[message.id]) {\n if (new Date().valueOf() - t0 > this.eventTimeout) {\n throw new Error(`Timeout waiting for \"${name}\" event`);\n }\n await new Promise((res) => setTimeout(() => res(true), 1));\n }\n const payload = this.eventReceipts[message.id];\n delete this.eventReceipts[message.id];\n return payload;\n }\n\n /**\n * Sets device change callback, remove if callback provided is `null`\n * @param {(Array<MediaDeviceInfo & {default: boolean}>): void|null} callback\n * @returns {true}\n */\n listenForDeviceChange(callback) {\n if (callback === null && this._deviceChangeCallback) {\n navigator.mediaDevices.removeEventListener(\n 'devicechange',\n this._deviceChangeCallback\n );\n this._deviceChangeCallback = null;\n } else if (callback !== null) {\n // Basically a debounce; we only want this called once when devices change\n // And we only want the most recent callback() to be executed\n // if a few are operating at the same time\n let lastId = 0;\n let lastDevices = [];\n const serializeDevices = (devices) =>\n devices\n .map((d) => d.deviceId)\n .sort()\n .join(',');\n const cb = async () => {\n let id = ++lastId;\n const devices = await this.listDevices();\n if (id === lastId) {\n if (serializeDevices(lastDevices) !== serializeDevices(devices)) {\n lastDevices = devices;\n callback(devices.slice());\n }\n }\n };\n navigator.mediaDevices.addEventListener('devicechange', cb);\n cb();\n this._deviceChangeCallback = cb;\n }\n return true;\n }\n\n /**\n * Manually request permission to use the microphone\n * @returns {Promise<true>}\n */\n async requestPermission() {\n const permissionStatus = await navigator.permissions.query({\n name: 'microphone',\n });\n if (permissionStatus.state === 'denied') {\n window.alert('You must grant microphone access to use this feature.');\n } else if (permissionStatus.state === 'prompt') {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n const tracks = stream.getTracks();\n tracks.forEach((track) => track.stop());\n } catch (e) {\n window.alert('You must grant microphone access to use this feature.');\n }\n }\n return true;\n }\n\n /**\n * List all eligible devices for recording, will request permission to use microphone\n * @returns {Promise<Array<MediaDeviceInfo & {default: boolean}>>}\n */\n async listDevices() {\n if (\n !navigator.mediaDevices ||\n !('enumerateDevices' in navigator.mediaDevices)\n ) {\n throw new Error('Could not request user devices');\n }\n await this.requestPermission();\n const devices = await navigator.mediaDevices.enumerateDevices();\n const audioDevices = devices.filter(\n (device) => device.kind === 'audioinput'\n );\n return audioDevices;\n // const defaultDeviceIndex = audioDevices.findIndex(\n // (device) => device.deviceId === 'default'\n // );\n // const deviceList = [];\n // if (defaultDeviceIndex !== -1) {\n // let defaultDevice = audioDevices.splice(defaultDeviceIndex, 1)[0];\n // let existingIndex = audioDevices.findIndex(\n // (device) => device.groupId === defaultDevice.groupId\n // );\n // if (existingIndex !== -1) {\n // defaultDevice = audioDevices.splice(existingIndex, 1)[0];\n // }\n // defaultDevice.default = true;\n // deviceList.push(defaultDevice);\n // }\n // return deviceList.concat(audioDevices);\n }\n\n /**\n * Begins a recording session and requests microphone permissions if not already granted\n * Microphone recording indicator will appear on browser tab but status will be \"paused\"\n * @param {string} [deviceId] if no device provided, default device will be used\n * @returns {Promise<true>}\n */\n async begin(deviceId) {\n if (this.processor) {\n throw new Error(\n `Already connected: please call .end() to start a new session`\n );\n }\n\n if (\n !navigator.mediaDevices ||\n !('getUserMedia' in navigator.mediaDevices)\n ) {\n throw new Error('Could not request user media');\n }\n deviceId = deviceId ?? this.deviceSelection?.deviceId;\n try {\n const config = { audio: true };\n if (deviceId) {\n config.audio = { deviceId: { exact: deviceId } };\n }\n this.stream = await navigator.mediaDevices.getUserMedia(config);\n } catch (err) {\n throw new Error('Could not start media stream');\n }\n\n this.listDevices().then((devices) => {\n deviceId = this.stream.getAudioTracks()[0].getSettings().deviceId;\n console.log(\n 'find current device',\n devices,\n deviceId,\n this.stream.getAudioTracks()[0].getSettings()\n );\n this.deviceSelection = devices.find((d) => d.deviceId === deviceId);\n console.log('current device', this.deviceSelection);\n });\n const context = new AudioContext({ sampleRate: this.sampleRate });\n const source = context.createMediaStreamSource(this.stream);\n // Load and execute the module script.\n try {\n await context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const processor = new AudioWorkletNode(context, 'audio_processor');\n processor.port.onmessage = (e) => {\n const { event, id, data } = e.data;\n if (event === 'receipt') {\n this.eventReceipts[id] = data;\n } else if (event === 'chunk') {\n if (this._chunkProcessorSize) {\n const buffer = this._chunkProcessorBuffer;\n this._chunkProcessorBuffer = {\n raw: WavPacker.mergeBuffers(buffer.raw, data.raw),\n mono: WavPacker.mergeBuffers(buffer.mono, data.mono),\n };\n if (\n this._chunkProcessorBuffer.mono.byteLength >=\n this._chunkProcessorSize\n ) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n } else {\n this._chunkProcessor(data);\n }\n }\n };\n\n const node = source.connect(processor);\n const analyser = context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n node.connect(analyser);\n if (this.outputToSpeakers) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Warning: Output to speakers may affect sound quality,\\n' +\n 'especially due to system audio feedback preventative measures.\\n' +\n 'use only for debugging'\n );\n analyser.connect(context.destination);\n }\n\n this.source = source;\n this.node = node;\n this.analyser = analyser;\n this.processor = processor;\n console.log('begin completed');\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the recording track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * Pauses the recording\n * Keeps microphone stream open but halts storage of audio\n * @returns {Promise<true>}\n */\n async pause() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n } else if (!this.recording) {\n throw new Error('Already paused: please call .record() first');\n }\n if (this._chunkProcessorBuffer.raw.byteLength) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n }\n this.log('Pausing ...');\n await this._event('stop');\n this.recording = false;\n return true;\n }\n\n /**\n * Start recording stream and storing to memory from the connected audio source\n * @param {(data: { mono: Int16Array; raw: Int16Array }) => any} [chunkProcessor]\n * @param {number} [chunkSize] chunkProcessor will not be triggered until this size threshold met in mono audio\n * @returns {Promise<true>}\n */\n async record(chunkProcessor = () => {}, chunkSize = 8192) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n } else if (this.recording) {\n throw new Error('Already recording: please call .pause() first');\n } else if (typeof chunkProcessor !== 'function') {\n throw new Error(`chunkProcessor must be a function`);\n }\n this._chunkProcessor = chunkProcessor;\n this._chunkProcessorSize = chunkSize;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n this.log('Recording ...');\n await this._event('start');\n this.recording = true;\n return true;\n }\n\n /**\n * Clears the audio buffer, empties stored recording\n * @returns {Promise<true>}\n */\n async clear() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n await this._event('clear');\n return true;\n }\n\n /**\n * Reads the current audio stream data\n * @returns {Promise<{meanValues: Float32Array, channels: Array<Float32Array>}>}\n */\n async read() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n this.log('Reading ...');\n const result = await this._event('read');\n return result;\n }\n\n /**\n * Saves the current audio stream to a file\n * @param {boolean} [force] Force saving while still recording\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async save(force = false) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n if (!force && this.recording) {\n throw new Error(\n 'Currently recording: please call .pause() first, or call .save(true) to force'\n );\n }\n this.log('Exporting ...');\n const exportData = await this._event('export');\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Ends the current recording session and saves the result\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async end() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n\n const _processor = this.processor;\n\n this.log('Stopping ...');\n await this._event('stop');\n this.recording = false;\n const tracks = this.stream.getTracks();\n tracks.forEach((track) => track.stop());\n\n this.log('Exporting ...');\n const exportData = await this._event('export', {}, _processor);\n\n this.processor.disconnect();\n this.source.disconnect();\n this.node.disconnect();\n this.analyser.disconnect();\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Performs a full cleanup of WavRecorder instance\n * Stops actively listening via microphone and removes existing listeners\n * @returns {Promise<true>}\n */\n async quit() {\n this.listenForDeviceChange(null);\n // we do not reset this on end so that selections persist across starts\n this.deviceSelection = null;\n if (this.processor) {\n await this.end();\n }\n return true;\n }\n}\n\nglobalThis.WavRecorder = WavRecorder;\n","const AudioProcessorWorklet = `\nclass AudioProcessor extends AudioWorkletProcessor {\n\n constructor() {\n super();\n this.port.onmessage = this.receive.bind(this);\n this.initialize();\n }\n\n initialize() {\n this.foundAudio = false;\n this.recording = false;\n this.chunks = [];\n }\n\n /**\n * Concatenates sampled chunks into channels\n * Format is chunk[Left[], Right[]]\n */\n readChannelData(chunks, channel = -1, maxChannels = 9) {\n let channelLimit;\n if (channel !== -1) {\n if (chunks[0] && chunks[0].length - 1 < channel) {\n throw new Error(\n \\`Channel \\${channel} out of range: max \\${chunks[0].length}\\`\n );\n }\n channelLimit = channel + 1;\n } else {\n channel = 0;\n channelLimit = Math.min(chunks[0] ? chunks[0].length : 1, maxChannels);\n }\n const channels = [];\n for (let n = channel; n < channelLimit; n++) {\n const length = chunks.reduce((sum, chunk) => {\n return sum + chunk[n].length;\n }, 0);\n const buffers = chunks.map((chunk) => chunk[n]);\n const result = new Float32Array(length);\n let offset = 0;\n for (let i = 0; i < buffers.length; i++) {\n result.set(buffers[i], offset);\n offset += buffers[i].length;\n }\n channels[n] = result;\n }\n return channels;\n }\n\n /**\n * Combines parallel audio data into correct format,\n * channels[Left[], Right[]] to float32Array[LRLRLRLR...]\n */\n formatAudioData(channels) {\n if (channels.length === 1) {\n // Simple case is only one channel\n const float32Array = channels[0].slice();\n const meanValues = channels[0].slice();\n return { float32Array, meanValues };\n } else {\n const float32Array = new Float32Array(\n channels[0].length * channels.length\n );\n const meanValues = new Float32Array(channels[0].length);\n for (let i = 0; i < channels[0].length; i++) {\n const offset = i * channels.length;\n let meanValue = 0;\n for (let n = 0; n < channels.length; n++) {\n float32Array[offset + n] = channels[n][i];\n meanValue += channels[n][i];\n }\n meanValues[i] = meanValue / channels.length;\n }\n return { float32Array, meanValues };\n }\n }\n\n /**\n * Converts 32-bit float data to 16-bit integers\n */\n floatTo16BitPCM(float32Array) {\n const buffer = new ArrayBuffer(float32Array.length * 2);\n const view = new DataView(buffer);\n let offset = 0;\n for (let i = 0; i < float32Array.length; i++, offset += 2) {\n let s = Math.max(-1, Math.min(1, float32Array[i]));\n view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n }\n return buffer;\n }\n\n /**\n * Retrieves the most recent amplitude values from the audio stream\n * @param {number} channel\n */\n getValues(channel = -1) {\n const channels = this.readChannelData(this.chunks, channel);\n const { meanValues } = this.formatAudioData(channels);\n return { meanValues, channels };\n }\n\n /**\n * Exports chunks as an audio/wav file\n */\n export() {\n const channels = this.readChannelData(this.chunks);\n const { float32Array, meanValues } = this.formatAudioData(channels);\n const audioData = this.floatTo16BitPCM(float32Array);\n return {\n meanValues: meanValues,\n audio: {\n bitsPerSample: 16,\n channels: channels,\n data: audioData,\n },\n };\n }\n\n receive(e) {\n const { event, id } = e.data;\n let receiptData = {};\n switch (event) {\n case 'start':\n this.recording = true;\n break;\n case 'stop':\n this.recording = false;\n break;\n case 'clear':\n this.initialize();\n break;\n case 'export':\n receiptData = this.export();\n break;\n case 'read':\n receiptData = this.getValues();\n break;\n default:\n break;\n }\n // Always send back receipt\n this.port.postMessage({ event: 'receipt', id, data: receiptData });\n }\n\n sendChunk(chunk) {\n const channels = this.readChannelData([chunk]);\n const { float32Array, meanValues } = this.formatAudioData(channels);\n const rawAudioData = this.floatTo16BitPCM(float32Array);\n const monoAudioData = this.floatTo16BitPCM(meanValues);\n this.port.postMessage({\n event: 'chunk',\n data: {\n mono: monoAudioData,\n raw: rawAudioData,\n },\n });\n }\n\n process(inputList, outputList, parameters) {\n // Copy input to output (e.g. speakers)\n // Note that this creates choppy sounds with Mac products\n const sourceLimit = Math.min(inputList.length, outputList.length);\n for (let inputNum = 0; inputNum < sourceLimit; inputNum++) {\n const input = inputList[inputNum];\n const output = outputList[inputNum];\n const channelCount = Math.min(input.length, output.length);\n for (let channelNum = 0; channelNum < channelCount; channelNum++) {\n input[channelNum].forEach((sample, i) => {\n output[channelNum][i] = sample;\n });\n }\n }\n const inputs = inputList[0];\n // There's latency at the beginning of a stream before recording starts\n // Make sure we actually receive audio data before we start storing chunks\n let sliceIndex = 0;\n if (!this.foundAudio) {\n for (const channel of inputs) {\n sliceIndex = 0; // reset for each channel\n if (this.foundAudio) {\n break;\n }\n if (channel) {\n for (const value of channel) {\n if (value !== 0) {\n // find only one non-zero entry in any channel\n this.foundAudio = true;\n break;\n } else {\n sliceIndex++;\n }\n }\n }\n }\n }\n if (inputs && inputs[0] && this.foundAudio && this.recording) {\n // We need to copy the TypedArray, because the \\`process\\`\n // internals will reuse the same buffer to hold each input\n const chunk = inputs.map((input) => input.slice(sliceIndex));\n this.chunks.push(chunk);\n this.sendChunk(chunk);\n }\n return true;\n }\n}\n\nregisterProcessor('audio_processor', AudioProcessor);\n`;\n\nconst script = new Blob([AudioProcessorWorklet], {\n type: 'application/javascript',\n});\nconst src = URL.createObjectURL(script);\nexport const AudioProcessorSrc = src;\n","import { AudioProcessorSrc } from \"./worklets/audio_processor.js\";\nimport { AudioAnalysis } from \"./analysis/audio_analysis.js\";\nimport { WavPacker } from \"./wav_packer.js\";\n\n/**\n * Decodes audio into a wav file\n * @typedef {Object} DecodedAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {Float32Array} values\n * @property {AudioBuffer} audioBuffer\n */\n\n/**\n * Records live stream of user audio as PCM16 \"audio/wav\" data\n * @class\n */\nexport class MediaStreamRecorder {\n /**\n * Create a new MediaStreamRecorder instance\n * @param {{sampleRate?: number, outputToSpeakers?: boolean, debug?: boolean}} [options]\n * @returns {MediaStreamRecorder}\n */\n constructor({\n sampleRate = 44100,\n outputToSpeakers = false,\n debug = false,\n } = {}) {\n // Script source\n this.scriptSrc = AudioProcessorSrc;\n // Config\n this.sampleRate = sampleRate;\n this.outputToSpeakers = outputToSpeakers;\n this.debug = !!debug;\n // State variables\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n this.recording = false;\n // Event handling with AudioWorklet\n this._lastEventId = 0;\n this.eventReceipts = {};\n this.eventTimeout = 5000;\n // Process chunks of audio\n this._chunkProcessor = () => {};\n this._chunkProcessorSize = void 0;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n\n /**\n * Logs data in debug mode\n * @param {...any} arguments\n * @returns {true}\n */\n log() {\n if (this.debug) {\n this.log(...arguments);\n }\n return true;\n }\n\n /**\n * Retrieves the current sampleRate for the recorder\n * @returns {number}\n */\n getSampleRate() {\n return this.sampleRate;\n }\n\n /**\n * Retrieves the current status of the recording\n * @returns {\"ended\"|\"paused\"|\"recording\"}\n */\n getStatus() {\n if (!this.processor) {\n return \"ended\";\n } else if (!this.recording) {\n return \"paused\";\n } else {\n return \"recording\";\n }\n }\n\n /**\n * Sends an event to the AudioWorklet\n * @private\n * @param {string} name\n * @param {{[key: string]: any}} data\n * @param {AudioWorkletNode} [_processor]\n * @returns {Promise<{[key: string]: any}>}\n */\n async _event(name, data = {}, _processor = null) {\n _processor = _processor || this.processor;\n if (!_processor) {\n throw new Error(\"Can not send events without recording first\");\n }\n const message = {\n event: name,\n id: this._lastEventId++,\n data,\n };\n _processor.port.postMessage(message);\n const t0 = new Date().valueOf();\n while (!this.eventReceipts[message.id]) {\n if (new Date().valueOf() - t0 > this.eventTimeout) {\n throw new Error(`Timeout waiting for \"${name}\" event`);\n }\n await new Promise((res) => setTimeout(() => res(true), 1));\n }\n const payload = this.eventReceipts[message.id];\n delete this.eventReceipts[message.id];\n return payload;\n }\n\n /**\n * Begins a recording session for the given audioTrack\n * Microphone recording indicator will appear on browser tab but status will be \"paused\"\n * @param {MediaStreamTrack} [audioTrack] if no device provided, default device will be used\n * @returns {Promise<true>}\n */\n async begin(audioTrack) {\n if (this.processor) {\n throw new Error(\n `Already connected: please call .end() to start a new session`\n );\n }\n\n if (!audioTrack || audioTrack.kind !== \"audio\") {\n throw new Error(\"No audio track provided\");\n }\n\n this.stream = new MediaStream([audioTrack]);\n\n const context = new AudioContext({ sampleRate: this.sampleRate });\n const source = context.createMediaStreamSource(this.stream);\n // Load and execute the module script.\n try {\n await context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const processor = new AudioWorkletNode(context, \"audio_processor\");\n processor.port.onmessage = (e) => {\n const { event, id, data } = e.data;\n if (event === \"receipt\") {\n this.eventReceipts[id] = data;\n } else if (event === \"chunk\") {\n if (this._chunkProcessorSize) {\n const buffer = this._chunkProcessorBuffer;\n this._chunkProcessorBuffer = {\n raw: WavPacker.mergeBuffers(buffer.raw, data.raw),\n mono: WavPacker.mergeBuffers(buffer.mono, data.mono),\n };\n if (\n this._chunkProcessorBuffer.mono.byteLength >=\n this._chunkProcessorSize\n ) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n } else {\n this._chunkProcessor(data);\n }\n }\n };\n\n const node = source.connect(processor);\n const analyser = context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n node.connect(analyser);\n if (this.outputToSpeakers) {\n // eslint-disable-next-line no-console\n console.warn(\n \"Warning: Output to speakers may affect sound quality,\\n\" +\n \"especially due to system audio feedback preventative measures.\\n\" +\n \"use only for debugging\"\n );\n analyser.connect(context.destination);\n }\n\n this.source = source;\n this.node = node;\n this.analyser = analyser;\n this.processor = processor;\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the recording track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = \"frequency\",\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * Pauses the recording\n * Keeps microphone stream open but halts storage of audio\n * @returns {Promise<true>}\n */\n async pause() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n } else if (!this.recording) {\n throw new Error(\"Already paused: please call .record() first\");\n }\n if (this._chunkProcessorBuffer.raw.byteLength) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n }\n this.log(\"Pausing ...\");\n await this._event(\"stop\");\n this.recording = false;\n return true;\n }\n\n /**\n * Start recording stream and storing to memory from the connected audio source\n * @param {(data: { mono: Int16Array; raw: Int16Array }) => any} [chunkProcessor]\n * @param {number} [chunkSize] chunkProcessor will not be triggered until this size threshold met in mono audio\n * @returns {Promise<true>}\n */\n async record(chunkProcessor = () => {}, chunkSize = 8192) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n } else if (this.recording) {\n throw new Error(\"Already recording: HELLO please call .pause() first\");\n } else if (typeof chunkProcessor !== \"function\") {\n throw new Error(`chunkProcessor must be a function`);\n }\n this._chunkProcessor = chunkProcessor;\n this._chunkProcessorSize = chunkSize;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n this.log(\"Recording ...\");\n await this._event(\"start\");\n this.recording = true;\n return true;\n }\n\n /**\n * Clears the audio buffer, empties stored recording\n * @returns {Promise<true>}\n */\n async clear() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n await this._event(\"clear\");\n return true;\n }\n\n /**\n * Reads the current audio stream data\n * @returns {Promise<{meanValues: Float32Array, channels: Array<Float32Array>}>}\n */\n async read() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n this.log(\"Reading ...\");\n const result = await this._event(\"read\");\n return result;\n }\n\n /**\n * Saves the current audio stream to a file\n * @param {boolean} [force] Force saving while still recording\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async save(force = false) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n if (!force && this.recording) {\n throw new Error(\n \"Currently recording: please call .pause() first, or call .save(true) to force\"\n );\n }\n this.log(\"Exporting ...\");\n const exportData = await this._event(\"export\");\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Ends the current recording session and saves the result\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async end() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n\n const _processor = this.processor;\n\n this.log(\"Stopping ...\");\n await this._event(\"stop\");\n this.recording = false;\n\n this.log(\"Exporting ...\");\n const exportData = await this._event(\"export\", {}, _processor);\n\n this.processor.disconnect();\n this.source.disconnect();\n this.node.disconnect();\n this.analyser.disconnect();\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Performs a full cleanup of WavRecorder instance\n * Stops actively listening via microphone and removes existing listeners\n * @returns {Promise<true>}\n */\n async quit() {\n this.listenForDeviceChange(null);\n if (this.processor) {\n await this.end();\n }\n return true;\n }\n}\n\nglobalThis.WavRecorder = WavRecorder;\n"],"names":[],"version":3,"file":"index.js.map"}
|
package/dist/index.module.js
CHANGED
|
@@ -1728,6 +1728,7 @@ class $683f111f61e07358$export$b1ca982aa1e488c1 extends (0, $7zbD8$Transport) {
|
|
|
1728
1728
|
this._daily.on("remote-participants-audio-level", this.handleRemoteAudioLevel.bind(this));
|
|
1729
1729
|
this._daily.on("app-message", this.handleAppMessage.bind(this));
|
|
1730
1730
|
this._daily.on("left-meeting", this.handleLeftMeeting.bind(this));
|
|
1731
|
+
this._daily.on("error", this.handleFatalError.bind(this));
|
|
1731
1732
|
this._daily.on("nonfatal-error", this.handleNonFatalError.bind(this));
|
|
1732
1733
|
}
|
|
1733
1734
|
async disconnect() {
|
|
@@ -1833,6 +1834,12 @@ class $683f111f61e07358$export$b1ca982aa1e488c1 extends (0, $7zbD8$Transport) {
|
|
|
1833
1834
|
this._botId = "";
|
|
1834
1835
|
this._callbacks.onDisconnected?.();
|
|
1835
1836
|
}
|
|
1837
|
+
handleFatalError(ev) {
|
|
1838
|
+
(0, $7zbD8$logger).error("Daily fatal error", ev.errorMsg);
|
|
1839
|
+
this.state = "error";
|
|
1840
|
+
this._botId = "";
|
|
1841
|
+
this._callbacks.onError?.((0, $7zbD8$RTVIMessage).error(ev.errorMsg, true));
|
|
1842
|
+
}
|
|
1836
1843
|
handleNonFatalError(ev) {
|
|
1837
1844
|
switch(ev.type){
|
|
1838
1845
|
case "screen-share-error":
|
package/dist/index.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["transports/daily/src/index.ts","transports/daily/src/transport.ts","lib/wavtools/index.js","lib/wavtools/lib/wav_packer.js","lib/wavtools/lib/analysis/audio_analysis.js","lib/wavtools/lib/analysis/constants.js","lib/wavtools/lib/wav_stream_player.js","lib/wavtools/lib/worklets/stream_processor.js","lib/wavtools/lib/wav_recorder.js","lib/wavtools/lib/worklets/audio_processor.js","lib/wavtools/lib/mediastream_recorder.js"],"sourcesContent":["export * from \"./transport\";\n","import Daily, {\n DailyCall,\n DailyEventObjectAppMessage,\n DailyEventObjectAvailableDevicesUpdated,\n DailyEventObjectLocalAudioLevel,\n DailyEventObjectNonFatalError,\n DailyEventObjectParticipant,\n DailyEventObjectParticipantLeft,\n DailyEventObjectRemoteParticipantsAudioLevel,\n DailyEventObjectSelectedDevicesUpdated,\n DailyEventObjectTrack,\n DailyFactoryOptions,\n DailyParticipant,\n} from \"@daily-co/daily-js\";\nimport {\n Participant,\n RTVIClientOptions,\n RTVIError,\n RTVIEventCallbacks,\n RTVIMessage,\n Tracks,\n Transport,\n TransportStartError,\n TransportState,\n logger,\n} from \"@pipecat-ai/client-js\";\n\nimport { MediaStreamRecorder } from \"../../../lib/wavtools\";\n\nexport interface DailyTransportAuthBundle {\n room_url: string;\n token: string;\n}\n\nexport interface DailyTransportConstructorOptions {\n bufferLocalAudioUntilBotReady?: boolean;\n dailyFactoryOptions?: DailyFactoryOptions;\n}\n\nexport enum DailyRTVIMessageType {\n AUDIO_BUFFERING_STARTED = \"audio-buffering-started\",\n AUDIO_BUFFERING_STOPPED = \"audio-buffering-stopped\",\n}\n\nclass DailyCallWrapper {\n private _daily: DailyCall;\n private _proxy: DailyCall;\n\n constructor(daily: DailyCall) {\n this._daily = daily;\n this._proxy = new Proxy(this._daily, {\n get: (target, prop, receiver) => {\n if (typeof target[prop as keyof DailyCall] === \"function\") {\n let errMsg;\n switch (String(prop)) {\n // Disable methods that modify the lifecycle of the call. These operations\n // should be performed via the RTVI client in order to keep state in sync.\n case \"preAuth\":\n errMsg = `Calls to preAuth() are disabled. Please use Transport.preAuth()`;\n break;\n case \"startCamera\":\n errMsg = `Calls to startCamera() are disabled. Please use RTVIClient.initDevices() or Transport.initDevices()`;\n break;\n case \"join\":\n errMsg = `Calls to join() are disabled. Please use RTVIClient.connect()`;\n break;\n case \"leave\":\n errMsg = `Calls to leave() are disabled. Please use RTVIClient.disconnect()`;\n break;\n case \"destroy\":\n errMsg = `Calls to destroy() are disabled.`;\n break;\n }\n if (errMsg) {\n return () => {\n throw new Error(errMsg);\n };\n }\n // Forward other method calls\n return (...args: any[]) => {\n return (target[prop as keyof DailyCall] as Function)(...args);\n };\n }\n // Forward property access\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n\n get proxy(): DailyCall {\n return this._proxy;\n }\n}\n\nexport class DailyTransport extends Transport {\n private declare _dailyWrapper: DailyCallWrapper;\n private declare _daily: DailyCall;\n private _dailyFactoryOptions: DailyFactoryOptions;\n\n private _bufferLocalAudioUntilBotReady: boolean;\n private _botId: string = \"\";\n private _selectedCam: MediaDeviceInfo | Record<string, never> = {};\n private _selectedMic: MediaDeviceInfo | Record<string, never> = {};\n private _selectedSpeaker: MediaDeviceInfo | Record<string, never> = {};\n\n private static RECORDER_SAMPLE_RATE = 16_000;\n private static RECORDER_CHUNK_SIZE = 512;\n private _currentAudioTrack: MediaStreamTrack | null = null;\n private _audioQueue: ArrayBuffer[] = [];\n private declare _mediaStreamRecorder: MediaStreamRecorder;\n\n constructor({\n dailyFactoryOptions = {},\n bufferLocalAudioUntilBotReady = false,\n }: DailyTransportConstructorOptions = {}) {\n super();\n this._callbacks = {} as RTVIEventCallbacks;\n\n this._dailyFactoryOptions = dailyFactoryOptions;\n this._bufferLocalAudioUntilBotReady = bufferLocalAudioUntilBotReady;\n\n this._daily = Daily.createCallObject({\n ...this._dailyFactoryOptions,\n allowMultipleCallInstances: true,\n });\n this._dailyWrapper = new DailyCallWrapper(this._daily);\n }\n\n private setupRecorder(): void {\n this._mediaStreamRecorder = new MediaStreamRecorder({\n sampleRate: DailyTransport.RECORDER_SAMPLE_RATE,\n });\n }\n\n handleUserAudioStream(data: ArrayBuffer): void {\n this._audioQueue.push(data);\n }\n\n private flushAudioQueue(): void {\n const batchSize = 10; // Number of buffers to send in one message\n if (this._audioQueue.length === 0) {\n return;\n }\n\n logger.debug(`Will flush audio queue: ${this._audioQueue.length}`);\n\n while (this._audioQueue.length > 0) {\n const batch: ArrayBuffer[] = [];\n\n // Collect up to `batchSize` items\n while (batch.length < batchSize && this._audioQueue.length > 0) {\n const queuedData = this._audioQueue.shift();\n if (queuedData) batch.push(queuedData);\n }\n\n if (batch.length > 0) {\n this._sendAudioBatch(batch);\n }\n }\n }\n\n _sendAudioBatch(dataBatch: ArrayBuffer[]): void {\n const encodedBatch = dataBatch.map((data) => {\n const pcmByteArray = new Uint8Array(data);\n return btoa(String.fromCharCode(...pcmByteArray));\n });\n\n const rtviMessage: RTVIMessage = {\n id: \"raw-audio-batch\",\n label: \"rtvi-ai\",\n type: \"raw-audio-batch\",\n data: {\n base64AudioBatch: encodedBatch, // Sending an array of base64 strings\n sampleRate: DailyTransport.RECORDER_SAMPLE_RATE,\n numChannels: 1,\n },\n };\n\n this.sendMessage(rtviMessage);\n }\n\n public initialize(\n options: RTVIClientOptions,\n messageHandler: (ev: RTVIMessage) => void\n ): void {\n if (this._bufferLocalAudioUntilBotReady) {\n this.setupRecorder();\n }\n\n this._callbacks = options.callbacks ?? {};\n this._onMessage = messageHandler;\n\n if (\n this._dailyFactoryOptions.startVideoOff == null ||\n options.enableCam != null\n ) {\n // Default is cam off\n this._dailyFactoryOptions.startVideoOff = !(options.enableCam ?? false);\n }\n if (\n this._dailyFactoryOptions.startAudioOff == null ||\n options.enableMic != null\n ) {\n // Default is mic on\n this._dailyFactoryOptions.startAudioOff = !(options.enableMic ?? true);\n }\n\n this.attachEventListeners();\n\n this.state = \"disconnected\";\n\n logger.debug(\"[RTVI Transport] Initialized\");\n }\n\n get dailyCallClient(): DailyCall {\n return this._dailyWrapper.proxy;\n }\n\n get state(): TransportState {\n return this._state;\n }\n\n private set state(state: TransportState) {\n if (this._state === state) return;\n\n this._state = state;\n this._callbacks.onTransportStateChanged?.(state);\n }\n\n async getAllCams() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"videoinput\");\n }\n\n updateCam(camId: string) {\n this._daily\n .setInputDevicesAsync({\n videoDeviceId: camId,\n })\n .then((infos) => {\n this._selectedCam = infos.camera;\n });\n }\n\n get selectedCam() {\n return this._selectedCam;\n }\n\n async getAllMics() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"audioinput\");\n }\n\n updateMic(micId: string) {\n this._daily\n .setInputDevicesAsync({\n audioDeviceId: micId,\n })\n .then((infos) => {\n this._selectedMic = infos.mic;\n });\n }\n\n get selectedMic() {\n return this._selectedMic;\n }\n\n async getAllSpeakers() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"audiooutput\");\n }\n\n updateSpeaker(speakerId: string) {\n this._daily\n .setOutputDeviceAsync({ outputDeviceId: speakerId })\n .then((infos) => {\n this._selectedSpeaker = infos.speaker;\n });\n }\n\n get selectedSpeaker() {\n return this._selectedSpeaker;\n }\n\n enableMic(enable: boolean) {\n this._daily.setLocalAudio(enable);\n }\n\n get isMicEnabled() {\n return this._daily.localAudio();\n }\n\n enableCam(enable: boolean) {\n this._daily.setLocalVideo(enable);\n }\n\n get isCamEnabled() {\n return this._daily.localVideo();\n }\n\n public enableScreenShare(enable: boolean) {\n if (enable) {\n this._daily.startScreenShare();\n } else {\n this._daily.stopScreenShare();\n }\n }\n\n public get isSharingScreen(): boolean {\n return this._daily.localScreenAudio() || this._daily.localScreenVideo();\n }\n\n tracks() {\n const participants = this._daily.participants() ?? {};\n const bot = participants?.[this._botId];\n\n const tracks: Tracks = {\n local: {\n audio: participants?.local?.tracks?.audio?.persistentTrack,\n screenAudio: participants?.local?.tracks?.screenAudio?.persistentTrack,\n screenVideo: participants?.local?.tracks?.screenVideo?.persistentTrack,\n video: participants?.local?.tracks?.video?.persistentTrack,\n },\n };\n\n if (bot) {\n tracks.bot = {\n audio: bot?.tracks?.audio?.persistentTrack,\n video: bot?.tracks?.video?.persistentTrack,\n };\n }\n\n return tracks;\n }\n\n private async startRecording(): Promise<void> {\n try {\n logger.info(\"[RTVI Transport] Initializing recording\");\n await this._mediaStreamRecorder.record((data) => {\n this.handleUserAudioStream(data.mono);\n }, DailyTransport.RECORDER_CHUNK_SIZE);\n this._onMessage({\n type: DailyRTVIMessageType.AUDIO_BUFFERING_STARTED,\n data: {},\n } as RTVIMessage);\n logger.info(\"[RTVI Transport] Recording Initialized\");\n } catch (e) {\n const err = e as Error;\n if (!err.message.includes(\"Already recording\")) {\n logger.error(\"Error starting recording\", e);\n }\n }\n }\n\n async preAuth(dailyFactoryOptions: DailyFactoryOptions) {\n this._dailyFactoryOptions = dailyFactoryOptions;\n await this._daily.preAuth(dailyFactoryOptions);\n }\n\n async initDevices() {\n if (!this._daily) {\n throw new RTVIError(\"Transport instance not initialized\");\n }\n\n this.state = \"initializing\";\n\n const infos = await this._daily.startCamera();\n const { devices } = await this._daily.enumerateDevices();\n const cams = devices.filter((d) => d.kind === \"videoinput\");\n const mics = devices.filter((d) => d.kind === \"audioinput\");\n const speakers = devices.filter((d) => d.kind === \"audiooutput\");\n this._selectedCam = infos.camera;\n this._selectedMic = infos.mic;\n this._selectedSpeaker = infos.speaker;\n\n this._callbacks.onAvailableCamsUpdated?.(cams);\n this._callbacks.onAvailableMicsUpdated?.(mics);\n this._callbacks.onAvailableSpeakersUpdated?.(speakers);\n this._callbacks.onCamUpdated?.(infos.camera as MediaDeviceInfo);\n this._callbacks.onMicUpdated?.(infos.mic as MediaDeviceInfo);\n this._callbacks.onSpeakerUpdated?.(infos.speaker as MediaDeviceInfo);\n\n // Instantiate audio observers\n if (!this._daily.isLocalAudioLevelObserverRunning())\n await this._daily.startLocalAudioLevelObserver(100);\n if (!this._daily.isRemoteParticipantsAudioLevelObserverRunning())\n await this._daily.startRemoteParticipantsAudioLevelObserver(100);\n\n this.state = \"initialized\";\n }\n\n async connect(\n authBundle: DailyTransportAuthBundle,\n abortController: AbortController\n ) {\n if (!this._daily) {\n throw new RTVIError(\"Transport instance not initialized\");\n }\n\n if (abortController.signal.aborted) return;\n\n this.state = \"connecting\";\n\n const opts = this._dailyFactoryOptions;\n opts.url = authBundle.room_url ?? opts.url;\n if (authBundle.token != null) {\n opts.token = authBundle.token;\n }\n try {\n await this._daily.join(opts);\n\n const room = await this._daily.room();\n if (room && \"id\" in room) {\n this._expiry = room.config?.exp;\n }\n } catch (e) {\n logger.error(\"Failed to join room\", e);\n this.state = \"error\";\n throw new TransportStartError();\n }\n\n if (abortController.signal.aborted) return;\n\n this.state = \"connected\";\n\n this._callbacks.onConnected?.();\n }\n\n async sendReadyMessage(): Promise<void> {\n return new Promise<void>((resolve) => {\n (async () => {\n const readyHandler = (ev: DailyEventObjectTrack) => {\n if (!ev.participant?.local) {\n this.state = \"ready\";\n this.flushAudioQueue();\n this.sendMessage(RTVIMessage.clientReady());\n this.stopRecording();\n this._daily.off(\"track-started\", readyHandler);\n resolve();\n }\n };\n this._daily.on(\"track-started\", readyHandler);\n })();\n });\n }\n\n private stopRecording() {\n if (\n this._mediaStreamRecorder &&\n this._mediaStreamRecorder.getStatus() !== \"ended\"\n ) {\n // disconnecting, we don't need to record anymore\n void this._mediaStreamRecorder.end();\n this._onMessage({\n type: DailyRTVIMessageType.AUDIO_BUFFERING_STOPPED,\n data: {},\n } as RTVIMessage);\n }\n }\n\n private attachEventListeners() {\n this._daily.on(\n \"available-devices-updated\",\n this.handleAvailableDevicesUpdated.bind(this)\n );\n this._daily.on(\n \"selected-devices-updated\",\n this.handleSelectedDevicesUpdated.bind(this)\n );\n\n this._daily.on(\"track-started\", this.handleTrackStarted.bind(this));\n this._daily.on(\"track-stopped\", this.handleTrackStopped.bind(this));\n this._daily.on(\n \"participant-joined\",\n this.handleParticipantJoined.bind(this)\n );\n this._daily.on(\"participant-left\", this.handleParticipantLeft.bind(this));\n this._daily.on(\"local-audio-level\", this.handleLocalAudioLevel.bind(this));\n this._daily.on(\n \"remote-participants-audio-level\",\n this.handleRemoteAudioLevel.bind(this)\n );\n this._daily.on(\"app-message\", this.handleAppMessage.bind(this));\n this._daily.on(\"left-meeting\", this.handleLeftMeeting.bind(this));\n this._daily.on(\"nonfatal-error\", this.handleNonFatalError.bind(this));\n }\n\n async disconnect() {\n this.state = \"disconnecting\";\n this._daily.stopLocalAudioLevelObserver();\n this._daily.stopRemoteParticipantsAudioLevelObserver();\n\n this._audioQueue = [];\n this._currentAudioTrack = null;\n this.stopRecording();\n\n await this._daily.leave();\n }\n\n public sendMessage(message: RTVIMessage) {\n this._daily.sendAppMessage(message, \"*\");\n }\n\n private handleAppMessage(ev: DailyEventObjectAppMessage) {\n // Bubble any messages with rtvi-ai label\n if (ev.data.label === \"rtvi-ai\") {\n this._onMessage({\n id: ev.data.id,\n type: ev.data.type,\n data: ev.data.data,\n } as RTVIMessage);\n }\n }\n\n private handleAvailableDevicesUpdated(\n ev: DailyEventObjectAvailableDevicesUpdated\n ) {\n this._callbacks.onAvailableCamsUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"videoinput\")\n );\n this._callbacks.onAvailableMicsUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"audioinput\")\n );\n this._callbacks.onAvailableSpeakersUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"audiooutput\")\n );\n }\n\n private handleSelectedDevicesUpdated(\n ev: DailyEventObjectSelectedDevicesUpdated\n ) {\n if (this._selectedCam?.deviceId !== ev.devices.camera) {\n this._selectedCam = ev.devices.camera;\n this._callbacks.onCamUpdated?.(ev.devices.camera as MediaDeviceInfo);\n }\n if (this._selectedMic?.deviceId !== ev.devices.mic) {\n this._selectedMic = ev.devices.mic;\n this._callbacks.onMicUpdated?.(ev.devices.mic as MediaDeviceInfo);\n }\n if (this._selectedSpeaker?.deviceId !== ev.devices.speaker) {\n this._selectedSpeaker = ev.devices.speaker;\n this._callbacks.onSpeakerUpdated?.(ev.devices.speaker as MediaDeviceInfo);\n }\n }\n\n private async handleLocalAudioTrack(track: MediaStreamTrack) {\n if (this.state == \"ready\" || !this._bufferLocalAudioUntilBotReady) {\n return;\n }\n const status = this._mediaStreamRecorder.getStatus();\n switch (status) {\n case \"ended\":\n await this._mediaStreamRecorder.begin(track);\n await this.startRecording();\n break;\n case \"paused\":\n await this.startRecording();\n break;\n case \"recording\":\n default:\n if (this._currentAudioTrack !== track) {\n await this._mediaStreamRecorder.end();\n await this._mediaStreamRecorder.begin(track);\n await this.startRecording();\n } else {\n logger.warn(\n \"track-started event received for current track and already recording\"\n );\n }\n break;\n }\n this._currentAudioTrack = track;\n }\n\n private handleTrackStarted(ev: DailyEventObjectTrack) {\n if (ev.type === \"screenAudio\" || ev.type === \"screenVideo\") {\n this._callbacks.onScreenTrackStarted?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n } else {\n if (ev.participant?.local && ev.track.kind === \"audio\") {\n void this.handleLocalAudioTrack(ev.track);\n }\n this._callbacks.onTrackStarted?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n }\n }\n\n private handleTrackStopped(ev: DailyEventObjectTrack) {\n if (ev.type === \"screenAudio\" || ev.type === \"screenVideo\") {\n this._callbacks.onScreenTrackStopped?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n } else {\n this._callbacks.onTrackStopped?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n }\n }\n\n private handleParticipantJoined(ev: DailyEventObjectParticipant) {\n const p = dailyParticipantToParticipant(ev.participant);\n\n this._callbacks.onParticipantJoined?.(p);\n\n if (p.local) return;\n\n this._botId = ev.participant.session_id;\n\n this._callbacks.onBotConnected?.(p);\n }\n\n private handleParticipantLeft(ev: DailyEventObjectParticipantLeft) {\n const p = dailyParticipantToParticipant(ev.participant);\n\n this._callbacks.onParticipantLeft?.(p);\n\n if (p.local) return;\n\n this._botId = \"\";\n\n this._callbacks.onBotDisconnected?.(p);\n }\n\n private handleLocalAudioLevel(ev: DailyEventObjectLocalAudioLevel) {\n this._callbacks.onLocalAudioLevel?.(ev.audioLevel);\n }\n\n private handleRemoteAudioLevel(\n ev: DailyEventObjectRemoteParticipantsAudioLevel\n ) {\n const participants = this._daily.participants();\n const ids = Object.keys(ev.participantsAudioLevel);\n for (let i = 0; i < ids.length; i++) {\n const id = ids[i];\n const level = ev.participantsAudioLevel[id];\n this._callbacks.onRemoteAudioLevel?.(\n level,\n dailyParticipantToParticipant(participants[id])\n );\n }\n }\n\n private handleLeftMeeting() {\n this.state = \"disconnected\";\n this._botId = \"\";\n this._callbacks.onDisconnected?.();\n }\n\n private handleNonFatalError(ev: DailyEventObjectNonFatalError) {\n switch (ev.type) {\n case \"screen-share-error\":\n this._callbacks.onScreenShareError?.(ev.errorMsg);\n break;\n }\n }\n}\n\nconst dailyParticipantToParticipant = (p: DailyParticipant): Participant => ({\n id: p.user_id,\n local: p.local,\n name: p.user_name,\n});\n","import { WavPacker } from './lib/wav_packer.js';\nimport { AudioAnalysis } from './lib/analysis/audio_analysis.js';\nimport { WavStreamPlayer } from './lib/wav_stream_player.js';\nimport { WavRecorder } from './lib/wav_recorder.js';\nimport { MediaStreamRecorder } from './lib/mediastream_recorder.js';\n\nexport {\n AudioAnalysis,\n MediaStreamRecorder,\n WavPacker,\n WavStreamPlayer,\n WavRecorder,\n};\n","/**\n * Raw wav audio file contents\n * @typedef {Object} WavPackerAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {number} channelCount\n * @property {number} sampleRate\n * @property {number} duration\n */\n\n/**\n * Utility class for assembling PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavPacker {\n /**\n * Converts Float32Array of amplitude data to ArrayBuffer in Int16Array format\n * @param {Float32Array} float32Array\n * @returns {ArrayBuffer}\n */\n static floatTo16BitPCM(float32Array) {\n const buffer = new ArrayBuffer(float32Array.length * 2);\n const view = new DataView(buffer);\n let offset = 0;\n for (let i = 0; i < float32Array.length; i++, offset += 2) {\n let s = Math.max(-1, Math.min(1, float32Array[i]));\n view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n }\n return buffer;\n }\n\n /**\n * Concatenates two ArrayBuffers\n * @param {ArrayBuffer} leftBuffer\n * @param {ArrayBuffer} rightBuffer\n * @returns {ArrayBuffer}\n */\n static mergeBuffers(leftBuffer, rightBuffer) {\n const tmpArray = new Uint8Array(\n leftBuffer.byteLength + rightBuffer.byteLength\n );\n tmpArray.set(new Uint8Array(leftBuffer), 0);\n tmpArray.set(new Uint8Array(rightBuffer), leftBuffer.byteLength);\n return tmpArray.buffer;\n }\n\n /**\n * Packs data into an Int16 format\n * @private\n * @param {number} size 0 = 1x Int16, 1 = 2x Int16\n * @param {number} arg value to pack\n * @returns\n */\n _packData(size, arg) {\n return [\n new Uint8Array([arg, arg >> 8]),\n new Uint8Array([arg, arg >> 8, arg >> 16, arg >> 24]),\n ][size];\n }\n\n /**\n * Packs audio into \"audio/wav\" Blob\n * @param {number} sampleRate\n * @param {{bitsPerSample: number, channels: Array<Float32Array>, data: Int16Array}} audio\n * @returns {WavPackerAudioType}\n */\n pack(sampleRate, audio) {\n if (!audio?.bitsPerSample) {\n throw new Error(`Missing \"bitsPerSample\"`);\n } else if (!audio?.channels) {\n throw new Error(`Missing \"channels\"`);\n } else if (!audio?.data) {\n throw new Error(`Missing \"data\"`);\n }\n const { bitsPerSample, channels, data } = audio;\n const output = [\n // Header\n 'RIFF',\n this._packData(\n 1,\n 4 + (8 + 24) /* chunk 1 length */ + (8 + 8) /* chunk 2 length */\n ), // Length\n 'WAVE',\n // chunk 1\n 'fmt ', // Sub-chunk identifier\n this._packData(1, 16), // Chunk length\n this._packData(0, 1), // Audio format (1 is linear quantization)\n this._packData(0, channels.length),\n this._packData(1, sampleRate),\n this._packData(1, (sampleRate * channels.length * bitsPerSample) / 8), // Byte rate\n this._packData(0, (channels.length * bitsPerSample) / 8),\n this._packData(0, bitsPerSample),\n // chunk 2\n 'data', // Sub-chunk identifier\n this._packData(\n 1,\n (channels[0].length * channels.length * bitsPerSample) / 8\n ), // Chunk length\n data,\n ];\n const blob = new Blob(output, { type: 'audio/mpeg' });\n const url = URL.createObjectURL(blob);\n return {\n blob,\n url,\n channelCount: channels.length,\n sampleRate,\n duration: data.byteLength / (channels.length * sampleRate * 2),\n };\n }\n}\n\nglobalThis.WavPacker = WavPacker;\n","import {\n noteFrequencies,\n noteFrequencyLabels,\n voiceFrequencies,\n voiceFrequencyLabels,\n} from './constants.js';\n\n/**\n * Output of AudioAnalysis for the frequency domain of the audio\n * @typedef {Object} AudioAnalysisOutputType\n * @property {Float32Array} values Amplitude of this frequency between {0, 1} inclusive\n * @property {number[]} frequencies Raw frequency bucket values\n * @property {string[]} labels Labels for the frequency bucket values\n */\n\n/**\n * Analyzes audio for visual output\n * @class\n */\nexport class AudioAnalysis {\n /**\n * Retrieves frequency domain data from an AnalyserNode adjusted to a decibel range\n * returns human-readable formatting and labels\n * @param {AnalyserNode} analyser\n * @param {number} sampleRate\n * @param {Float32Array} [fftResult]\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {AudioAnalysisOutputType}\n */\n static getFrequencies(\n analyser,\n sampleRate,\n fftResult,\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30,\n ) {\n if (!fftResult) {\n fftResult = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(fftResult);\n }\n const nyquistFrequency = sampleRate / 2;\n const frequencyStep = (1 / fftResult.length) * nyquistFrequency;\n let outputValues;\n let frequencies;\n let labels;\n if (analysisType === 'music' || analysisType === 'voice') {\n const useFrequencies =\n analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n const aggregateOutput = Array(useFrequencies.length).fill(minDecibels);\n for (let i = 0; i < fftResult.length; i++) {\n const frequency = i * frequencyStep;\n const amplitude = fftResult[i];\n for (let n = useFrequencies.length - 1; n >= 0; n--) {\n if (frequency > useFrequencies[n]) {\n aggregateOutput[n] = Math.max(aggregateOutput[n], amplitude);\n break;\n }\n }\n }\n outputValues = aggregateOutput;\n frequencies =\n analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n labels =\n analysisType === 'voice' ? voiceFrequencyLabels : noteFrequencyLabels;\n } else {\n outputValues = Array.from(fftResult);\n frequencies = outputValues.map((_, i) => frequencyStep * i);\n labels = frequencies.map((f) => `${f.toFixed(2)} Hz`);\n }\n // We normalize to {0, 1}\n const normalizedOutput = outputValues.map((v) => {\n return Math.max(\n 0,\n Math.min((v - minDecibels) / (maxDecibels - minDecibels), 1),\n );\n });\n const values = new Float32Array(normalizedOutput);\n return {\n values,\n frequencies,\n labels,\n };\n }\n\n /**\n * Creates a new AudioAnalysis instance for an HTMLAudioElement\n * @param {HTMLAudioElement} audioElement\n * @param {AudioBuffer|null} [audioBuffer] If provided, will cache all frequency domain data from the buffer\n * @returns {AudioAnalysis}\n */\n constructor(audioElement, audioBuffer = null) {\n this.fftResults = [];\n if (audioBuffer) {\n /**\n * Modified from\n * https://stackoverflow.com/questions/75063715/using-the-web-audio-api-to-analyze-a-song-without-playing\n *\n * We do this to populate FFT values for the audio if provided an `audioBuffer`\n * The reason to do this is that Safari fails when using `createMediaElementSource`\n * This has a non-zero RAM cost so we only opt-in to run it on Safari, Chrome is better\n */\n const { length, sampleRate } = audioBuffer;\n const offlineAudioContext = new OfflineAudioContext({\n length,\n sampleRate,\n });\n const source = offlineAudioContext.createBufferSource();\n source.buffer = audioBuffer;\n const analyser = offlineAudioContext.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n source.connect(analyser);\n // limit is :: 128 / sampleRate;\n // but we just want 60fps - cuts ~1s from 6MB to 1MB of RAM\n const renderQuantumInSeconds = 1 / 60;\n const durationInSeconds = length / sampleRate;\n const analyze = (index) => {\n const suspendTime = renderQuantumInSeconds * index;\n if (suspendTime < durationInSeconds) {\n offlineAudioContext.suspend(suspendTime).then(() => {\n const fftResult = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(fftResult);\n this.fftResults.push(fftResult);\n analyze(index + 1);\n });\n }\n if (index === 1) {\n offlineAudioContext.startRendering();\n } else {\n offlineAudioContext.resume();\n }\n };\n source.start(0);\n analyze(1);\n this.audio = audioElement;\n this.context = offlineAudioContext;\n this.analyser = analyser;\n this.sampleRate = sampleRate;\n this.audioBuffer = audioBuffer;\n } else {\n const audioContext = new AudioContext();\n const track = audioContext.createMediaElementSource(audioElement);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n track.connect(analyser);\n analyser.connect(audioContext.destination);\n this.audio = audioElement;\n this.context = audioContext;\n this.analyser = analyser;\n this.sampleRate = this.context.sampleRate;\n this.audioBuffer = null;\n }\n }\n\n /**\n * Gets the current frequency domain data from the playing audio track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30,\n ) {\n let fftResult = null;\n if (this.audioBuffer && this.fftResults.length) {\n const pct = this.audio.currentTime / this.audio.duration;\n const index = Math.min(\n (pct * this.fftResults.length) | 0,\n this.fftResults.length - 1,\n );\n fftResult = this.fftResults[index];\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n fftResult,\n analysisType,\n minDecibels,\n maxDecibels,\n );\n }\n\n /**\n * Resume the internal AudioContext if it was suspended due to the lack of\n * user interaction when the AudioAnalysis was instantiated.\n * @returns {Promise<true>}\n */\n async resumeIfSuspended() {\n if (this.context.state === 'suspended') {\n await this.context.resume();\n }\n return true;\n }\n}\n\nglobalThis.AudioAnalysis = AudioAnalysis;\n","/**\n * Constants for help with visualization\n * Helps map frequency ranges from Fast Fourier Transform\n * to human-interpretable ranges, notably music ranges and\n * human vocal ranges.\n */\n\n// Eighth octave frequencies\nconst octave8Frequencies = [\n 4186.01, 4434.92, 4698.63, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93,\n 6644.88, 7040.0, 7458.62, 7902.13,\n];\n\n// Labels for each of the above frequencies\nconst octave8FrequencyLabels = [\n 'C',\n 'C#',\n 'D',\n 'D#',\n 'E',\n 'F',\n 'F#',\n 'G',\n 'G#',\n 'A',\n 'A#',\n 'B',\n];\n\n/**\n * All note frequencies from 1st to 8th octave\n * in format \"A#8\" (A#, 8th octave)\n */\nexport const noteFrequencies = [];\nexport const noteFrequencyLabels = [];\nfor (let i = 1; i <= 8; i++) {\n for (let f = 0; f < octave8Frequencies.length; f++) {\n const freq = octave8Frequencies[f];\n noteFrequencies.push(freq / Math.pow(2, 8 - i));\n noteFrequencyLabels.push(octave8FrequencyLabels[f] + i);\n }\n}\n\n/**\n * Subset of the note frequencies between 32 and 2000 Hz\n * 6 octave range: C1 to B6\n */\nconst voiceFrequencyRange = [32.0, 2000.0];\nexport const voiceFrequencies = noteFrequencies.filter((_, i) => {\n return (\n noteFrequencies[i] > voiceFrequencyRange[0] &&\n noteFrequencies[i] < voiceFrequencyRange[1]\n );\n});\nexport const voiceFrequencyLabels = noteFrequencyLabels.filter((_, i) => {\n return (\n noteFrequencies[i] > voiceFrequencyRange[0] &&\n noteFrequencies[i] < voiceFrequencyRange[1]\n );\n});\n","import { StreamProcessorSrc } from \"./worklets/stream_processor.js\";\nimport { AudioAnalysis } from \"./analysis/audio_analysis.js\";\n\n/**\n * Plays audio streams received in raw PCM16 chunks from the browser\n * @class\n */\nexport class WavStreamPlayer {\n /**\n * Creates a new WavStreamPlayer instance\n * @param {{sampleRate?: number}} options\n * @returns {WavStreamPlayer}\n */\n constructor({ sampleRate = 44100 } = {}) {\n this.scriptSrc = StreamProcessorSrc;\n this.sampleRate = sampleRate;\n this.context = null;\n this.stream = null;\n this.analyser = null;\n this.trackSampleOffsets = {};\n this.interruptedTrackIds = {};\n }\n\n /**\n * Connects the audio context and enables output to speakers\n * @returns {Promise<true>}\n */\n async connect() {\n this.context = new AudioContext({ sampleRate: this.sampleRate });\n if (this._speakerID) {\n this.context.setSinkId(this._speakerID);\n }\n if (this.context.state === \"suspended\") {\n await this.context.resume();\n }\n try {\n await this.context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const analyser = this.context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n this.analyser = analyser;\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the playing track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = \"frequency\",\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.analyser) {\n throw new Error(\"Not connected, please call .connect() first\");\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * @param {string} speaker deviceId\n */\n async updateSpeaker(speaker) {\n const _prevSpeaker = this._speakerID;\n this._speakerID = speaker;\n if (this.context) {\n try {\n if (speaker === \"default\") {\n await this.context.setSinkId();\n } else {\n await this.context.setSinkId(speaker);\n }\n } catch (e) {\n console.error(`Could not set sinkId to ${speaker}: ${e}`);\n this._speakerID = _prevSpeaker;\n }\n }\n }\n\n /**\n * Starts audio streaming\n * @private\n * @returns {Promise<true>}\n */\n _start() {\n const streamNode = new AudioWorkletNode(this.context, \"stream_processor\");\n streamNode.connect(this.context.destination);\n streamNode.port.onmessage = (e) => {\n const { event } = e.data;\n if (event === \"stop\") {\n streamNode.disconnect();\n this.stream = null;\n } else if (event === \"offset\") {\n const { requestId, trackId, offset } = e.data;\n const currentTime = offset / this.sampleRate;\n this.trackSampleOffsets[requestId] = { trackId, offset, currentTime };\n }\n };\n this.analyser.disconnect();\n streamNode.connect(this.analyser);\n this.stream = streamNode;\n return true;\n }\n\n /**\n * Adds 16BitPCM data to the currently playing audio stream\n * You can add chunks beyond the current play point and they will be queued for play\n * @param {ArrayBuffer|Int16Array} arrayBuffer\n * @param {string} [trackId]\n * @returns {Int16Array}\n */\n add16BitPCM(arrayBuffer, trackId = \"default\") {\n if (typeof trackId !== \"string\") {\n throw new Error(`trackId must be a string`);\n } else if (this.interruptedTrackIds[trackId]) {\n return;\n }\n if (!this.stream) {\n this._start();\n }\n let buffer;\n if (arrayBuffer instanceof Int16Array) {\n buffer = arrayBuffer;\n } else if (arrayBuffer instanceof ArrayBuffer) {\n buffer = new Int16Array(arrayBuffer);\n } else {\n throw new Error(`argument must be Int16Array or ArrayBuffer`);\n }\n this.stream.port.postMessage({ event: \"write\", buffer, trackId });\n return buffer;\n }\n\n /**\n * Gets the offset (sample count) of the currently playing stream\n * @param {boolean} [interrupt]\n * @returns {{trackId: string|null, offset: number, currentTime: number}}\n */\n async getTrackSampleOffset(interrupt = false) {\n if (!this.stream) {\n return null;\n }\n const requestId = crypto.randomUUID();\n this.stream.port.postMessage({\n event: interrupt ? \"interrupt\" : \"offset\",\n requestId,\n });\n let trackSampleOffset;\n while (!trackSampleOffset) {\n trackSampleOffset = this.trackSampleOffsets[requestId];\n await new Promise((r) => setTimeout(() => r(), 1));\n }\n const { trackId } = trackSampleOffset;\n if (interrupt && trackId) {\n this.interruptedTrackIds[trackId] = true;\n }\n return trackSampleOffset;\n }\n\n /**\n * Strips the current stream and returns the sample offset of the audio\n * @param {boolean} [interrupt]\n * @returns {{trackId: string|null, offset: number, currentTime: number}}\n */\n async interrupt() {\n return this.getTrackSampleOffset(true);\n }\n}\n\nglobalThis.WavStreamPlayer = WavStreamPlayer;\n","export const StreamProcessorWorklet = `\nclass StreamProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.hasStarted = false;\n this.hasInterrupted = false;\n this.outputBuffers = [];\n this.bufferLength = 128;\n this.write = { buffer: new Float32Array(this.bufferLength), trackId: null };\n this.writeOffset = 0;\n this.trackSampleOffsets = {};\n this.port.onmessage = (event) => {\n if (event.data) {\n const payload = event.data;\n if (payload.event === 'write') {\n const int16Array = payload.buffer;\n const float32Array = new Float32Array(int16Array.length);\n for (let i = 0; i < int16Array.length; i++) {\n float32Array[i] = int16Array[i] / 0x8000; // Convert Int16 to Float32\n }\n this.writeData(float32Array, payload.trackId);\n } else if (\n payload.event === 'offset' ||\n payload.event === 'interrupt'\n ) {\n const requestId = payload.requestId;\n const trackId = this.write.trackId;\n const offset = this.trackSampleOffsets[trackId] || 0;\n this.port.postMessage({\n event: 'offset',\n requestId,\n trackId,\n offset,\n });\n if (payload.event === 'interrupt') {\n this.hasInterrupted = true;\n }\n } else {\n throw new Error(\\`Unhandled event \"\\${payload.event}\"\\`);\n }\n }\n };\n }\n\n writeData(float32Array, trackId = null) {\n let { buffer } = this.write;\n let offset = this.writeOffset;\n for (let i = 0; i < float32Array.length; i++) {\n buffer[offset++] = float32Array[i];\n if (offset >= buffer.length) {\n this.outputBuffers.push(this.write);\n this.write = { buffer: new Float32Array(this.bufferLength), trackId };\n buffer = this.write.buffer;\n offset = 0;\n }\n }\n this.writeOffset = offset;\n return true;\n }\n\n process(inputs, outputs, parameters) {\n const output = outputs[0];\n const outputChannelData = output[0];\n const outputBuffers = this.outputBuffers;\n if (this.hasInterrupted) {\n this.port.postMessage({ event: 'stop' });\n return false;\n } else if (outputBuffers.length) {\n this.hasStarted = true;\n const { buffer, trackId } = outputBuffers.shift();\n for (let i = 0; i < outputChannelData.length; i++) {\n outputChannelData[i] = buffer[i] || 0;\n }\n if (trackId) {\n this.trackSampleOffsets[trackId] =\n this.trackSampleOffsets[trackId] || 0;\n this.trackSampleOffsets[trackId] += buffer.length;\n }\n return true;\n } else if (this.hasStarted) {\n this.port.postMessage({ event: 'stop' });\n return false;\n } else {\n return true;\n }\n }\n}\n\nregisterProcessor('stream_processor', StreamProcessor);\n`;\n\nconst script = new Blob([StreamProcessorWorklet], {\n type: 'application/javascript',\n});\nconst src = URL.createObjectURL(script);\nexport const StreamProcessorSrc = src;\n","import { AudioProcessorSrc } from './worklets/audio_processor.js';\nimport { AudioAnalysis } from './analysis/audio_analysis.js';\nimport { WavPacker } from './wav_packer.js';\n\n/**\n * Decodes audio into a wav file\n * @typedef {Object} DecodedAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {Float32Array} values\n * @property {AudioBuffer} audioBuffer\n */\n\n/**\n * Records live stream of user audio as PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavRecorder {\n /**\n * Create a new WavRecorder instance\n * @param {{sampleRate?: number, outputToSpeakers?: boolean, debug?: boolean}} [options]\n * @returns {WavRecorder}\n */\n constructor({\n sampleRate = 44100,\n outputToSpeakers = false,\n debug = false,\n } = {}) {\n // Script source\n this.scriptSrc = AudioProcessorSrc;\n // Config\n this.sampleRate = sampleRate;\n this.outputToSpeakers = outputToSpeakers;\n this.debug = !!debug;\n this._deviceChangeCallback = null;\n this._devices = [];\n this.deviceSelection = null;\n // State variables\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n this.recording = false;\n // Event handling with AudioWorklet\n this._lastEventId = 0;\n this.eventReceipts = {};\n this.eventTimeout = 5000;\n // Process chunks of audio\n this._chunkProcessor = () => {};\n this._chunkProcessorSize = void 0;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n\n /**\n * Decodes audio data from multiple formats to a Blob, url, Float32Array and AudioBuffer\n * @param {Blob|Float32Array|Int16Array|ArrayBuffer|number[]} audioData\n * @param {number} sampleRate\n * @param {number} fromSampleRate\n * @returns {Promise<DecodedAudioType>}\n */\n static async decode(audioData, sampleRate = 44100, fromSampleRate = -1) {\n const context = new AudioContext({ sampleRate });\n let arrayBuffer;\n let blob;\n if (audioData instanceof Blob) {\n if (fromSampleRate !== -1) {\n throw new Error(\n `Can not specify \"fromSampleRate\" when reading from Blob`\n );\n }\n blob = audioData;\n arrayBuffer = await blob.arrayBuffer();\n } else if (audioData instanceof ArrayBuffer) {\n if (fromSampleRate !== -1) {\n throw new Error(\n `Can not specify \"fromSampleRate\" when reading from ArrayBuffer`\n );\n }\n arrayBuffer = audioData;\n blob = new Blob([arrayBuffer], { type: 'audio/wav' });\n } else {\n let float32Array;\n let data;\n if (audioData instanceof Int16Array) {\n data = audioData;\n float32Array = new Float32Array(audioData.length);\n for (let i = 0; i < audioData.length; i++) {\n float32Array[i] = audioData[i] / 0x8000;\n }\n } else if (audioData instanceof Float32Array) {\n float32Array = audioData;\n } else if (audioData instanceof Array) {\n float32Array = new Float32Array(audioData);\n } else {\n throw new Error(\n `\"audioData\" must be one of: Blob, Float32Arrray, Int16Array, ArrayBuffer, Array<number>`\n );\n }\n if (fromSampleRate === -1) {\n throw new Error(\n `Must specify \"fromSampleRate\" when reading from Float32Array, In16Array or Array`\n );\n } else if (fromSampleRate < 3000) {\n throw new Error(`Minimum \"fromSampleRate\" is 3000 (3kHz)`);\n }\n if (!data) {\n data = WavPacker.floatTo16BitPCM(float32Array);\n }\n const audio = {\n bitsPerSample: 16,\n channels: [float32Array],\n data,\n };\n const packer = new WavPacker();\n const result = packer.pack(fromSampleRate, audio);\n blob = result.blob;\n arrayBuffer = await blob.arrayBuffer();\n }\n const audioBuffer = await context.decodeAudioData(arrayBuffer);\n const values = audioBuffer.getChannelData(0);\n const url = URL.createObjectURL(blob);\n return {\n blob,\n url,\n values,\n audioBuffer,\n };\n }\n\n /**\n * Logs data in debug mode\n * @param {...any} arguments\n * @returns {true}\n */\n log() {\n if (this.debug) {\n this.log(...arguments);\n }\n return true;\n }\n\n /**\n * Retrieves the current sampleRate for the recorder\n * @returns {number}\n */\n getSampleRate() {\n return this.sampleRate;\n }\n\n /**\n * Retrieves the current status of the recording\n * @returns {\"ended\"|\"paused\"|\"recording\"}\n */\n getStatus() {\n if (!this.processor) {\n return 'ended';\n } else if (!this.recording) {\n return 'paused';\n } else {\n return 'recording';\n }\n }\n\n /**\n * Sends an event to the AudioWorklet\n * @private\n * @param {string} name\n * @param {{[key: string]: any}} data\n * @param {AudioWorkletNode} [_processor]\n * @returns {Promise<{[key: string]: any}>}\n */\n async _event(name, data = {}, _processor = null) {\n _processor = _processor || this.processor;\n if (!_processor) {\n throw new Error('Can not send events without recording first');\n }\n const message = {\n event: name,\n id: this._lastEventId++,\n data,\n };\n _processor.port.postMessage(message);\n const t0 = new Date().valueOf();\n while (!this.eventReceipts[message.id]) {\n if (new Date().valueOf() - t0 > this.eventTimeout) {\n throw new Error(`Timeout waiting for \"${name}\" event`);\n }\n await new Promise((res) => setTimeout(() => res(true), 1));\n }\n const payload = this.eventReceipts[message.id];\n delete this.eventReceipts[message.id];\n return payload;\n }\n\n /**\n * Sets device change callback, remove if callback provided is `null`\n * @param {(Array<MediaDeviceInfo & {default: boolean}>): void|null} callback\n * @returns {true}\n */\n listenForDeviceChange(callback) {\n if (callback === null && this._deviceChangeCallback) {\n navigator.mediaDevices.removeEventListener(\n 'devicechange',\n this._deviceChangeCallback\n );\n this._deviceChangeCallback = null;\n } else if (callback !== null) {\n // Basically a debounce; we only want this called once when devices change\n // And we only want the most recent callback() to be executed\n // if a few are operating at the same time\n let lastId = 0;\n let lastDevices = [];\n const serializeDevices = (devices) =>\n devices\n .map((d) => d.deviceId)\n .sort()\n .join(',');\n const cb = async () => {\n let id = ++lastId;\n const devices = await this.listDevices();\n if (id === lastId) {\n if (serializeDevices(lastDevices) !== serializeDevices(devices)) {\n lastDevices = devices;\n callback(devices.slice());\n }\n }\n };\n navigator.mediaDevices.addEventListener('devicechange', cb);\n cb();\n this._deviceChangeCallback = cb;\n }\n return true;\n }\n\n /**\n * Manually request permission to use the microphone\n * @returns {Promise<true>}\n */\n async requestPermission() {\n const permissionStatus = await navigator.permissions.query({\n name: 'microphone',\n });\n if (permissionStatus.state === 'denied') {\n window.alert('You must grant microphone access to use this feature.');\n } else if (permissionStatus.state === 'prompt') {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n const tracks = stream.getTracks();\n tracks.forEach((track) => track.stop());\n } catch (e) {\n window.alert('You must grant microphone access to use this feature.');\n }\n }\n return true;\n }\n\n /**\n * List all eligible devices for recording, will request permission to use microphone\n * @returns {Promise<Array<MediaDeviceInfo & {default: boolean}>>}\n */\n async listDevices() {\n if (\n !navigator.mediaDevices ||\n !('enumerateDevices' in navigator.mediaDevices)\n ) {\n throw new Error('Could not request user devices');\n }\n await this.requestPermission();\n const devices = await navigator.mediaDevices.enumerateDevices();\n const audioDevices = devices.filter(\n (device) => device.kind === 'audioinput'\n );\n return audioDevices;\n // const defaultDeviceIndex = audioDevices.findIndex(\n // (device) => device.deviceId === 'default'\n // );\n // const deviceList = [];\n // if (defaultDeviceIndex !== -1) {\n // let defaultDevice = audioDevices.splice(defaultDeviceIndex, 1)[0];\n // let existingIndex = audioDevices.findIndex(\n // (device) => device.groupId === defaultDevice.groupId\n // );\n // if (existingIndex !== -1) {\n // defaultDevice = audioDevices.splice(existingIndex, 1)[0];\n // }\n // defaultDevice.default = true;\n // deviceList.push(defaultDevice);\n // }\n // return deviceList.concat(audioDevices);\n }\n\n /**\n * Begins a recording session and requests microphone permissions if not already granted\n * Microphone recording indicator will appear on browser tab but status will be \"paused\"\n * @param {string} [deviceId] if no device provided, default device will be used\n * @returns {Promise<true>}\n */\n async begin(deviceId) {\n if (this.processor) {\n throw new Error(\n `Already connected: please call .end() to start a new session`\n );\n }\n\n if (\n !navigator.mediaDevices ||\n !('getUserMedia' in navigator.mediaDevices)\n ) {\n throw new Error('Could not request user media');\n }\n deviceId = deviceId ?? this.deviceSelection?.deviceId;\n try {\n const config = { audio: true };\n if (deviceId) {\n config.audio = { deviceId: { exact: deviceId } };\n }\n this.stream = await navigator.mediaDevices.getUserMedia(config);\n } catch (err) {\n throw new Error('Could not start media stream');\n }\n\n this.listDevices().then((devices) => {\n deviceId = this.stream.getAudioTracks()[0].getSettings().deviceId;\n console.log(\n 'find current device',\n devices,\n deviceId,\n this.stream.getAudioTracks()[0].getSettings()\n );\n this.deviceSelection = devices.find((d) => d.deviceId === deviceId);\n console.log('current device', this.deviceSelection);\n });\n const context = new AudioContext({ sampleRate: this.sampleRate });\n const source = context.createMediaStreamSource(this.stream);\n // Load and execute the module script.\n try {\n await context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const processor = new AudioWorkletNode(context, 'audio_processor');\n processor.port.onmessage = (e) => {\n const { event, id, data } = e.data;\n if (event === 'receipt') {\n this.eventReceipts[id] = data;\n } else if (event === 'chunk') {\n if (this._chunkProcessorSize) {\n const buffer = this._chunkProcessorBuffer;\n this._chunkProcessorBuffer = {\n raw: WavPacker.mergeBuffers(buffer.raw, data.raw),\n mono: WavPacker.mergeBuffers(buffer.mono, data.mono),\n };\n if (\n this._chunkProcessorBuffer.mono.byteLength >=\n this._chunkProcessorSize\n ) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n } else {\n this._chunkProcessor(data);\n }\n }\n };\n\n const node = source.connect(processor);\n const analyser = context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n node.connect(analyser);\n if (this.outputToSpeakers) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Warning: Output to speakers may affect sound quality,\\n' +\n 'especially due to system audio feedback preventative measures.\\n' +\n 'use only for debugging'\n );\n analyser.connect(context.destination);\n }\n\n this.source = source;\n this.node = node;\n this.analyser = analyser;\n this.processor = processor;\n console.log('begin completed');\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the recording track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * Pauses the recording\n * Keeps microphone stream open but halts storage of audio\n * @returns {Promise<true>}\n */\n async pause() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n } else if (!this.recording) {\n throw new Error('Already paused: please call .record() first');\n }\n if (this._chunkProcessorBuffer.raw.byteLength) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n }\n this.log('Pausing ...');\n await this._event('stop');\n this.recording = false;\n return true;\n }\n\n /**\n * Start recording stream and storing to memory from the connected audio source\n * @param {(data: { mono: Int16Array; raw: Int16Array }) => any} [chunkProcessor]\n * @param {number} [chunkSize] chunkProcessor will not be triggered until this size threshold met in mono audio\n * @returns {Promise<true>}\n */\n async record(chunkProcessor = () => {}, chunkSize = 8192) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n } else if (this.recording) {\n throw new Error('Already recording: please call .pause() first');\n } else if (typeof chunkProcessor !== 'function') {\n throw new Error(`chunkProcessor must be a function`);\n }\n this._chunkProcessor = chunkProcessor;\n this._chunkProcessorSize = chunkSize;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n this.log('Recording ...');\n await this._event('start');\n this.recording = true;\n return true;\n }\n\n /**\n * Clears the audio buffer, empties stored recording\n * @returns {Promise<true>}\n */\n async clear() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n await this._event('clear');\n return true;\n }\n\n /**\n * Reads the current audio stream data\n * @returns {Promise<{meanValues: Float32Array, channels: Array<Float32Array>}>}\n */\n async read() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n this.log('Reading ...');\n const result = await this._event('read');\n return result;\n }\n\n /**\n * Saves the current audio stream to a file\n * @param {boolean} [force] Force saving while still recording\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async save(force = false) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n if (!force && this.recording) {\n throw new Error(\n 'Currently recording: please call .pause() first, or call .save(true) to force'\n );\n }\n this.log('Exporting ...');\n const exportData = await this._event('export');\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Ends the current recording session and saves the result\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async end() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n\n const _processor = this.processor;\n\n this.log('Stopping ...');\n await this._event('stop');\n this.recording = false;\n const tracks = this.stream.getTracks();\n tracks.forEach((track) => track.stop());\n\n this.log('Exporting ...');\n const exportData = await this._event('export', {}, _processor);\n\n this.processor.disconnect();\n this.source.disconnect();\n this.node.disconnect();\n this.analyser.disconnect();\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Performs a full cleanup of WavRecorder instance\n * Stops actively listening via microphone and removes existing listeners\n * @returns {Promise<true>}\n */\n async quit() {\n this.listenForDeviceChange(null);\n // we do not reset this on end so that selections persist across starts\n this.deviceSelection = null;\n if (this.processor) {\n await this.end();\n }\n return true;\n }\n}\n\nglobalThis.WavRecorder = WavRecorder;\n","const AudioProcessorWorklet = `\nclass AudioProcessor extends AudioWorkletProcessor {\n\n constructor() {\n super();\n this.port.onmessage = this.receive.bind(this);\n this.initialize();\n }\n\n initialize() {\n this.foundAudio = false;\n this.recording = false;\n this.chunks = [];\n }\n\n /**\n * Concatenates sampled chunks into channels\n * Format is chunk[Left[], Right[]]\n */\n readChannelData(chunks, channel = -1, maxChannels = 9) {\n let channelLimit;\n if (channel !== -1) {\n if (chunks[0] && chunks[0].length - 1 < channel) {\n throw new Error(\n \\`Channel \\${channel} out of range: max \\${chunks[0].length}\\`\n );\n }\n channelLimit = channel + 1;\n } else {\n channel = 0;\n channelLimit = Math.min(chunks[0] ? chunks[0].length : 1, maxChannels);\n }\n const channels = [];\n for (let n = channel; n < channelLimit; n++) {\n const length = chunks.reduce((sum, chunk) => {\n return sum + chunk[n].length;\n }, 0);\n const buffers = chunks.map((chunk) => chunk[n]);\n const result = new Float32Array(length);\n let offset = 0;\n for (let i = 0; i < buffers.length; i++) {\n result.set(buffers[i], offset);\n offset += buffers[i].length;\n }\n channels[n] = result;\n }\n return channels;\n }\n\n /**\n * Combines parallel audio data into correct format,\n * channels[Left[], Right[]] to float32Array[LRLRLRLR...]\n */\n formatAudioData(channels) {\n if (channels.length === 1) {\n // Simple case is only one channel\n const float32Array = channels[0].slice();\n const meanValues = channels[0].slice();\n return { float32Array, meanValues };\n } else {\n const float32Array = new Float32Array(\n channels[0].length * channels.length\n );\n const meanValues = new Float32Array(channels[0].length);\n for (let i = 0; i < channels[0].length; i++) {\n const offset = i * channels.length;\n let meanValue = 0;\n for (let n = 0; n < channels.length; n++) {\n float32Array[offset + n] = channels[n][i];\n meanValue += channels[n][i];\n }\n meanValues[i] = meanValue / channels.length;\n }\n return { float32Array, meanValues };\n }\n }\n\n /**\n * Converts 32-bit float data to 16-bit integers\n */\n floatTo16BitPCM(float32Array) {\n const buffer = new ArrayBuffer(float32Array.length * 2);\n const view = new DataView(buffer);\n let offset = 0;\n for (let i = 0; i < float32Array.length; i++, offset += 2) {\n let s = Math.max(-1, Math.min(1, float32Array[i]));\n view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n }\n return buffer;\n }\n\n /**\n * Retrieves the most recent amplitude values from the audio stream\n * @param {number} channel\n */\n getValues(channel = -1) {\n const channels = this.readChannelData(this.chunks, channel);\n const { meanValues } = this.formatAudioData(channels);\n return { meanValues, channels };\n }\n\n /**\n * Exports chunks as an audio/wav file\n */\n export() {\n const channels = this.readChannelData(this.chunks);\n const { float32Array, meanValues } = this.formatAudioData(channels);\n const audioData = this.floatTo16BitPCM(float32Array);\n return {\n meanValues: meanValues,\n audio: {\n bitsPerSample: 16,\n channels: channels,\n data: audioData,\n },\n };\n }\n\n receive(e) {\n const { event, id } = e.data;\n let receiptData = {};\n switch (event) {\n case 'start':\n this.recording = true;\n break;\n case 'stop':\n this.recording = false;\n break;\n case 'clear':\n this.initialize();\n break;\n case 'export':\n receiptData = this.export();\n break;\n case 'read':\n receiptData = this.getValues();\n break;\n default:\n break;\n }\n // Always send back receipt\n this.port.postMessage({ event: 'receipt', id, data: receiptData });\n }\n\n sendChunk(chunk) {\n const channels = this.readChannelData([chunk]);\n const { float32Array, meanValues } = this.formatAudioData(channels);\n const rawAudioData = this.floatTo16BitPCM(float32Array);\n const monoAudioData = this.floatTo16BitPCM(meanValues);\n this.port.postMessage({\n event: 'chunk',\n data: {\n mono: monoAudioData,\n raw: rawAudioData,\n },\n });\n }\n\n process(inputList, outputList, parameters) {\n // Copy input to output (e.g. speakers)\n // Note that this creates choppy sounds with Mac products\n const sourceLimit = Math.min(inputList.length, outputList.length);\n for (let inputNum = 0; inputNum < sourceLimit; inputNum++) {\n const input = inputList[inputNum];\n const output = outputList[inputNum];\n const channelCount = Math.min(input.length, output.length);\n for (let channelNum = 0; channelNum < channelCount; channelNum++) {\n input[channelNum].forEach((sample, i) => {\n output[channelNum][i] = sample;\n });\n }\n }\n const inputs = inputList[0];\n // There's latency at the beginning of a stream before recording starts\n // Make sure we actually receive audio data before we start storing chunks\n let sliceIndex = 0;\n if (!this.foundAudio) {\n for (const channel of inputs) {\n sliceIndex = 0; // reset for each channel\n if (this.foundAudio) {\n break;\n }\n if (channel) {\n for (const value of channel) {\n if (value !== 0) {\n // find only one non-zero entry in any channel\n this.foundAudio = true;\n break;\n } else {\n sliceIndex++;\n }\n }\n }\n }\n }\n if (inputs && inputs[0] && this.foundAudio && this.recording) {\n // We need to copy the TypedArray, because the \\`process\\`\n // internals will reuse the same buffer to hold each input\n const chunk = inputs.map((input) => input.slice(sliceIndex));\n this.chunks.push(chunk);\n this.sendChunk(chunk);\n }\n return true;\n }\n}\n\nregisterProcessor('audio_processor', AudioProcessor);\n`;\n\nconst script = new Blob([AudioProcessorWorklet], {\n type: 'application/javascript',\n});\nconst src = URL.createObjectURL(script);\nexport const AudioProcessorSrc = src;\n","import { AudioProcessorSrc } from \"./worklets/audio_processor.js\";\nimport { AudioAnalysis } from \"./analysis/audio_analysis.js\";\nimport { WavPacker } from \"./wav_packer.js\";\n\n/**\n * Decodes audio into a wav file\n * @typedef {Object} DecodedAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {Float32Array} values\n * @property {AudioBuffer} audioBuffer\n */\n\n/**\n * Records live stream of user audio as PCM16 \"audio/wav\" data\n * @class\n */\nexport class MediaStreamRecorder {\n /**\n * Create a new MediaStreamRecorder instance\n * @param {{sampleRate?: number, outputToSpeakers?: boolean, debug?: boolean}} [options]\n * @returns {MediaStreamRecorder}\n */\n constructor({\n sampleRate = 44100,\n outputToSpeakers = false,\n debug = false,\n } = {}) {\n // Script source\n this.scriptSrc = AudioProcessorSrc;\n // Config\n this.sampleRate = sampleRate;\n this.outputToSpeakers = outputToSpeakers;\n this.debug = !!debug;\n // State variables\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n this.recording = false;\n // Event handling with AudioWorklet\n this._lastEventId = 0;\n this.eventReceipts = {};\n this.eventTimeout = 5000;\n // Process chunks of audio\n this._chunkProcessor = () => {};\n this._chunkProcessorSize = void 0;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n\n /**\n * Logs data in debug mode\n * @param {...any} arguments\n * @returns {true}\n */\n log() {\n if (this.debug) {\n this.log(...arguments);\n }\n return true;\n }\n\n /**\n * Retrieves the current sampleRate for the recorder\n * @returns {number}\n */\n getSampleRate() {\n return this.sampleRate;\n }\n\n /**\n * Retrieves the current status of the recording\n * @returns {\"ended\"|\"paused\"|\"recording\"}\n */\n getStatus() {\n if (!this.processor) {\n return \"ended\";\n } else if (!this.recording) {\n return \"paused\";\n } else {\n return \"recording\";\n }\n }\n\n /**\n * Sends an event to the AudioWorklet\n * @private\n * @param {string} name\n * @param {{[key: string]: any}} data\n * @param {AudioWorkletNode} [_processor]\n * @returns {Promise<{[key: string]: any}>}\n */\n async _event(name, data = {}, _processor = null) {\n _processor = _processor || this.processor;\n if (!_processor) {\n throw new Error(\"Can not send events without recording first\");\n }\n const message = {\n event: name,\n id: this._lastEventId++,\n data,\n };\n _processor.port.postMessage(message);\n const t0 = new Date().valueOf();\n while (!this.eventReceipts[message.id]) {\n if (new Date().valueOf() - t0 > this.eventTimeout) {\n throw new Error(`Timeout waiting for \"${name}\" event`);\n }\n await new Promise((res) => setTimeout(() => res(true), 1));\n }\n const payload = this.eventReceipts[message.id];\n delete this.eventReceipts[message.id];\n return payload;\n }\n\n /**\n * Begins a recording session for the given audioTrack\n * Microphone recording indicator will appear on browser tab but status will be \"paused\"\n * @param {MediaStreamTrack} [audioTrack] if no device provided, default device will be used\n * @returns {Promise<true>}\n */\n async begin(audioTrack) {\n if (this.processor) {\n throw new Error(\n `Already connected: please call .end() to start a new session`\n );\n }\n\n if (!audioTrack || audioTrack.kind !== \"audio\") {\n throw new Error(\"No audio track provided\");\n }\n\n this.stream = new MediaStream([audioTrack]);\n\n const context = new AudioContext({ sampleRate: this.sampleRate });\n const source = context.createMediaStreamSource(this.stream);\n // Load and execute the module script.\n try {\n await context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const processor = new AudioWorkletNode(context, \"audio_processor\");\n processor.port.onmessage = (e) => {\n const { event, id, data } = e.data;\n if (event === \"receipt\") {\n this.eventReceipts[id] = data;\n } else if (event === \"chunk\") {\n if (this._chunkProcessorSize) {\n const buffer = this._chunkProcessorBuffer;\n this._chunkProcessorBuffer = {\n raw: WavPacker.mergeBuffers(buffer.raw, data.raw),\n mono: WavPacker.mergeBuffers(buffer.mono, data.mono),\n };\n if (\n this._chunkProcessorBuffer.mono.byteLength >=\n this._chunkProcessorSize\n ) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n } else {\n this._chunkProcessor(data);\n }\n }\n };\n\n const node = source.connect(processor);\n const analyser = context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n node.connect(analyser);\n if (this.outputToSpeakers) {\n // eslint-disable-next-line no-console\n console.warn(\n \"Warning: Output to speakers may affect sound quality,\\n\" +\n \"especially due to system audio feedback preventative measures.\\n\" +\n \"use only for debugging\"\n );\n analyser.connect(context.destination);\n }\n\n this.source = source;\n this.node = node;\n this.analyser = analyser;\n this.processor = processor;\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the recording track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = \"frequency\",\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * Pauses the recording\n * Keeps microphone stream open but halts storage of audio\n * @returns {Promise<true>}\n */\n async pause() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n } else if (!this.recording) {\n throw new Error(\"Already paused: please call .record() first\");\n }\n if (this._chunkProcessorBuffer.raw.byteLength) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n }\n this.log(\"Pausing ...\");\n await this._event(\"stop\");\n this.recording = false;\n return true;\n }\n\n /**\n * Start recording stream and storing to memory from the connected audio source\n * @param {(data: { mono: Int16Array; raw: Int16Array }) => any} [chunkProcessor]\n * @param {number} [chunkSize] chunkProcessor will not be triggered until this size threshold met in mono audio\n * @returns {Promise<true>}\n */\n async record(chunkProcessor = () => {}, chunkSize = 8192) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n } else if (this.recording) {\n throw new Error(\"Already recording: HELLO please call .pause() first\");\n } else if (typeof chunkProcessor !== \"function\") {\n throw new Error(`chunkProcessor must be a function`);\n }\n this._chunkProcessor = chunkProcessor;\n this._chunkProcessorSize = chunkSize;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n this.log(\"Recording ...\");\n await this._event(\"start\");\n this.recording = true;\n return true;\n }\n\n /**\n * Clears the audio buffer, empties stored recording\n * @returns {Promise<true>}\n */\n async clear() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n await this._event(\"clear\");\n return true;\n }\n\n /**\n * Reads the current audio stream data\n * @returns {Promise<{meanValues: Float32Array, channels: Array<Float32Array>}>}\n */\n async read() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n this.log(\"Reading ...\");\n const result = await this._event(\"read\");\n return result;\n }\n\n /**\n * Saves the current audio stream to a file\n * @param {boolean} [force] Force saving while still recording\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async save(force = false) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n if (!force && this.recording) {\n throw new Error(\n \"Currently recording: please call .pause() first, or call .save(true) to force\"\n );\n }\n this.log(\"Exporting ...\");\n const exportData = await this._event(\"export\");\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Ends the current recording session and saves the result\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async end() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n\n const _processor = this.processor;\n\n this.log(\"Stopping ...\");\n await this._event(\"stop\");\n this.recording = false;\n\n this.log(\"Exporting ...\");\n const exportData = await this._event(\"export\", {}, _processor);\n\n this.processor.disconnect();\n this.source.disconnect();\n this.node.disconnect();\n this.analyser.disconnect();\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Performs a full cleanup of WavRecorder instance\n * Stops actively listening via microphone and removes existing listeners\n * @returns {Promise<true>}\n */\n async quit() {\n this.listenForDeviceChange(null);\n if (this.processor) {\n await this.end();\n }\n return true;\n }\n}\n\nglobalThis.WavRecorder = WavRecorder;\n"],"names":[],"version":3,"file":"index.module.js.map"}
|
|
1
|
+
{"mappings":"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","sources":["transports/daily/src/index.ts","transports/daily/src/transport.ts","lib/wavtools/index.js","lib/wavtools/lib/wav_packer.js","lib/wavtools/lib/analysis/audio_analysis.js","lib/wavtools/lib/analysis/constants.js","lib/wavtools/lib/wav_stream_player.js","lib/wavtools/lib/worklets/stream_processor.js","lib/wavtools/lib/wav_recorder.js","lib/wavtools/lib/worklets/audio_processor.js","lib/wavtools/lib/mediastream_recorder.js"],"sourcesContent":["export * from \"./transport\";\n","import Daily, {\n DailyCall,\n DailyEventObjectAppMessage,\n DailyEventObjectAvailableDevicesUpdated,\n DailyEventObjectFatalError,\n DailyEventObjectLocalAudioLevel,\n DailyEventObjectNonFatalError,\n DailyEventObjectParticipant,\n DailyEventObjectParticipantLeft,\n DailyEventObjectRemoteParticipantsAudioLevel,\n DailyEventObjectSelectedDevicesUpdated,\n DailyEventObjectTrack,\n DailyFactoryOptions,\n DailyParticipant,\n} from \"@daily-co/daily-js\";\nimport {\n Participant,\n RTVIClientOptions,\n RTVIError,\n RTVIEventCallbacks,\n RTVIMessage,\n Tracks,\n Transport,\n TransportStartError,\n TransportState,\n logger,\n} from \"@pipecat-ai/client-js\";\n\nimport { MediaStreamRecorder } from \"../../../lib/wavtools\";\n\nexport interface DailyTransportAuthBundle {\n room_url: string;\n token: string;\n}\n\nexport interface DailyTransportConstructorOptions {\n bufferLocalAudioUntilBotReady?: boolean;\n dailyFactoryOptions?: DailyFactoryOptions;\n}\n\nexport enum DailyRTVIMessageType {\n AUDIO_BUFFERING_STARTED = \"audio-buffering-started\",\n AUDIO_BUFFERING_STOPPED = \"audio-buffering-stopped\",\n}\n\nclass DailyCallWrapper {\n private _daily: DailyCall;\n private _proxy: DailyCall;\n\n constructor(daily: DailyCall) {\n this._daily = daily;\n this._proxy = new Proxy(this._daily, {\n get: (target, prop, receiver) => {\n if (typeof target[prop as keyof DailyCall] === \"function\") {\n let errMsg;\n switch (String(prop)) {\n // Disable methods that modify the lifecycle of the call. These operations\n // should be performed via the RTVI client in order to keep state in sync.\n case \"preAuth\":\n errMsg = `Calls to preAuth() are disabled. Please use Transport.preAuth()`;\n break;\n case \"startCamera\":\n errMsg = `Calls to startCamera() are disabled. Please use RTVIClient.initDevices() or Transport.initDevices()`;\n break;\n case \"join\":\n errMsg = `Calls to join() are disabled. Please use RTVIClient.connect()`;\n break;\n case \"leave\":\n errMsg = `Calls to leave() are disabled. Please use RTVIClient.disconnect()`;\n break;\n case \"destroy\":\n errMsg = `Calls to destroy() are disabled.`;\n break;\n }\n if (errMsg) {\n return () => {\n throw new Error(errMsg);\n };\n }\n // Forward other method calls\n return (...args: any[]) => {\n return (target[prop as keyof DailyCall] as Function)(...args);\n };\n }\n // Forward property access\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n\n get proxy(): DailyCall {\n return this._proxy;\n }\n}\n\nexport class DailyTransport extends Transport {\n private declare _dailyWrapper: DailyCallWrapper;\n private declare _daily: DailyCall;\n private _dailyFactoryOptions: DailyFactoryOptions;\n\n private _bufferLocalAudioUntilBotReady: boolean;\n private _botId: string = \"\";\n private _selectedCam: MediaDeviceInfo | Record<string, never> = {};\n private _selectedMic: MediaDeviceInfo | Record<string, never> = {};\n private _selectedSpeaker: MediaDeviceInfo | Record<string, never> = {};\n\n private static RECORDER_SAMPLE_RATE = 16_000;\n private static RECORDER_CHUNK_SIZE = 512;\n private _currentAudioTrack: MediaStreamTrack | null = null;\n private _audioQueue: ArrayBuffer[] = [];\n private declare _mediaStreamRecorder: MediaStreamRecorder;\n\n constructor({\n dailyFactoryOptions = {},\n bufferLocalAudioUntilBotReady = false,\n }: DailyTransportConstructorOptions = {}) {\n super();\n this._callbacks = {} as RTVIEventCallbacks;\n\n this._dailyFactoryOptions = dailyFactoryOptions;\n this._bufferLocalAudioUntilBotReady = bufferLocalAudioUntilBotReady;\n\n this._daily = Daily.createCallObject({\n ...this._dailyFactoryOptions,\n allowMultipleCallInstances: true,\n });\n this._dailyWrapper = new DailyCallWrapper(this._daily);\n }\n\n private setupRecorder(): void {\n this._mediaStreamRecorder = new MediaStreamRecorder({\n sampleRate: DailyTransport.RECORDER_SAMPLE_RATE,\n });\n }\n\n handleUserAudioStream(data: ArrayBuffer): void {\n this._audioQueue.push(data);\n }\n\n private flushAudioQueue(): void {\n const batchSize = 10; // Number of buffers to send in one message\n if (this._audioQueue.length === 0) {\n return;\n }\n\n logger.debug(`Will flush audio queue: ${this._audioQueue.length}`);\n\n while (this._audioQueue.length > 0) {\n const batch: ArrayBuffer[] = [];\n\n // Collect up to `batchSize` items\n while (batch.length < batchSize && this._audioQueue.length > 0) {\n const queuedData = this._audioQueue.shift();\n if (queuedData) batch.push(queuedData);\n }\n\n if (batch.length > 0) {\n this._sendAudioBatch(batch);\n }\n }\n }\n\n _sendAudioBatch(dataBatch: ArrayBuffer[]): void {\n const encodedBatch = dataBatch.map((data) => {\n const pcmByteArray = new Uint8Array(data);\n return btoa(String.fromCharCode(...pcmByteArray));\n });\n\n const rtviMessage: RTVIMessage = {\n id: \"raw-audio-batch\",\n label: \"rtvi-ai\",\n type: \"raw-audio-batch\",\n data: {\n base64AudioBatch: encodedBatch, // Sending an array of base64 strings\n sampleRate: DailyTransport.RECORDER_SAMPLE_RATE,\n numChannels: 1,\n },\n };\n\n this.sendMessage(rtviMessage);\n }\n\n public initialize(\n options: RTVIClientOptions,\n messageHandler: (ev: RTVIMessage) => void\n ): void {\n if (this._bufferLocalAudioUntilBotReady) {\n this.setupRecorder();\n }\n\n this._callbacks = options.callbacks ?? {};\n this._onMessage = messageHandler;\n\n if (\n this._dailyFactoryOptions.startVideoOff == null ||\n options.enableCam != null\n ) {\n // Default is cam off\n this._dailyFactoryOptions.startVideoOff = !(options.enableCam ?? false);\n }\n if (\n this._dailyFactoryOptions.startAudioOff == null ||\n options.enableMic != null\n ) {\n // Default is mic on\n this._dailyFactoryOptions.startAudioOff = !(options.enableMic ?? true);\n }\n\n this.attachEventListeners();\n\n this.state = \"disconnected\";\n\n logger.debug(\"[RTVI Transport] Initialized\");\n }\n\n get dailyCallClient(): DailyCall {\n return this._dailyWrapper.proxy;\n }\n\n get state(): TransportState {\n return this._state;\n }\n\n private set state(state: TransportState) {\n if (this._state === state) return;\n\n this._state = state;\n this._callbacks.onTransportStateChanged?.(state);\n }\n\n async getAllCams() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"videoinput\");\n }\n\n updateCam(camId: string) {\n this._daily\n .setInputDevicesAsync({\n videoDeviceId: camId,\n })\n .then((infos) => {\n this._selectedCam = infos.camera;\n });\n }\n\n get selectedCam() {\n return this._selectedCam;\n }\n\n async getAllMics() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"audioinput\");\n }\n\n updateMic(micId: string) {\n this._daily\n .setInputDevicesAsync({\n audioDeviceId: micId,\n })\n .then((infos) => {\n this._selectedMic = infos.mic;\n });\n }\n\n get selectedMic() {\n return this._selectedMic;\n }\n\n async getAllSpeakers() {\n const { devices } = await this._daily.enumerateDevices();\n return devices.filter((d) => d.kind === \"audiooutput\");\n }\n\n updateSpeaker(speakerId: string) {\n this._daily\n .setOutputDeviceAsync({ outputDeviceId: speakerId })\n .then((infos) => {\n this._selectedSpeaker = infos.speaker;\n });\n }\n\n get selectedSpeaker() {\n return this._selectedSpeaker;\n }\n\n enableMic(enable: boolean) {\n this._daily.setLocalAudio(enable);\n }\n\n get isMicEnabled() {\n return this._daily.localAudio();\n }\n\n enableCam(enable: boolean) {\n this._daily.setLocalVideo(enable);\n }\n\n get isCamEnabled() {\n return this._daily.localVideo();\n }\n\n public enableScreenShare(enable: boolean) {\n if (enable) {\n this._daily.startScreenShare();\n } else {\n this._daily.stopScreenShare();\n }\n }\n\n public get isSharingScreen(): boolean {\n return this._daily.localScreenAudio() || this._daily.localScreenVideo();\n }\n\n tracks() {\n const participants = this._daily.participants() ?? {};\n const bot = participants?.[this._botId];\n\n const tracks: Tracks = {\n local: {\n audio: participants?.local?.tracks?.audio?.persistentTrack,\n screenAudio: participants?.local?.tracks?.screenAudio?.persistentTrack,\n screenVideo: participants?.local?.tracks?.screenVideo?.persistentTrack,\n video: participants?.local?.tracks?.video?.persistentTrack,\n },\n };\n\n if (bot) {\n tracks.bot = {\n audio: bot?.tracks?.audio?.persistentTrack,\n video: bot?.tracks?.video?.persistentTrack,\n };\n }\n\n return tracks;\n }\n\n private async startRecording(): Promise<void> {\n try {\n logger.info(\"[RTVI Transport] Initializing recording\");\n await this._mediaStreamRecorder.record((data) => {\n this.handleUserAudioStream(data.mono);\n }, DailyTransport.RECORDER_CHUNK_SIZE);\n this._onMessage({\n type: DailyRTVIMessageType.AUDIO_BUFFERING_STARTED,\n data: {},\n } as RTVIMessage);\n logger.info(\"[RTVI Transport] Recording Initialized\");\n } catch (e) {\n const err = e as Error;\n if (!err.message.includes(\"Already recording\")) {\n logger.error(\"Error starting recording\", e);\n }\n }\n }\n\n async preAuth(dailyFactoryOptions: DailyFactoryOptions) {\n this._dailyFactoryOptions = dailyFactoryOptions;\n await this._daily.preAuth(dailyFactoryOptions);\n }\n\n async initDevices() {\n if (!this._daily) {\n throw new RTVIError(\"Transport instance not initialized\");\n }\n\n this.state = \"initializing\";\n\n const infos = await this._daily.startCamera();\n const { devices } = await this._daily.enumerateDevices();\n const cams = devices.filter((d) => d.kind === \"videoinput\");\n const mics = devices.filter((d) => d.kind === \"audioinput\");\n const speakers = devices.filter((d) => d.kind === \"audiooutput\");\n this._selectedCam = infos.camera;\n this._selectedMic = infos.mic;\n this._selectedSpeaker = infos.speaker;\n\n this._callbacks.onAvailableCamsUpdated?.(cams);\n this._callbacks.onAvailableMicsUpdated?.(mics);\n this._callbacks.onAvailableSpeakersUpdated?.(speakers);\n this._callbacks.onCamUpdated?.(infos.camera as MediaDeviceInfo);\n this._callbacks.onMicUpdated?.(infos.mic as MediaDeviceInfo);\n this._callbacks.onSpeakerUpdated?.(infos.speaker as MediaDeviceInfo);\n\n // Instantiate audio observers\n if (!this._daily.isLocalAudioLevelObserverRunning())\n await this._daily.startLocalAudioLevelObserver(100);\n if (!this._daily.isRemoteParticipantsAudioLevelObserverRunning())\n await this._daily.startRemoteParticipantsAudioLevelObserver(100);\n\n this.state = \"initialized\";\n }\n\n async connect(\n authBundle: DailyTransportAuthBundle,\n abortController: AbortController\n ) {\n if (!this._daily) {\n throw new RTVIError(\"Transport instance not initialized\");\n }\n\n if (abortController.signal.aborted) return;\n\n this.state = \"connecting\";\n\n const opts = this._dailyFactoryOptions;\n opts.url = authBundle.room_url ?? opts.url;\n if (authBundle.token != null) {\n opts.token = authBundle.token;\n }\n try {\n await this._daily.join(opts);\n\n const room = await this._daily.room();\n if (room && \"id\" in room) {\n this._expiry = room.config?.exp;\n }\n } catch (e) {\n logger.error(\"Failed to join room\", e);\n this.state = \"error\";\n throw new TransportStartError();\n }\n\n if (abortController.signal.aborted) return;\n\n this.state = \"connected\";\n\n this._callbacks.onConnected?.();\n }\n\n async sendReadyMessage(): Promise<void> {\n return new Promise<void>((resolve) => {\n (async () => {\n const readyHandler = (ev: DailyEventObjectTrack) => {\n if (!ev.participant?.local) {\n this.state = \"ready\";\n this.flushAudioQueue();\n this.sendMessage(RTVIMessage.clientReady());\n this.stopRecording();\n this._daily.off(\"track-started\", readyHandler);\n resolve();\n }\n };\n this._daily.on(\"track-started\", readyHandler);\n })();\n });\n }\n\n private stopRecording() {\n if (\n this._mediaStreamRecorder &&\n this._mediaStreamRecorder.getStatus() !== \"ended\"\n ) {\n // disconnecting, we don't need to record anymore\n void this._mediaStreamRecorder.end();\n this._onMessage({\n type: DailyRTVIMessageType.AUDIO_BUFFERING_STOPPED,\n data: {},\n } as RTVIMessage);\n }\n }\n\n private attachEventListeners() {\n this._daily.on(\n \"available-devices-updated\",\n this.handleAvailableDevicesUpdated.bind(this)\n );\n this._daily.on(\n \"selected-devices-updated\",\n this.handleSelectedDevicesUpdated.bind(this)\n );\n\n this._daily.on(\"track-started\", this.handleTrackStarted.bind(this));\n this._daily.on(\"track-stopped\", this.handleTrackStopped.bind(this));\n this._daily.on(\n \"participant-joined\",\n this.handleParticipantJoined.bind(this)\n );\n this._daily.on(\"participant-left\", this.handleParticipantLeft.bind(this));\n this._daily.on(\"local-audio-level\", this.handleLocalAudioLevel.bind(this));\n this._daily.on(\n \"remote-participants-audio-level\",\n this.handleRemoteAudioLevel.bind(this)\n );\n this._daily.on(\"app-message\", this.handleAppMessage.bind(this));\n this._daily.on(\"left-meeting\", this.handleLeftMeeting.bind(this));\n this._daily.on(\"error\", this.handleFatalError.bind(this));\n this._daily.on(\"nonfatal-error\", this.handleNonFatalError.bind(this));\n }\n\n async disconnect() {\n this.state = \"disconnecting\";\n this._daily.stopLocalAudioLevelObserver();\n this._daily.stopRemoteParticipantsAudioLevelObserver();\n\n this._audioQueue = [];\n this._currentAudioTrack = null;\n this.stopRecording();\n\n await this._daily.leave();\n }\n\n public sendMessage(message: RTVIMessage) {\n this._daily.sendAppMessage(message, \"*\");\n }\n\n private handleAppMessage(ev: DailyEventObjectAppMessage) {\n // Bubble any messages with rtvi-ai label\n if (ev.data.label === \"rtvi-ai\") {\n this._onMessage({\n id: ev.data.id,\n type: ev.data.type,\n data: ev.data.data,\n } as RTVIMessage);\n }\n }\n\n private handleAvailableDevicesUpdated(\n ev: DailyEventObjectAvailableDevicesUpdated\n ) {\n this._callbacks.onAvailableCamsUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"videoinput\")\n );\n this._callbacks.onAvailableMicsUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"audioinput\")\n );\n this._callbacks.onAvailableSpeakersUpdated?.(\n ev.availableDevices.filter((d) => d.kind === \"audiooutput\")\n );\n }\n\n private handleSelectedDevicesUpdated(\n ev: DailyEventObjectSelectedDevicesUpdated\n ) {\n if (this._selectedCam?.deviceId !== ev.devices.camera) {\n this._selectedCam = ev.devices.camera;\n this._callbacks.onCamUpdated?.(ev.devices.camera as MediaDeviceInfo);\n }\n if (this._selectedMic?.deviceId !== ev.devices.mic) {\n this._selectedMic = ev.devices.mic;\n this._callbacks.onMicUpdated?.(ev.devices.mic as MediaDeviceInfo);\n }\n if (this._selectedSpeaker?.deviceId !== ev.devices.speaker) {\n this._selectedSpeaker = ev.devices.speaker;\n this._callbacks.onSpeakerUpdated?.(ev.devices.speaker as MediaDeviceInfo);\n }\n }\n\n private async handleLocalAudioTrack(track: MediaStreamTrack) {\n if (this.state == \"ready\" || !this._bufferLocalAudioUntilBotReady) {\n return;\n }\n const status = this._mediaStreamRecorder.getStatus();\n switch (status) {\n case \"ended\":\n await this._mediaStreamRecorder.begin(track);\n await this.startRecording();\n break;\n case \"paused\":\n await this.startRecording();\n break;\n case \"recording\":\n default:\n if (this._currentAudioTrack !== track) {\n await this._mediaStreamRecorder.end();\n await this._mediaStreamRecorder.begin(track);\n await this.startRecording();\n } else {\n logger.warn(\n \"track-started event received for current track and already recording\"\n );\n }\n break;\n }\n this._currentAudioTrack = track;\n }\n\n private handleTrackStarted(ev: DailyEventObjectTrack) {\n if (ev.type === \"screenAudio\" || ev.type === \"screenVideo\") {\n this._callbacks.onScreenTrackStarted?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n } else {\n if (ev.participant?.local && ev.track.kind === \"audio\") {\n void this.handleLocalAudioTrack(ev.track);\n }\n this._callbacks.onTrackStarted?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n }\n }\n\n private handleTrackStopped(ev: DailyEventObjectTrack) {\n if (ev.type === \"screenAudio\" || ev.type === \"screenVideo\") {\n this._callbacks.onScreenTrackStopped?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n } else {\n this._callbacks.onTrackStopped?.(\n ev.track,\n ev.participant\n ? dailyParticipantToParticipant(ev.participant)\n : undefined\n );\n }\n }\n\n private handleParticipantJoined(ev: DailyEventObjectParticipant) {\n const p = dailyParticipantToParticipant(ev.participant);\n\n this._callbacks.onParticipantJoined?.(p);\n\n if (p.local) return;\n\n this._botId = ev.participant.session_id;\n\n this._callbacks.onBotConnected?.(p);\n }\n\n private handleParticipantLeft(ev: DailyEventObjectParticipantLeft) {\n const p = dailyParticipantToParticipant(ev.participant);\n\n this._callbacks.onParticipantLeft?.(p);\n\n if (p.local) return;\n\n this._botId = \"\";\n\n this._callbacks.onBotDisconnected?.(p);\n }\n\n private handleLocalAudioLevel(ev: DailyEventObjectLocalAudioLevel) {\n this._callbacks.onLocalAudioLevel?.(ev.audioLevel);\n }\n\n private handleRemoteAudioLevel(\n ev: DailyEventObjectRemoteParticipantsAudioLevel\n ) {\n const participants = this._daily.participants();\n const ids = Object.keys(ev.participantsAudioLevel);\n for (let i = 0; i < ids.length; i++) {\n const id = ids[i];\n const level = ev.participantsAudioLevel[id];\n this._callbacks.onRemoteAudioLevel?.(\n level,\n dailyParticipantToParticipant(participants[id])\n );\n }\n }\n\n private handleLeftMeeting() {\n this.state = \"disconnected\";\n this._botId = \"\";\n this._callbacks.onDisconnected?.();\n }\n\n private handleFatalError(ev: DailyEventObjectFatalError) {\n logger.error(\"Daily fatal error\", ev.errorMsg);\n this.state = \"error\";\n this._botId = \"\";\n this._callbacks.onError?.(RTVIMessage.error(ev.errorMsg, true));\n }\n\n private handleNonFatalError(ev: DailyEventObjectNonFatalError) {\n switch (ev.type) {\n case \"screen-share-error\":\n this._callbacks.onScreenShareError?.(ev.errorMsg);\n break;\n }\n }\n}\n\nconst dailyParticipantToParticipant = (p: DailyParticipant): Participant => ({\n id: p.user_id,\n local: p.local,\n name: p.user_name,\n});\n","import { WavPacker } from './lib/wav_packer.js';\nimport { AudioAnalysis } from './lib/analysis/audio_analysis.js';\nimport { WavStreamPlayer } from './lib/wav_stream_player.js';\nimport { WavRecorder } from './lib/wav_recorder.js';\nimport { MediaStreamRecorder } from './lib/mediastream_recorder.js';\n\nexport {\n AudioAnalysis,\n MediaStreamRecorder,\n WavPacker,\n WavStreamPlayer,\n WavRecorder,\n};\n","/**\n * Raw wav audio file contents\n * @typedef {Object} WavPackerAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {number} channelCount\n * @property {number} sampleRate\n * @property {number} duration\n */\n\n/**\n * Utility class for assembling PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavPacker {\n /**\n * Converts Float32Array of amplitude data to ArrayBuffer in Int16Array format\n * @param {Float32Array} float32Array\n * @returns {ArrayBuffer}\n */\n static floatTo16BitPCM(float32Array) {\n const buffer = new ArrayBuffer(float32Array.length * 2);\n const view = new DataView(buffer);\n let offset = 0;\n for (let i = 0; i < float32Array.length; i++, offset += 2) {\n let s = Math.max(-1, Math.min(1, float32Array[i]));\n view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n }\n return buffer;\n }\n\n /**\n * Concatenates two ArrayBuffers\n * @param {ArrayBuffer} leftBuffer\n * @param {ArrayBuffer} rightBuffer\n * @returns {ArrayBuffer}\n */\n static mergeBuffers(leftBuffer, rightBuffer) {\n const tmpArray = new Uint8Array(\n leftBuffer.byteLength + rightBuffer.byteLength\n );\n tmpArray.set(new Uint8Array(leftBuffer), 0);\n tmpArray.set(new Uint8Array(rightBuffer), leftBuffer.byteLength);\n return tmpArray.buffer;\n }\n\n /**\n * Packs data into an Int16 format\n * @private\n * @param {number} size 0 = 1x Int16, 1 = 2x Int16\n * @param {number} arg value to pack\n * @returns\n */\n _packData(size, arg) {\n return [\n new Uint8Array([arg, arg >> 8]),\n new Uint8Array([arg, arg >> 8, arg >> 16, arg >> 24]),\n ][size];\n }\n\n /**\n * Packs audio into \"audio/wav\" Blob\n * @param {number} sampleRate\n * @param {{bitsPerSample: number, channels: Array<Float32Array>, data: Int16Array}} audio\n * @returns {WavPackerAudioType}\n */\n pack(sampleRate, audio) {\n if (!audio?.bitsPerSample) {\n throw new Error(`Missing \"bitsPerSample\"`);\n } else if (!audio?.channels) {\n throw new Error(`Missing \"channels\"`);\n } else if (!audio?.data) {\n throw new Error(`Missing \"data\"`);\n }\n const { bitsPerSample, channels, data } = audio;\n const output = [\n // Header\n 'RIFF',\n this._packData(\n 1,\n 4 + (8 + 24) /* chunk 1 length */ + (8 + 8) /* chunk 2 length */\n ), // Length\n 'WAVE',\n // chunk 1\n 'fmt ', // Sub-chunk identifier\n this._packData(1, 16), // Chunk length\n this._packData(0, 1), // Audio format (1 is linear quantization)\n this._packData(0, channels.length),\n this._packData(1, sampleRate),\n this._packData(1, (sampleRate * channels.length * bitsPerSample) / 8), // Byte rate\n this._packData(0, (channels.length * bitsPerSample) / 8),\n this._packData(0, bitsPerSample),\n // chunk 2\n 'data', // Sub-chunk identifier\n this._packData(\n 1,\n (channels[0].length * channels.length * bitsPerSample) / 8\n ), // Chunk length\n data,\n ];\n const blob = new Blob(output, { type: 'audio/mpeg' });\n const url = URL.createObjectURL(blob);\n return {\n blob,\n url,\n channelCount: channels.length,\n sampleRate,\n duration: data.byteLength / (channels.length * sampleRate * 2),\n };\n }\n}\n\nglobalThis.WavPacker = WavPacker;\n","import {\n noteFrequencies,\n noteFrequencyLabels,\n voiceFrequencies,\n voiceFrequencyLabels,\n} from './constants.js';\n\n/**\n * Output of AudioAnalysis for the frequency domain of the audio\n * @typedef {Object} AudioAnalysisOutputType\n * @property {Float32Array} values Amplitude of this frequency between {0, 1} inclusive\n * @property {number[]} frequencies Raw frequency bucket values\n * @property {string[]} labels Labels for the frequency bucket values\n */\n\n/**\n * Analyzes audio for visual output\n * @class\n */\nexport class AudioAnalysis {\n /**\n * Retrieves frequency domain data from an AnalyserNode adjusted to a decibel range\n * returns human-readable formatting and labels\n * @param {AnalyserNode} analyser\n * @param {number} sampleRate\n * @param {Float32Array} [fftResult]\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {AudioAnalysisOutputType}\n */\n static getFrequencies(\n analyser,\n sampleRate,\n fftResult,\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30,\n ) {\n if (!fftResult) {\n fftResult = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(fftResult);\n }\n const nyquistFrequency = sampleRate / 2;\n const frequencyStep = (1 / fftResult.length) * nyquistFrequency;\n let outputValues;\n let frequencies;\n let labels;\n if (analysisType === 'music' || analysisType === 'voice') {\n const useFrequencies =\n analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n const aggregateOutput = Array(useFrequencies.length).fill(minDecibels);\n for (let i = 0; i < fftResult.length; i++) {\n const frequency = i * frequencyStep;\n const amplitude = fftResult[i];\n for (let n = useFrequencies.length - 1; n >= 0; n--) {\n if (frequency > useFrequencies[n]) {\n aggregateOutput[n] = Math.max(aggregateOutput[n], amplitude);\n break;\n }\n }\n }\n outputValues = aggregateOutput;\n frequencies =\n analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n labels =\n analysisType === 'voice' ? voiceFrequencyLabels : noteFrequencyLabels;\n } else {\n outputValues = Array.from(fftResult);\n frequencies = outputValues.map((_, i) => frequencyStep * i);\n labels = frequencies.map((f) => `${f.toFixed(2)} Hz`);\n }\n // We normalize to {0, 1}\n const normalizedOutput = outputValues.map((v) => {\n return Math.max(\n 0,\n Math.min((v - minDecibels) / (maxDecibels - minDecibels), 1),\n );\n });\n const values = new Float32Array(normalizedOutput);\n return {\n values,\n frequencies,\n labels,\n };\n }\n\n /**\n * Creates a new AudioAnalysis instance for an HTMLAudioElement\n * @param {HTMLAudioElement} audioElement\n * @param {AudioBuffer|null} [audioBuffer] If provided, will cache all frequency domain data from the buffer\n * @returns {AudioAnalysis}\n */\n constructor(audioElement, audioBuffer = null) {\n this.fftResults = [];\n if (audioBuffer) {\n /**\n * Modified from\n * https://stackoverflow.com/questions/75063715/using-the-web-audio-api-to-analyze-a-song-without-playing\n *\n * We do this to populate FFT values for the audio if provided an `audioBuffer`\n * The reason to do this is that Safari fails when using `createMediaElementSource`\n * This has a non-zero RAM cost so we only opt-in to run it on Safari, Chrome is better\n */\n const { length, sampleRate } = audioBuffer;\n const offlineAudioContext = new OfflineAudioContext({\n length,\n sampleRate,\n });\n const source = offlineAudioContext.createBufferSource();\n source.buffer = audioBuffer;\n const analyser = offlineAudioContext.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n source.connect(analyser);\n // limit is :: 128 / sampleRate;\n // but we just want 60fps - cuts ~1s from 6MB to 1MB of RAM\n const renderQuantumInSeconds = 1 / 60;\n const durationInSeconds = length / sampleRate;\n const analyze = (index) => {\n const suspendTime = renderQuantumInSeconds * index;\n if (suspendTime < durationInSeconds) {\n offlineAudioContext.suspend(suspendTime).then(() => {\n const fftResult = new Float32Array(analyser.frequencyBinCount);\n analyser.getFloatFrequencyData(fftResult);\n this.fftResults.push(fftResult);\n analyze(index + 1);\n });\n }\n if (index === 1) {\n offlineAudioContext.startRendering();\n } else {\n offlineAudioContext.resume();\n }\n };\n source.start(0);\n analyze(1);\n this.audio = audioElement;\n this.context = offlineAudioContext;\n this.analyser = analyser;\n this.sampleRate = sampleRate;\n this.audioBuffer = audioBuffer;\n } else {\n const audioContext = new AudioContext();\n const track = audioContext.createMediaElementSource(audioElement);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n track.connect(analyser);\n analyser.connect(audioContext.destination);\n this.audio = audioElement;\n this.context = audioContext;\n this.analyser = analyser;\n this.sampleRate = this.context.sampleRate;\n this.audioBuffer = null;\n }\n }\n\n /**\n * Gets the current frequency domain data from the playing audio track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30,\n ) {\n let fftResult = null;\n if (this.audioBuffer && this.fftResults.length) {\n const pct = this.audio.currentTime / this.audio.duration;\n const index = Math.min(\n (pct * this.fftResults.length) | 0,\n this.fftResults.length - 1,\n );\n fftResult = this.fftResults[index];\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n fftResult,\n analysisType,\n minDecibels,\n maxDecibels,\n );\n }\n\n /**\n * Resume the internal AudioContext if it was suspended due to the lack of\n * user interaction when the AudioAnalysis was instantiated.\n * @returns {Promise<true>}\n */\n async resumeIfSuspended() {\n if (this.context.state === 'suspended') {\n await this.context.resume();\n }\n return true;\n }\n}\n\nglobalThis.AudioAnalysis = AudioAnalysis;\n","/**\n * Constants for help with visualization\n * Helps map frequency ranges from Fast Fourier Transform\n * to human-interpretable ranges, notably music ranges and\n * human vocal ranges.\n */\n\n// Eighth octave frequencies\nconst octave8Frequencies = [\n 4186.01, 4434.92, 4698.63, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93,\n 6644.88, 7040.0, 7458.62, 7902.13,\n];\n\n// Labels for each of the above frequencies\nconst octave8FrequencyLabels = [\n 'C',\n 'C#',\n 'D',\n 'D#',\n 'E',\n 'F',\n 'F#',\n 'G',\n 'G#',\n 'A',\n 'A#',\n 'B',\n];\n\n/**\n * All note frequencies from 1st to 8th octave\n * in format \"A#8\" (A#, 8th octave)\n */\nexport const noteFrequencies = [];\nexport const noteFrequencyLabels = [];\nfor (let i = 1; i <= 8; i++) {\n for (let f = 0; f < octave8Frequencies.length; f++) {\n const freq = octave8Frequencies[f];\n noteFrequencies.push(freq / Math.pow(2, 8 - i));\n noteFrequencyLabels.push(octave8FrequencyLabels[f] + i);\n }\n}\n\n/**\n * Subset of the note frequencies between 32 and 2000 Hz\n * 6 octave range: C1 to B6\n */\nconst voiceFrequencyRange = [32.0, 2000.0];\nexport const voiceFrequencies = noteFrequencies.filter((_, i) => {\n return (\n noteFrequencies[i] > voiceFrequencyRange[0] &&\n noteFrequencies[i] < voiceFrequencyRange[1]\n );\n});\nexport const voiceFrequencyLabels = noteFrequencyLabels.filter((_, i) => {\n return (\n noteFrequencies[i] > voiceFrequencyRange[0] &&\n noteFrequencies[i] < voiceFrequencyRange[1]\n );\n});\n","import { StreamProcessorSrc } from \"./worklets/stream_processor.js\";\nimport { AudioAnalysis } from \"./analysis/audio_analysis.js\";\n\n/**\n * Plays audio streams received in raw PCM16 chunks from the browser\n * @class\n */\nexport class WavStreamPlayer {\n /**\n * Creates a new WavStreamPlayer instance\n * @param {{sampleRate?: number}} options\n * @returns {WavStreamPlayer}\n */\n constructor({ sampleRate = 44100 } = {}) {\n this.scriptSrc = StreamProcessorSrc;\n this.sampleRate = sampleRate;\n this.context = null;\n this.stream = null;\n this.analyser = null;\n this.trackSampleOffsets = {};\n this.interruptedTrackIds = {};\n }\n\n /**\n * Connects the audio context and enables output to speakers\n * @returns {Promise<true>}\n */\n async connect() {\n this.context = new AudioContext({ sampleRate: this.sampleRate });\n if (this._speakerID) {\n this.context.setSinkId(this._speakerID);\n }\n if (this.context.state === \"suspended\") {\n await this.context.resume();\n }\n try {\n await this.context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const analyser = this.context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n this.analyser = analyser;\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the playing track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = \"frequency\",\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.analyser) {\n throw new Error(\"Not connected, please call .connect() first\");\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * @param {string} speaker deviceId\n */\n async updateSpeaker(speaker) {\n const _prevSpeaker = this._speakerID;\n this._speakerID = speaker;\n if (this.context) {\n try {\n if (speaker === \"default\") {\n await this.context.setSinkId();\n } else {\n await this.context.setSinkId(speaker);\n }\n } catch (e) {\n console.error(`Could not set sinkId to ${speaker}: ${e}`);\n this._speakerID = _prevSpeaker;\n }\n }\n }\n\n /**\n * Starts audio streaming\n * @private\n * @returns {Promise<true>}\n */\n _start() {\n const streamNode = new AudioWorkletNode(this.context, \"stream_processor\");\n streamNode.connect(this.context.destination);\n streamNode.port.onmessage = (e) => {\n const { event } = e.data;\n if (event === \"stop\") {\n streamNode.disconnect();\n this.stream = null;\n } else if (event === \"offset\") {\n const { requestId, trackId, offset } = e.data;\n const currentTime = offset / this.sampleRate;\n this.trackSampleOffsets[requestId] = { trackId, offset, currentTime };\n }\n };\n this.analyser.disconnect();\n streamNode.connect(this.analyser);\n this.stream = streamNode;\n return true;\n }\n\n /**\n * Adds 16BitPCM data to the currently playing audio stream\n * You can add chunks beyond the current play point and they will be queued for play\n * @param {ArrayBuffer|Int16Array} arrayBuffer\n * @param {string} [trackId]\n * @returns {Int16Array}\n */\n add16BitPCM(arrayBuffer, trackId = \"default\") {\n if (typeof trackId !== \"string\") {\n throw new Error(`trackId must be a string`);\n } else if (this.interruptedTrackIds[trackId]) {\n return;\n }\n if (!this.stream) {\n this._start();\n }\n let buffer;\n if (arrayBuffer instanceof Int16Array) {\n buffer = arrayBuffer;\n } else if (arrayBuffer instanceof ArrayBuffer) {\n buffer = new Int16Array(arrayBuffer);\n } else {\n throw new Error(`argument must be Int16Array or ArrayBuffer`);\n }\n this.stream.port.postMessage({ event: \"write\", buffer, trackId });\n return buffer;\n }\n\n /**\n * Gets the offset (sample count) of the currently playing stream\n * @param {boolean} [interrupt]\n * @returns {{trackId: string|null, offset: number, currentTime: number}}\n */\n async getTrackSampleOffset(interrupt = false) {\n if (!this.stream) {\n return null;\n }\n const requestId = crypto.randomUUID();\n this.stream.port.postMessage({\n event: interrupt ? \"interrupt\" : \"offset\",\n requestId,\n });\n let trackSampleOffset;\n while (!trackSampleOffset) {\n trackSampleOffset = this.trackSampleOffsets[requestId];\n await new Promise((r) => setTimeout(() => r(), 1));\n }\n const { trackId } = trackSampleOffset;\n if (interrupt && trackId) {\n this.interruptedTrackIds[trackId] = true;\n }\n return trackSampleOffset;\n }\n\n /**\n * Strips the current stream and returns the sample offset of the audio\n * @param {boolean} [interrupt]\n * @returns {{trackId: string|null, offset: number, currentTime: number}}\n */\n async interrupt() {\n return this.getTrackSampleOffset(true);\n }\n}\n\nglobalThis.WavStreamPlayer = WavStreamPlayer;\n","export const StreamProcessorWorklet = `\nclass StreamProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.hasStarted = false;\n this.hasInterrupted = false;\n this.outputBuffers = [];\n this.bufferLength = 128;\n this.write = { buffer: new Float32Array(this.bufferLength), trackId: null };\n this.writeOffset = 0;\n this.trackSampleOffsets = {};\n this.port.onmessage = (event) => {\n if (event.data) {\n const payload = event.data;\n if (payload.event === 'write') {\n const int16Array = payload.buffer;\n const float32Array = new Float32Array(int16Array.length);\n for (let i = 0; i < int16Array.length; i++) {\n float32Array[i] = int16Array[i] / 0x8000; // Convert Int16 to Float32\n }\n this.writeData(float32Array, payload.trackId);\n } else if (\n payload.event === 'offset' ||\n payload.event === 'interrupt'\n ) {\n const requestId = payload.requestId;\n const trackId = this.write.trackId;\n const offset = this.trackSampleOffsets[trackId] || 0;\n this.port.postMessage({\n event: 'offset',\n requestId,\n trackId,\n offset,\n });\n if (payload.event === 'interrupt') {\n this.hasInterrupted = true;\n }\n } else {\n throw new Error(\\`Unhandled event \"\\${payload.event}\"\\`);\n }\n }\n };\n }\n\n writeData(float32Array, trackId = null) {\n let { buffer } = this.write;\n let offset = this.writeOffset;\n for (let i = 0; i < float32Array.length; i++) {\n buffer[offset++] = float32Array[i];\n if (offset >= buffer.length) {\n this.outputBuffers.push(this.write);\n this.write = { buffer: new Float32Array(this.bufferLength), trackId };\n buffer = this.write.buffer;\n offset = 0;\n }\n }\n this.writeOffset = offset;\n return true;\n }\n\n process(inputs, outputs, parameters) {\n const output = outputs[0];\n const outputChannelData = output[0];\n const outputBuffers = this.outputBuffers;\n if (this.hasInterrupted) {\n this.port.postMessage({ event: 'stop' });\n return false;\n } else if (outputBuffers.length) {\n this.hasStarted = true;\n const { buffer, trackId } = outputBuffers.shift();\n for (let i = 0; i < outputChannelData.length; i++) {\n outputChannelData[i] = buffer[i] || 0;\n }\n if (trackId) {\n this.trackSampleOffsets[trackId] =\n this.trackSampleOffsets[trackId] || 0;\n this.trackSampleOffsets[trackId] += buffer.length;\n }\n return true;\n } else if (this.hasStarted) {\n this.port.postMessage({ event: 'stop' });\n return false;\n } else {\n return true;\n }\n }\n}\n\nregisterProcessor('stream_processor', StreamProcessor);\n`;\n\nconst script = new Blob([StreamProcessorWorklet], {\n type: 'application/javascript',\n});\nconst src = URL.createObjectURL(script);\nexport const StreamProcessorSrc = src;\n","import { AudioProcessorSrc } from './worklets/audio_processor.js';\nimport { AudioAnalysis } from './analysis/audio_analysis.js';\nimport { WavPacker } from './wav_packer.js';\n\n/**\n * Decodes audio into a wav file\n * @typedef {Object} DecodedAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {Float32Array} values\n * @property {AudioBuffer} audioBuffer\n */\n\n/**\n * Records live stream of user audio as PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavRecorder {\n /**\n * Create a new WavRecorder instance\n * @param {{sampleRate?: number, outputToSpeakers?: boolean, debug?: boolean}} [options]\n * @returns {WavRecorder}\n */\n constructor({\n sampleRate = 44100,\n outputToSpeakers = false,\n debug = false,\n } = {}) {\n // Script source\n this.scriptSrc = AudioProcessorSrc;\n // Config\n this.sampleRate = sampleRate;\n this.outputToSpeakers = outputToSpeakers;\n this.debug = !!debug;\n this._deviceChangeCallback = null;\n this._devices = [];\n this.deviceSelection = null;\n // State variables\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n this.recording = false;\n // Event handling with AudioWorklet\n this._lastEventId = 0;\n this.eventReceipts = {};\n this.eventTimeout = 5000;\n // Process chunks of audio\n this._chunkProcessor = () => {};\n this._chunkProcessorSize = void 0;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n\n /**\n * Decodes audio data from multiple formats to a Blob, url, Float32Array and AudioBuffer\n * @param {Blob|Float32Array|Int16Array|ArrayBuffer|number[]} audioData\n * @param {number} sampleRate\n * @param {number} fromSampleRate\n * @returns {Promise<DecodedAudioType>}\n */\n static async decode(audioData, sampleRate = 44100, fromSampleRate = -1) {\n const context = new AudioContext({ sampleRate });\n let arrayBuffer;\n let blob;\n if (audioData instanceof Blob) {\n if (fromSampleRate !== -1) {\n throw new Error(\n `Can not specify \"fromSampleRate\" when reading from Blob`\n );\n }\n blob = audioData;\n arrayBuffer = await blob.arrayBuffer();\n } else if (audioData instanceof ArrayBuffer) {\n if (fromSampleRate !== -1) {\n throw new Error(\n `Can not specify \"fromSampleRate\" when reading from ArrayBuffer`\n );\n }\n arrayBuffer = audioData;\n blob = new Blob([arrayBuffer], { type: 'audio/wav' });\n } else {\n let float32Array;\n let data;\n if (audioData instanceof Int16Array) {\n data = audioData;\n float32Array = new Float32Array(audioData.length);\n for (let i = 0; i < audioData.length; i++) {\n float32Array[i] = audioData[i] / 0x8000;\n }\n } else if (audioData instanceof Float32Array) {\n float32Array = audioData;\n } else if (audioData instanceof Array) {\n float32Array = new Float32Array(audioData);\n } else {\n throw new Error(\n `\"audioData\" must be one of: Blob, Float32Arrray, Int16Array, ArrayBuffer, Array<number>`\n );\n }\n if (fromSampleRate === -1) {\n throw new Error(\n `Must specify \"fromSampleRate\" when reading from Float32Array, In16Array or Array`\n );\n } else if (fromSampleRate < 3000) {\n throw new Error(`Minimum \"fromSampleRate\" is 3000 (3kHz)`);\n }\n if (!data) {\n data = WavPacker.floatTo16BitPCM(float32Array);\n }\n const audio = {\n bitsPerSample: 16,\n channels: [float32Array],\n data,\n };\n const packer = new WavPacker();\n const result = packer.pack(fromSampleRate, audio);\n blob = result.blob;\n arrayBuffer = await blob.arrayBuffer();\n }\n const audioBuffer = await context.decodeAudioData(arrayBuffer);\n const values = audioBuffer.getChannelData(0);\n const url = URL.createObjectURL(blob);\n return {\n blob,\n url,\n values,\n audioBuffer,\n };\n }\n\n /**\n * Logs data in debug mode\n * @param {...any} arguments\n * @returns {true}\n */\n log() {\n if (this.debug) {\n this.log(...arguments);\n }\n return true;\n }\n\n /**\n * Retrieves the current sampleRate for the recorder\n * @returns {number}\n */\n getSampleRate() {\n return this.sampleRate;\n }\n\n /**\n * Retrieves the current status of the recording\n * @returns {\"ended\"|\"paused\"|\"recording\"}\n */\n getStatus() {\n if (!this.processor) {\n return 'ended';\n } else if (!this.recording) {\n return 'paused';\n } else {\n return 'recording';\n }\n }\n\n /**\n * Sends an event to the AudioWorklet\n * @private\n * @param {string} name\n * @param {{[key: string]: any}} data\n * @param {AudioWorkletNode} [_processor]\n * @returns {Promise<{[key: string]: any}>}\n */\n async _event(name, data = {}, _processor = null) {\n _processor = _processor || this.processor;\n if (!_processor) {\n throw new Error('Can not send events without recording first');\n }\n const message = {\n event: name,\n id: this._lastEventId++,\n data,\n };\n _processor.port.postMessage(message);\n const t0 = new Date().valueOf();\n while (!this.eventReceipts[message.id]) {\n if (new Date().valueOf() - t0 > this.eventTimeout) {\n throw new Error(`Timeout waiting for \"${name}\" event`);\n }\n await new Promise((res) => setTimeout(() => res(true), 1));\n }\n const payload = this.eventReceipts[message.id];\n delete this.eventReceipts[message.id];\n return payload;\n }\n\n /**\n * Sets device change callback, remove if callback provided is `null`\n * @param {(Array<MediaDeviceInfo & {default: boolean}>): void|null} callback\n * @returns {true}\n */\n listenForDeviceChange(callback) {\n if (callback === null && this._deviceChangeCallback) {\n navigator.mediaDevices.removeEventListener(\n 'devicechange',\n this._deviceChangeCallback\n );\n this._deviceChangeCallback = null;\n } else if (callback !== null) {\n // Basically a debounce; we only want this called once when devices change\n // And we only want the most recent callback() to be executed\n // if a few are operating at the same time\n let lastId = 0;\n let lastDevices = [];\n const serializeDevices = (devices) =>\n devices\n .map((d) => d.deviceId)\n .sort()\n .join(',');\n const cb = async () => {\n let id = ++lastId;\n const devices = await this.listDevices();\n if (id === lastId) {\n if (serializeDevices(lastDevices) !== serializeDevices(devices)) {\n lastDevices = devices;\n callback(devices.slice());\n }\n }\n };\n navigator.mediaDevices.addEventListener('devicechange', cb);\n cb();\n this._deviceChangeCallback = cb;\n }\n return true;\n }\n\n /**\n * Manually request permission to use the microphone\n * @returns {Promise<true>}\n */\n async requestPermission() {\n const permissionStatus = await navigator.permissions.query({\n name: 'microphone',\n });\n if (permissionStatus.state === 'denied') {\n window.alert('You must grant microphone access to use this feature.');\n } else if (permissionStatus.state === 'prompt') {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n const tracks = stream.getTracks();\n tracks.forEach((track) => track.stop());\n } catch (e) {\n window.alert('You must grant microphone access to use this feature.');\n }\n }\n return true;\n }\n\n /**\n * List all eligible devices for recording, will request permission to use microphone\n * @returns {Promise<Array<MediaDeviceInfo & {default: boolean}>>}\n */\n async listDevices() {\n if (\n !navigator.mediaDevices ||\n !('enumerateDevices' in navigator.mediaDevices)\n ) {\n throw new Error('Could not request user devices');\n }\n await this.requestPermission();\n const devices = await navigator.mediaDevices.enumerateDevices();\n const audioDevices = devices.filter(\n (device) => device.kind === 'audioinput'\n );\n return audioDevices;\n // const defaultDeviceIndex = audioDevices.findIndex(\n // (device) => device.deviceId === 'default'\n // );\n // const deviceList = [];\n // if (defaultDeviceIndex !== -1) {\n // let defaultDevice = audioDevices.splice(defaultDeviceIndex, 1)[0];\n // let existingIndex = audioDevices.findIndex(\n // (device) => device.groupId === defaultDevice.groupId\n // );\n // if (existingIndex !== -1) {\n // defaultDevice = audioDevices.splice(existingIndex, 1)[0];\n // }\n // defaultDevice.default = true;\n // deviceList.push(defaultDevice);\n // }\n // return deviceList.concat(audioDevices);\n }\n\n /**\n * Begins a recording session and requests microphone permissions if not already granted\n * Microphone recording indicator will appear on browser tab but status will be \"paused\"\n * @param {string} [deviceId] if no device provided, default device will be used\n * @returns {Promise<true>}\n */\n async begin(deviceId) {\n if (this.processor) {\n throw new Error(\n `Already connected: please call .end() to start a new session`\n );\n }\n\n if (\n !navigator.mediaDevices ||\n !('getUserMedia' in navigator.mediaDevices)\n ) {\n throw new Error('Could not request user media');\n }\n deviceId = deviceId ?? this.deviceSelection?.deviceId;\n try {\n const config = { audio: true };\n if (deviceId) {\n config.audio = { deviceId: { exact: deviceId } };\n }\n this.stream = await navigator.mediaDevices.getUserMedia(config);\n } catch (err) {\n throw new Error('Could not start media stream');\n }\n\n this.listDevices().then((devices) => {\n deviceId = this.stream.getAudioTracks()[0].getSettings().deviceId;\n console.log(\n 'find current device',\n devices,\n deviceId,\n this.stream.getAudioTracks()[0].getSettings()\n );\n this.deviceSelection = devices.find((d) => d.deviceId === deviceId);\n console.log('current device', this.deviceSelection);\n });\n const context = new AudioContext({ sampleRate: this.sampleRate });\n const source = context.createMediaStreamSource(this.stream);\n // Load and execute the module script.\n try {\n await context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const processor = new AudioWorkletNode(context, 'audio_processor');\n processor.port.onmessage = (e) => {\n const { event, id, data } = e.data;\n if (event === 'receipt') {\n this.eventReceipts[id] = data;\n } else if (event === 'chunk') {\n if (this._chunkProcessorSize) {\n const buffer = this._chunkProcessorBuffer;\n this._chunkProcessorBuffer = {\n raw: WavPacker.mergeBuffers(buffer.raw, data.raw),\n mono: WavPacker.mergeBuffers(buffer.mono, data.mono),\n };\n if (\n this._chunkProcessorBuffer.mono.byteLength >=\n this._chunkProcessorSize\n ) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n } else {\n this._chunkProcessor(data);\n }\n }\n };\n\n const node = source.connect(processor);\n const analyser = context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n node.connect(analyser);\n if (this.outputToSpeakers) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Warning: Output to speakers may affect sound quality,\\n' +\n 'especially due to system audio feedback preventative measures.\\n' +\n 'use only for debugging'\n );\n analyser.connect(context.destination);\n }\n\n this.source = source;\n this.node = node;\n this.analyser = analyser;\n this.processor = processor;\n console.log('begin completed');\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the recording track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = 'frequency',\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * Pauses the recording\n * Keeps microphone stream open but halts storage of audio\n * @returns {Promise<true>}\n */\n async pause() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n } else if (!this.recording) {\n throw new Error('Already paused: please call .record() first');\n }\n if (this._chunkProcessorBuffer.raw.byteLength) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n }\n this.log('Pausing ...');\n await this._event('stop');\n this.recording = false;\n return true;\n }\n\n /**\n * Start recording stream and storing to memory from the connected audio source\n * @param {(data: { mono: Int16Array; raw: Int16Array }) => any} [chunkProcessor]\n * @param {number} [chunkSize] chunkProcessor will not be triggered until this size threshold met in mono audio\n * @returns {Promise<true>}\n */\n async record(chunkProcessor = () => {}, chunkSize = 8192) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n } else if (this.recording) {\n throw new Error('Already recording: please call .pause() first');\n } else if (typeof chunkProcessor !== 'function') {\n throw new Error(`chunkProcessor must be a function`);\n }\n this._chunkProcessor = chunkProcessor;\n this._chunkProcessorSize = chunkSize;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n this.log('Recording ...');\n await this._event('start');\n this.recording = true;\n return true;\n }\n\n /**\n * Clears the audio buffer, empties stored recording\n * @returns {Promise<true>}\n */\n async clear() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n await this._event('clear');\n return true;\n }\n\n /**\n * Reads the current audio stream data\n * @returns {Promise<{meanValues: Float32Array, channels: Array<Float32Array>}>}\n */\n async read() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n this.log('Reading ...');\n const result = await this._event('read');\n return result;\n }\n\n /**\n * Saves the current audio stream to a file\n * @param {boolean} [force] Force saving while still recording\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async save(force = false) {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n if (!force && this.recording) {\n throw new Error(\n 'Currently recording: please call .pause() first, or call .save(true) to force'\n );\n }\n this.log('Exporting ...');\n const exportData = await this._event('export');\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Ends the current recording session and saves the result\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async end() {\n if (!this.processor) {\n throw new Error('Session ended: please call .begin() first');\n }\n\n const _processor = this.processor;\n\n this.log('Stopping ...');\n await this._event('stop');\n this.recording = false;\n const tracks = this.stream.getTracks();\n tracks.forEach((track) => track.stop());\n\n this.log('Exporting ...');\n const exportData = await this._event('export', {}, _processor);\n\n this.processor.disconnect();\n this.source.disconnect();\n this.node.disconnect();\n this.analyser.disconnect();\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Performs a full cleanup of WavRecorder instance\n * Stops actively listening via microphone and removes existing listeners\n * @returns {Promise<true>}\n */\n async quit() {\n this.listenForDeviceChange(null);\n // we do not reset this on end so that selections persist across starts\n this.deviceSelection = null;\n if (this.processor) {\n await this.end();\n }\n return true;\n }\n}\n\nglobalThis.WavRecorder = WavRecorder;\n","const AudioProcessorWorklet = `\nclass AudioProcessor extends AudioWorkletProcessor {\n\n constructor() {\n super();\n this.port.onmessage = this.receive.bind(this);\n this.initialize();\n }\n\n initialize() {\n this.foundAudio = false;\n this.recording = false;\n this.chunks = [];\n }\n\n /**\n * Concatenates sampled chunks into channels\n * Format is chunk[Left[], Right[]]\n */\n readChannelData(chunks, channel = -1, maxChannels = 9) {\n let channelLimit;\n if (channel !== -1) {\n if (chunks[0] && chunks[0].length - 1 < channel) {\n throw new Error(\n \\`Channel \\${channel} out of range: max \\${chunks[0].length}\\`\n );\n }\n channelLimit = channel + 1;\n } else {\n channel = 0;\n channelLimit = Math.min(chunks[0] ? chunks[0].length : 1, maxChannels);\n }\n const channels = [];\n for (let n = channel; n < channelLimit; n++) {\n const length = chunks.reduce((sum, chunk) => {\n return sum + chunk[n].length;\n }, 0);\n const buffers = chunks.map((chunk) => chunk[n]);\n const result = new Float32Array(length);\n let offset = 0;\n for (let i = 0; i < buffers.length; i++) {\n result.set(buffers[i], offset);\n offset += buffers[i].length;\n }\n channels[n] = result;\n }\n return channels;\n }\n\n /**\n * Combines parallel audio data into correct format,\n * channels[Left[], Right[]] to float32Array[LRLRLRLR...]\n */\n formatAudioData(channels) {\n if (channels.length === 1) {\n // Simple case is only one channel\n const float32Array = channels[0].slice();\n const meanValues = channels[0].slice();\n return { float32Array, meanValues };\n } else {\n const float32Array = new Float32Array(\n channels[0].length * channels.length\n );\n const meanValues = new Float32Array(channels[0].length);\n for (let i = 0; i < channels[0].length; i++) {\n const offset = i * channels.length;\n let meanValue = 0;\n for (let n = 0; n < channels.length; n++) {\n float32Array[offset + n] = channels[n][i];\n meanValue += channels[n][i];\n }\n meanValues[i] = meanValue / channels.length;\n }\n return { float32Array, meanValues };\n }\n }\n\n /**\n * Converts 32-bit float data to 16-bit integers\n */\n floatTo16BitPCM(float32Array) {\n const buffer = new ArrayBuffer(float32Array.length * 2);\n const view = new DataView(buffer);\n let offset = 0;\n for (let i = 0; i < float32Array.length; i++, offset += 2) {\n let s = Math.max(-1, Math.min(1, float32Array[i]));\n view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n }\n return buffer;\n }\n\n /**\n * Retrieves the most recent amplitude values from the audio stream\n * @param {number} channel\n */\n getValues(channel = -1) {\n const channels = this.readChannelData(this.chunks, channel);\n const { meanValues } = this.formatAudioData(channels);\n return { meanValues, channels };\n }\n\n /**\n * Exports chunks as an audio/wav file\n */\n export() {\n const channels = this.readChannelData(this.chunks);\n const { float32Array, meanValues } = this.formatAudioData(channels);\n const audioData = this.floatTo16BitPCM(float32Array);\n return {\n meanValues: meanValues,\n audio: {\n bitsPerSample: 16,\n channels: channels,\n data: audioData,\n },\n };\n }\n\n receive(e) {\n const { event, id } = e.data;\n let receiptData = {};\n switch (event) {\n case 'start':\n this.recording = true;\n break;\n case 'stop':\n this.recording = false;\n break;\n case 'clear':\n this.initialize();\n break;\n case 'export':\n receiptData = this.export();\n break;\n case 'read':\n receiptData = this.getValues();\n break;\n default:\n break;\n }\n // Always send back receipt\n this.port.postMessage({ event: 'receipt', id, data: receiptData });\n }\n\n sendChunk(chunk) {\n const channels = this.readChannelData([chunk]);\n const { float32Array, meanValues } = this.formatAudioData(channels);\n const rawAudioData = this.floatTo16BitPCM(float32Array);\n const monoAudioData = this.floatTo16BitPCM(meanValues);\n this.port.postMessage({\n event: 'chunk',\n data: {\n mono: monoAudioData,\n raw: rawAudioData,\n },\n });\n }\n\n process(inputList, outputList, parameters) {\n // Copy input to output (e.g. speakers)\n // Note that this creates choppy sounds with Mac products\n const sourceLimit = Math.min(inputList.length, outputList.length);\n for (let inputNum = 0; inputNum < sourceLimit; inputNum++) {\n const input = inputList[inputNum];\n const output = outputList[inputNum];\n const channelCount = Math.min(input.length, output.length);\n for (let channelNum = 0; channelNum < channelCount; channelNum++) {\n input[channelNum].forEach((sample, i) => {\n output[channelNum][i] = sample;\n });\n }\n }\n const inputs = inputList[0];\n // There's latency at the beginning of a stream before recording starts\n // Make sure we actually receive audio data before we start storing chunks\n let sliceIndex = 0;\n if (!this.foundAudio) {\n for (const channel of inputs) {\n sliceIndex = 0; // reset for each channel\n if (this.foundAudio) {\n break;\n }\n if (channel) {\n for (const value of channel) {\n if (value !== 0) {\n // find only one non-zero entry in any channel\n this.foundAudio = true;\n break;\n } else {\n sliceIndex++;\n }\n }\n }\n }\n }\n if (inputs && inputs[0] && this.foundAudio && this.recording) {\n // We need to copy the TypedArray, because the \\`process\\`\n // internals will reuse the same buffer to hold each input\n const chunk = inputs.map((input) => input.slice(sliceIndex));\n this.chunks.push(chunk);\n this.sendChunk(chunk);\n }\n return true;\n }\n}\n\nregisterProcessor('audio_processor', AudioProcessor);\n`;\n\nconst script = new Blob([AudioProcessorWorklet], {\n type: 'application/javascript',\n});\nconst src = URL.createObjectURL(script);\nexport const AudioProcessorSrc = src;\n","import { AudioProcessorSrc } from \"./worklets/audio_processor.js\";\nimport { AudioAnalysis } from \"./analysis/audio_analysis.js\";\nimport { WavPacker } from \"./wav_packer.js\";\n\n/**\n * Decodes audio into a wav file\n * @typedef {Object} DecodedAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {Float32Array} values\n * @property {AudioBuffer} audioBuffer\n */\n\n/**\n * Records live stream of user audio as PCM16 \"audio/wav\" data\n * @class\n */\nexport class MediaStreamRecorder {\n /**\n * Create a new MediaStreamRecorder instance\n * @param {{sampleRate?: number, outputToSpeakers?: boolean, debug?: boolean}} [options]\n * @returns {MediaStreamRecorder}\n */\n constructor({\n sampleRate = 44100,\n outputToSpeakers = false,\n debug = false,\n } = {}) {\n // Script source\n this.scriptSrc = AudioProcessorSrc;\n // Config\n this.sampleRate = sampleRate;\n this.outputToSpeakers = outputToSpeakers;\n this.debug = !!debug;\n // State variables\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n this.recording = false;\n // Event handling with AudioWorklet\n this._lastEventId = 0;\n this.eventReceipts = {};\n this.eventTimeout = 5000;\n // Process chunks of audio\n this._chunkProcessor = () => {};\n this._chunkProcessorSize = void 0;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n\n /**\n * Logs data in debug mode\n * @param {...any} arguments\n * @returns {true}\n */\n log() {\n if (this.debug) {\n this.log(...arguments);\n }\n return true;\n }\n\n /**\n * Retrieves the current sampleRate for the recorder\n * @returns {number}\n */\n getSampleRate() {\n return this.sampleRate;\n }\n\n /**\n * Retrieves the current status of the recording\n * @returns {\"ended\"|\"paused\"|\"recording\"}\n */\n getStatus() {\n if (!this.processor) {\n return \"ended\";\n } else if (!this.recording) {\n return \"paused\";\n } else {\n return \"recording\";\n }\n }\n\n /**\n * Sends an event to the AudioWorklet\n * @private\n * @param {string} name\n * @param {{[key: string]: any}} data\n * @param {AudioWorkletNode} [_processor]\n * @returns {Promise<{[key: string]: any}>}\n */\n async _event(name, data = {}, _processor = null) {\n _processor = _processor || this.processor;\n if (!_processor) {\n throw new Error(\"Can not send events without recording first\");\n }\n const message = {\n event: name,\n id: this._lastEventId++,\n data,\n };\n _processor.port.postMessage(message);\n const t0 = new Date().valueOf();\n while (!this.eventReceipts[message.id]) {\n if (new Date().valueOf() - t0 > this.eventTimeout) {\n throw new Error(`Timeout waiting for \"${name}\" event`);\n }\n await new Promise((res) => setTimeout(() => res(true), 1));\n }\n const payload = this.eventReceipts[message.id];\n delete this.eventReceipts[message.id];\n return payload;\n }\n\n /**\n * Begins a recording session for the given audioTrack\n * Microphone recording indicator will appear on browser tab but status will be \"paused\"\n * @param {MediaStreamTrack} [audioTrack] if no device provided, default device will be used\n * @returns {Promise<true>}\n */\n async begin(audioTrack) {\n if (this.processor) {\n throw new Error(\n `Already connected: please call .end() to start a new session`\n );\n }\n\n if (!audioTrack || audioTrack.kind !== \"audio\") {\n throw new Error(\"No audio track provided\");\n }\n\n this.stream = new MediaStream([audioTrack]);\n\n const context = new AudioContext({ sampleRate: this.sampleRate });\n const source = context.createMediaStreamSource(this.stream);\n // Load and execute the module script.\n try {\n await context.audioWorklet.addModule(this.scriptSrc);\n } catch (e) {\n console.error(e);\n throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n }\n const processor = new AudioWorkletNode(context, \"audio_processor\");\n processor.port.onmessage = (e) => {\n const { event, id, data } = e.data;\n if (event === \"receipt\") {\n this.eventReceipts[id] = data;\n } else if (event === \"chunk\") {\n if (this._chunkProcessorSize) {\n const buffer = this._chunkProcessorBuffer;\n this._chunkProcessorBuffer = {\n raw: WavPacker.mergeBuffers(buffer.raw, data.raw),\n mono: WavPacker.mergeBuffers(buffer.mono, data.mono),\n };\n if (\n this._chunkProcessorBuffer.mono.byteLength >=\n this._chunkProcessorSize\n ) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n }\n } else {\n this._chunkProcessor(data);\n }\n }\n };\n\n const node = source.connect(processor);\n const analyser = context.createAnalyser();\n analyser.fftSize = 8192;\n analyser.smoothingTimeConstant = 0.1;\n node.connect(analyser);\n if (this.outputToSpeakers) {\n // eslint-disable-next-line no-console\n console.warn(\n \"Warning: Output to speakers may affect sound quality,\\n\" +\n \"especially due to system audio feedback preventative measures.\\n\" +\n \"use only for debugging\"\n );\n analyser.connect(context.destination);\n }\n\n this.source = source;\n this.node = node;\n this.analyser = analyser;\n this.processor = processor;\n return true;\n }\n\n /**\n * Gets the current frequency domain data from the recording track\n * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n * @param {number} [minDecibels] default -100\n * @param {number} [maxDecibels] default -30\n * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n */\n getFrequencies(\n analysisType = \"frequency\",\n minDecibels = -100,\n maxDecibels = -30\n ) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n return AudioAnalysis.getFrequencies(\n this.analyser,\n this.sampleRate,\n null,\n analysisType,\n minDecibels,\n maxDecibels\n );\n }\n\n /**\n * Pauses the recording\n * Keeps microphone stream open but halts storage of audio\n * @returns {Promise<true>}\n */\n async pause() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n } else if (!this.recording) {\n throw new Error(\"Already paused: please call .record() first\");\n }\n if (this._chunkProcessorBuffer.raw.byteLength) {\n this._chunkProcessor(this._chunkProcessorBuffer);\n }\n this.log(\"Pausing ...\");\n await this._event(\"stop\");\n this.recording = false;\n return true;\n }\n\n /**\n * Start recording stream and storing to memory from the connected audio source\n * @param {(data: { mono: Int16Array; raw: Int16Array }) => any} [chunkProcessor]\n * @param {number} [chunkSize] chunkProcessor will not be triggered until this size threshold met in mono audio\n * @returns {Promise<true>}\n */\n async record(chunkProcessor = () => {}, chunkSize = 8192) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n } else if (this.recording) {\n throw new Error(\"Already recording: HELLO please call .pause() first\");\n } else if (typeof chunkProcessor !== \"function\") {\n throw new Error(`chunkProcessor must be a function`);\n }\n this._chunkProcessor = chunkProcessor;\n this._chunkProcessorSize = chunkSize;\n this._chunkProcessorBuffer = {\n raw: new ArrayBuffer(0),\n mono: new ArrayBuffer(0),\n };\n this.log(\"Recording ...\");\n await this._event(\"start\");\n this.recording = true;\n return true;\n }\n\n /**\n * Clears the audio buffer, empties stored recording\n * @returns {Promise<true>}\n */\n async clear() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n await this._event(\"clear\");\n return true;\n }\n\n /**\n * Reads the current audio stream data\n * @returns {Promise<{meanValues: Float32Array, channels: Array<Float32Array>}>}\n */\n async read() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n this.log(\"Reading ...\");\n const result = await this._event(\"read\");\n return result;\n }\n\n /**\n * Saves the current audio stream to a file\n * @param {boolean} [force] Force saving while still recording\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async save(force = false) {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n if (!force && this.recording) {\n throw new Error(\n \"Currently recording: please call .pause() first, or call .save(true) to force\"\n );\n }\n this.log(\"Exporting ...\");\n const exportData = await this._event(\"export\");\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Ends the current recording session and saves the result\n * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n */\n async end() {\n if (!this.processor) {\n throw new Error(\"Session ended: please call .begin() first\");\n }\n\n const _processor = this.processor;\n\n this.log(\"Stopping ...\");\n await this._event(\"stop\");\n this.recording = false;\n\n this.log(\"Exporting ...\");\n const exportData = await this._event(\"export\", {}, _processor);\n\n this.processor.disconnect();\n this.source.disconnect();\n this.node.disconnect();\n this.analyser.disconnect();\n this.stream = null;\n this.processor = null;\n this.source = null;\n this.node = null;\n\n const packer = new WavPacker();\n const result = packer.pack(this.sampleRate, exportData.audio);\n return result;\n }\n\n /**\n * Performs a full cleanup of WavRecorder instance\n * Stops actively listening via microphone and removes existing listeners\n * @returns {Promise<true>}\n */\n async quit() {\n this.listenForDeviceChange(null);\n if (this.processor) {\n await this.end();\n }\n return true;\n }\n}\n\nglobalThis.WavRecorder = WavRecorder;\n"],"names":[],"version":3,"file":"index.module.js.map"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipecat-ai/daily-transport",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"license": "BSD-2-Clause",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.module.js",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"lint": "eslint . --ext ts --report-unused-disable-directives --max-warnings 0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@pipecat-ai/client-js": "
|
|
24
|
+
"@pipecat-ai/client-js": "^0.3.5",
|
|
25
25
|
"eslint": "9.11.1",
|
|
26
26
|
"eslint-config-prettier": "^9.1.0",
|
|
27
27
|
"eslint-plugin-simple-import-sort": "^12.1.1"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"@pipecat-ai/client-js": "~0.3.
|
|
30
|
+
"@pipecat-ai/client-js": "~0.3.5"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@daily-co/daily-js": "^0.73.0"
|