@ugfoundation/swaralipi-js 0.14.0 → 0.14.2
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/README.md +4 -0
- package/dist/{batch-D4HRATTH.js → batch-QEIW6XAA.js} +5 -5
- package/dist/{batch-D4HRATTH.js.map → batch-QEIW6XAA.js.map} +1 -1
- package/dist/{chunk-QQOC6LRA.js → chunk-6AKH2NLW.js} +6 -6
- package/dist/{chunk-QQOC6LRA.js.map → chunk-6AKH2NLW.js.map} +1 -1
- package/dist/{chunk-UV5OJYT3.js → chunk-CJI7A6AM.js} +3 -3
- package/dist/{chunk-UV5OJYT3.js.map → chunk-CJI7A6AM.js.map} +1 -1
- package/dist/{chunk-KOHSKHXI.js → chunk-K73Y46WU.js} +3 -3
- package/dist/{chunk-KOHSKHXI.js.map → chunk-K73Y46WU.js.map} +1 -1
- package/dist/{chunk-YBFM5NLW.js → chunk-WEXTZRRB.js} +29 -4
- package/dist/chunk-WEXTZRRB.js.map +1 -0
- package/dist/cli.cjs +4 -4
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +3 -3
- package/dist/convert/index.cjs +4 -4
- package/dist/convert/index.cjs.map +1 -1
- package/dist/convert/index.d.cts +1 -1
- package/dist/convert/index.d.ts +1 -1
- package/dist/convert/index.js +3 -3
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{schedule-oJgg_bnc.d.cts → instruments-C3CbtYdm.d.ts} +171 -162
- package/dist/{schedule-DsVESieT.d.ts → instruments-CfHu4bSQ.d.cts} +171 -162
- package/dist/{lay-CXhC-HRO.d.cts → lay-Bi87MnkT.d.cts} +1 -1
- package/dist/{lay-CWlEhImP.d.ts → lay-CFLy_wd_.d.ts} +1 -1
- package/dist/player/index.cjs +163 -63
- package/dist/player/index.cjs.map +1 -1
- package/dist/player/index.d.cts +37 -17
- package/dist/player/index.d.ts +37 -17
- package/dist/player/index.js +139 -67
- package/dist/player/index.js.map +1 -1
- package/dist/spec/index.cjs +2 -2
- package/dist/spec/index.cjs.map +1 -1
- package/dist/spec/index.d.cts +12 -12
- package/dist/spec/index.d.ts +12 -12
- package/dist/spec/index.js +2 -2
- package/dist/viewer/index.cjs +127 -4
- package/dist/viewer/index.cjs.map +1 -1
- package/dist/viewer/index.d.cts +64 -4
- package/dist/viewer/index.d.ts +64 -4
- package/dist/viewer/index.js +124 -5
- package/dist/viewer/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-YBFM5NLW.js.map +0 -1
- package/dist/{schema-DZag9qkF.d.ts → schema-DyL0bMCf.d.cts} +36 -36
- package/dist/{schema-DZag9qkF.d.cts → schema-DyL0bMCf.d.ts} +36 -36
package/dist/player/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { S as Swaralipi, T as Taal, O as Octave, a as SvaraLetter, N as Note } from '../schema-
|
|
2
|
-
import { a as LaySpeeds, T as TaalId } from '../lay-
|
|
3
|
-
export { b as LAYS, c as LAY_SPEEDS, L as Lay, p as printedLay, r as resolveLaySpeeds, d as rowLay } from '../lay-
|
|
4
|
-
import { I as InstrumentId, a as InstrumentDef, E as Excerpt, S as Schedule, D as DrumVoice, T as TempoSegment } from '../
|
|
5
|
-
export { A as ARC_RAW_RE, b as DEFAULT_SOUNDS_BASE, c as DRUM_KIT_BASE, G as GRACE_STEP, d as GlideLeg, e as INSTRUMENTS, L as Line, f as LyricMap, M as MEEND_HOLD, P as PlayEvent, g as SALAMANDER_BASE, h as SAMPLED_TAALS, i as ScheduleOptions, j as TABLA_BPMS, k as TABLA_VARIATIONS, l as TONEJS_INSTRUMENTS_BASE, m as ToneModule, n as alignLyrics, o as buildSchedule, p as createBuffers, q as drumPattern, r as eventAt, s as glideTargets, t as graceTouches, u as instrumentSampleUrl, v as isArcRaw, w as
|
|
1
|
+
import { S as Swaralipi, T as Taal, O as Octave, a as SvaraLetter, N as Note } from '../schema-DyL0bMCf.cjs';
|
|
2
|
+
import { a as LaySpeeds, T as TaalId } from '../lay-Bi87MnkT.cjs';
|
|
3
|
+
export { b as LAYS, c as LAY_SPEEDS, L as Lay, p as printedLay, r as resolveLaySpeeds, d as rowLay } from '../lay-Bi87MnkT.cjs';
|
|
4
|
+
import { I as InstrumentId, a as InstrumentDef, E as Excerpt, S as Schedule, D as DrumVoice, T as TempoSegment } from '../instruments-CfHu4bSQ.cjs';
|
|
5
|
+
export { A as ARC_RAW_RE, b as DEFAULT_SOUNDS_BASE, c as DRUM_KIT_BASE, G as GRACE_STEP, d as GlideLeg, e as INSTRUMENTS, L as Line, f as LyricMap, M as MEEND_HOLD, P as PlayEvent, g as SALAMANDER_BASE, h as SAMPLED_TAALS, i as ScheduleOptions, j as TABLA_BPMS, k as TABLA_VARIATIONS, l as TONEJS_INSTRUMENTS_BASE, m as ToneModule, n as alignLyrics, o as buildSchedule, p as createBuffers, q as drumPattern, r as eventAt, s as glideTargets, t as graceTouches, u as instrumentSampleUrl, v as isArcRaw, w as lyricCues, x as meendContinuations, y as nearestSampleKey, z as nearestTablaBpm, B as normalizeBase, C as probeUrl, F as quantizeLoopEnd, H as santoorUrls, J as scheduleLines, K as subsetUrls, N as tablaBpms, O as tablaUrl, Q as triggerGlide } from '../instruments-CfHu4bSQ.cjs';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import 'tone';
|
|
8
8
|
|
|
@@ -239,6 +239,10 @@ declare class SwaralipiPlayer {
|
|
|
239
239
|
|
|
240
240
|
type AudioFormat = 'wav' | 'mp3';
|
|
241
241
|
interface AudioExportOptions {
|
|
242
|
+
/** Play only the notes singing these stretches of the text (see alignLyrics). */
|
|
243
|
+
excerpt?: Excerpt;
|
|
244
|
+
/** The song's words: when given, the result carries their `cues` (an LRC's timing). */
|
|
245
|
+
lyrics?: string;
|
|
242
246
|
/** Samples host (santoor/tabla/tanpura/metronome). Default the project CDN. */
|
|
243
247
|
soundsBaseUrl?: string;
|
|
244
248
|
/** Self-host the grand piano (see the player's `pianoBaseUrl`). */
|
|
@@ -293,6 +297,15 @@ interface AudioExportResult {
|
|
|
293
297
|
mimeType: string;
|
|
294
298
|
/** Rendered length in seconds. */
|
|
295
299
|
durationSec: number;
|
|
300
|
+
/** Each sung line and its words, in seconds on this file's timeline (given `lyrics`). */
|
|
301
|
+
cues?: LyricCue[];
|
|
302
|
+
}
|
|
303
|
+
interface LyricCue {
|
|
304
|
+
sec: number;
|
|
305
|
+
words: {
|
|
306
|
+
sec: number;
|
|
307
|
+
text: string;
|
|
308
|
+
}[];
|
|
296
309
|
}
|
|
297
310
|
/**
|
|
298
311
|
* Render a swaralipi doc to an audio Blob in the browser. Runs in an
|
|
@@ -308,11 +321,17 @@ declare function exportAudio(doc: Swaralipi, options?: AudioExportOptions): Prom
|
|
|
308
321
|
*/
|
|
309
322
|
declare function encodeWav(channels: Float32Array[], sampleRate: number): Uint8Array;
|
|
310
323
|
/**
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
324
|
+
* A streaming MP3 encoder: feed 16-bit PCM in any number of pieces, get one MP3 — one encoder
|
|
325
|
+
* delay, so a track joined from several renders keeps its timing. lamejs is **dynamically
|
|
326
|
+
* imported** and an *optional* peer dependency (LGPL-3.0). Samples go in 1152-frame blocks (a
|
|
327
|
+
* multiple of 576, lamejs' preferred size).
|
|
315
328
|
*/
|
|
329
|
+
declare function mp3Stream(sampleRate?: number, kbps?: number, channels?: 1 | 2): Promise<{
|
|
330
|
+
push(left: Int16Array, right?: Int16Array): void;
|
|
331
|
+
end(): Uint8Array[];
|
|
332
|
+
}>;
|
|
333
|
+
/** Encode planar float channels to MP3 via lamejs (see mp3Stream). WAV needs no dependency, so
|
|
334
|
+
* only reach for this when a compressed file is wanted. */
|
|
316
335
|
declare function encodeMp3(channels: Float32Array[], sampleRate: number, kbps?: number): Promise<Uint8Array>;
|
|
317
336
|
|
|
318
337
|
/**
|
|
@@ -333,6 +352,8 @@ declare function encodeMp3(channels: Float32Array[], sampleRate: number, kbps?:
|
|
|
333
352
|
*/
|
|
334
353
|
|
|
335
354
|
interface MidiExportOptions {
|
|
355
|
+
/** Play only the notes singing these stretches of the text (see alignLyrics). */
|
|
356
|
+
excerpt?: Excerpt;
|
|
336
357
|
/** Tonic (Sa). Accepts `C`, `C#`, `cs`… Default: doc tonic, else `C`. */
|
|
337
358
|
tonic?: string;
|
|
338
359
|
/** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */
|
|
@@ -357,13 +378,6 @@ interface MidiExportResult {
|
|
|
357
378
|
filename: string;
|
|
358
379
|
mimeType: string;
|
|
359
380
|
}
|
|
360
|
-
/**
|
|
361
|
-
* Encode a schedule to a Standard MIDI File. Melody rides channel 0; when
|
|
362
|
-
* `drums` is given, its per-matra voices ride a second GM channel-10 track
|
|
363
|
-
* (the file becomes format 1). `drums` is one pattern for the whole song, or a
|
|
364
|
-
* function picking each লয় / তাল segment's own (তালফেরতা; `undefined` = rest).
|
|
365
|
-
* Pure — no Tone, no browser — directly testable.
|
|
366
|
-
*/
|
|
367
381
|
declare function encodeMidi(schedule: Schedule, opts: {
|
|
368
382
|
bpm: number;
|
|
369
383
|
name?: string;
|
|
@@ -374,6 +388,12 @@ declare function encodeMidi(schedule: Schedule, opts: {
|
|
|
374
388
|
* beyond `Blob` (present in Node 20+ too), so it works client-side or server-side.
|
|
375
389
|
*/
|
|
376
390
|
declare function exportMidi(doc: Swaralipi, options?: MidiExportOptions): MidiExportResult;
|
|
391
|
+
/** Several songs on one timeline (a whole dance-drama), back to back with two beats' rest:
|
|
392
|
+
* each song opens with its own tempo and a marker naming it; drums share one channel-10 track. */
|
|
393
|
+
declare function exportMidiSet(items: {
|
|
394
|
+
doc: Swaralipi;
|
|
395
|
+
options?: MidiExportOptions;
|
|
396
|
+
}[], name: string): MidiExportResult;
|
|
377
397
|
|
|
378
398
|
/** Octave register offset in octaves, relative to madhyam (middle). */
|
|
379
399
|
declare const OCTAVE_OFFSET: Record<Octave, number>;
|
|
@@ -421,4 +441,4 @@ declare function sampleFileName(midi: number): string;
|
|
|
421
441
|
*/
|
|
422
442
|
declare function sCurve(x: number, steepness?: number): number;
|
|
423
443
|
|
|
424
|
-
export { type AudioExportOptions, type AudioExportResult, type AudioFormat, type BindSheetOptions, DrumVoice, Excerpt, InstrumentDef, InstrumentId, LaySpeeds, type LineRange, type MidiExportOptions, type MidiExportResult, OCTAVE_OFFSET, type PlayerOptions, type PlayerState, type PracticeState, type RhythmMode, SHUDDHA, Schedule, SwaralipiPlayer, TempoSegment, encodeMidi, encodeMp3, encodeWav, exportAudio, exportMidi, midiToSampleName, parseTonic, sCurve, sampleFileName, svaraSemitone, svaraToMidi };
|
|
444
|
+
export { type AudioExportOptions, type AudioExportResult, type AudioFormat, type BindSheetOptions, DrumVoice, Excerpt, InstrumentDef, InstrumentId, LaySpeeds, type LineRange, type LyricCue, type MidiExportOptions, type MidiExportResult, OCTAVE_OFFSET, type PlayerOptions, type PlayerState, type PracticeState, type RhythmMode, SHUDDHA, Schedule, SwaralipiPlayer, TempoSegment, encodeMidi, encodeMp3, encodeWav, exportAudio, exportMidi, exportMidiSet, midiToSampleName, mp3Stream, parseTonic, sCurve, sampleFileName, svaraSemitone, svaraToMidi };
|
package/dist/player/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { S as Swaralipi, T as Taal, O as Octave, a as SvaraLetter, N as Note } from '../schema-
|
|
2
|
-
import { a as LaySpeeds, T as TaalId } from '../lay-
|
|
3
|
-
export { b as LAYS, c as LAY_SPEEDS, L as Lay, p as printedLay, r as resolveLaySpeeds, d as rowLay } from '../lay-
|
|
4
|
-
import { I as InstrumentId, a as InstrumentDef, E as Excerpt, S as Schedule, D as DrumVoice, T as TempoSegment } from '../
|
|
5
|
-
export { A as ARC_RAW_RE, b as DEFAULT_SOUNDS_BASE, c as DRUM_KIT_BASE, G as GRACE_STEP, d as GlideLeg, e as INSTRUMENTS, L as Line, f as LyricMap, M as MEEND_HOLD, P as PlayEvent, g as SALAMANDER_BASE, h as SAMPLED_TAALS, i as ScheduleOptions, j as TABLA_BPMS, k as TABLA_VARIATIONS, l as TONEJS_INSTRUMENTS_BASE, m as ToneModule, n as alignLyrics, o as buildSchedule, p as createBuffers, q as drumPattern, r as eventAt, s as glideTargets, t as graceTouches, u as instrumentSampleUrl, v as isArcRaw, w as
|
|
1
|
+
import { S as Swaralipi, T as Taal, O as Octave, a as SvaraLetter, N as Note } from '../schema-DyL0bMCf.js';
|
|
2
|
+
import { a as LaySpeeds, T as TaalId } from '../lay-CFLy_wd_.js';
|
|
3
|
+
export { b as LAYS, c as LAY_SPEEDS, L as Lay, p as printedLay, r as resolveLaySpeeds, d as rowLay } from '../lay-CFLy_wd_.js';
|
|
4
|
+
import { I as InstrumentId, a as InstrumentDef, E as Excerpt, S as Schedule, D as DrumVoice, T as TempoSegment } from '../instruments-C3CbtYdm.js';
|
|
5
|
+
export { A as ARC_RAW_RE, b as DEFAULT_SOUNDS_BASE, c as DRUM_KIT_BASE, G as GRACE_STEP, d as GlideLeg, e as INSTRUMENTS, L as Line, f as LyricMap, M as MEEND_HOLD, P as PlayEvent, g as SALAMANDER_BASE, h as SAMPLED_TAALS, i as ScheduleOptions, j as TABLA_BPMS, k as TABLA_VARIATIONS, l as TONEJS_INSTRUMENTS_BASE, m as ToneModule, n as alignLyrics, o as buildSchedule, p as createBuffers, q as drumPattern, r as eventAt, s as glideTargets, t as graceTouches, u as instrumentSampleUrl, v as isArcRaw, w as lyricCues, x as meendContinuations, y as nearestSampleKey, z as nearestTablaBpm, B as normalizeBase, C as probeUrl, F as quantizeLoopEnd, H as santoorUrls, J as scheduleLines, K as subsetUrls, N as tablaBpms, O as tablaUrl, Q as triggerGlide } from '../instruments-C3CbtYdm.js';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import 'tone';
|
|
8
8
|
|
|
@@ -239,6 +239,10 @@ declare class SwaralipiPlayer {
|
|
|
239
239
|
|
|
240
240
|
type AudioFormat = 'wav' | 'mp3';
|
|
241
241
|
interface AudioExportOptions {
|
|
242
|
+
/** Play only the notes singing these stretches of the text (see alignLyrics). */
|
|
243
|
+
excerpt?: Excerpt;
|
|
244
|
+
/** The song's words: when given, the result carries their `cues` (an LRC's timing). */
|
|
245
|
+
lyrics?: string;
|
|
242
246
|
/** Samples host (santoor/tabla/tanpura/metronome). Default the project CDN. */
|
|
243
247
|
soundsBaseUrl?: string;
|
|
244
248
|
/** Self-host the grand piano (see the player's `pianoBaseUrl`). */
|
|
@@ -293,6 +297,15 @@ interface AudioExportResult {
|
|
|
293
297
|
mimeType: string;
|
|
294
298
|
/** Rendered length in seconds. */
|
|
295
299
|
durationSec: number;
|
|
300
|
+
/** Each sung line and its words, in seconds on this file's timeline (given `lyrics`). */
|
|
301
|
+
cues?: LyricCue[];
|
|
302
|
+
}
|
|
303
|
+
interface LyricCue {
|
|
304
|
+
sec: number;
|
|
305
|
+
words: {
|
|
306
|
+
sec: number;
|
|
307
|
+
text: string;
|
|
308
|
+
}[];
|
|
296
309
|
}
|
|
297
310
|
/**
|
|
298
311
|
* Render a swaralipi doc to an audio Blob in the browser. Runs in an
|
|
@@ -308,11 +321,17 @@ declare function exportAudio(doc: Swaralipi, options?: AudioExportOptions): Prom
|
|
|
308
321
|
*/
|
|
309
322
|
declare function encodeWav(channels: Float32Array[], sampleRate: number): Uint8Array;
|
|
310
323
|
/**
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
324
|
+
* A streaming MP3 encoder: feed 16-bit PCM in any number of pieces, get one MP3 — one encoder
|
|
325
|
+
* delay, so a track joined from several renders keeps its timing. lamejs is **dynamically
|
|
326
|
+
* imported** and an *optional* peer dependency (LGPL-3.0). Samples go in 1152-frame blocks (a
|
|
327
|
+
* multiple of 576, lamejs' preferred size).
|
|
315
328
|
*/
|
|
329
|
+
declare function mp3Stream(sampleRate?: number, kbps?: number, channels?: 1 | 2): Promise<{
|
|
330
|
+
push(left: Int16Array, right?: Int16Array): void;
|
|
331
|
+
end(): Uint8Array[];
|
|
332
|
+
}>;
|
|
333
|
+
/** Encode planar float channels to MP3 via lamejs (see mp3Stream). WAV needs no dependency, so
|
|
334
|
+
* only reach for this when a compressed file is wanted. */
|
|
316
335
|
declare function encodeMp3(channels: Float32Array[], sampleRate: number, kbps?: number): Promise<Uint8Array>;
|
|
317
336
|
|
|
318
337
|
/**
|
|
@@ -333,6 +352,8 @@ declare function encodeMp3(channels: Float32Array[], sampleRate: number, kbps?:
|
|
|
333
352
|
*/
|
|
334
353
|
|
|
335
354
|
interface MidiExportOptions {
|
|
355
|
+
/** Play only the notes singing these stretches of the text (see alignLyrics). */
|
|
356
|
+
excerpt?: Excerpt;
|
|
336
357
|
/** Tonic (Sa). Accepts `C`, `C#`, `cs`… Default: doc tonic, else `C`. */
|
|
337
358
|
tonic?: string;
|
|
338
359
|
/** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */
|
|
@@ -357,13 +378,6 @@ interface MidiExportResult {
|
|
|
357
378
|
filename: string;
|
|
358
379
|
mimeType: string;
|
|
359
380
|
}
|
|
360
|
-
/**
|
|
361
|
-
* Encode a schedule to a Standard MIDI File. Melody rides channel 0; when
|
|
362
|
-
* `drums` is given, its per-matra voices ride a second GM channel-10 track
|
|
363
|
-
* (the file becomes format 1). `drums` is one pattern for the whole song, or a
|
|
364
|
-
* function picking each লয় / তাল segment's own (তালফেরতা; `undefined` = rest).
|
|
365
|
-
* Pure — no Tone, no browser — directly testable.
|
|
366
|
-
*/
|
|
367
381
|
declare function encodeMidi(schedule: Schedule, opts: {
|
|
368
382
|
bpm: number;
|
|
369
383
|
name?: string;
|
|
@@ -374,6 +388,12 @@ declare function encodeMidi(schedule: Schedule, opts: {
|
|
|
374
388
|
* beyond `Blob` (present in Node 20+ too), so it works client-side or server-side.
|
|
375
389
|
*/
|
|
376
390
|
declare function exportMidi(doc: Swaralipi, options?: MidiExportOptions): MidiExportResult;
|
|
391
|
+
/** Several songs on one timeline (a whole dance-drama), back to back with two beats' rest:
|
|
392
|
+
* each song opens with its own tempo and a marker naming it; drums share one channel-10 track. */
|
|
393
|
+
declare function exportMidiSet(items: {
|
|
394
|
+
doc: Swaralipi;
|
|
395
|
+
options?: MidiExportOptions;
|
|
396
|
+
}[], name: string): MidiExportResult;
|
|
377
397
|
|
|
378
398
|
/** Octave register offset in octaves, relative to madhyam (middle). */
|
|
379
399
|
declare const OCTAVE_OFFSET: Record<Octave, number>;
|
|
@@ -421,4 +441,4 @@ declare function sampleFileName(midi: number): string;
|
|
|
421
441
|
*/
|
|
422
442
|
declare function sCurve(x: number, steepness?: number): number;
|
|
423
443
|
|
|
424
|
-
export { type AudioExportOptions, type AudioExportResult, type AudioFormat, type BindSheetOptions, DrumVoice, Excerpt, InstrumentDef, InstrumentId, LaySpeeds, type LineRange, type MidiExportOptions, type MidiExportResult, OCTAVE_OFFSET, type PlayerOptions, type PlayerState, type PracticeState, type RhythmMode, SHUDDHA, Schedule, SwaralipiPlayer, TempoSegment, encodeMidi, encodeMp3, encodeWav, exportAudio, exportMidi, midiToSampleName, parseTonic, sCurve, sampleFileName, svaraSemitone, svaraToMidi };
|
|
444
|
+
export { type AudioExportOptions, type AudioExportResult, type AudioFormat, type BindSheetOptions, DrumVoice, Excerpt, InstrumentDef, InstrumentId, LaySpeeds, type LineRange, type LyricCue, type MidiExportOptions, type MidiExportResult, OCTAVE_OFFSET, type PlayerOptions, type PlayerState, type PracticeState, type RhythmMode, SHUDDHA, Schedule, SwaralipiPlayer, TempoSegment, encodeMidi, encodeMp3, encodeWav, exportAudio, exportMidi, exportMidiSet, midiToSampleName, mp3Stream, parseTonic, sCurve, sampleFileName, svaraSemitone, svaraToMidi };
|
package/dist/player/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DEFAULT_SOUNDS_BASE, INSTRUMENTS, SAMPLED_TAALS, buildSchedule, eventAt, lineAt, byRow, lineFor, quantizeLoopEnd, instrumentSampleUrl, probeUrl, scheduleLines, GRACE_STEP, normalizeBase, nearestTablaBpm, tablaBpms, graceTouches, midiToSampleName, glideTargets, triggerGlide, createSampler, createBuffers, tablaShiftSemitones, tablaUrl, TABLA_GRAIN_OVERLAP_SEC, TABLA_GRAIN_SEC, createDrumKit, drumPattern, createMetronome, TANPURA_PCS, createTanpura, parseTonic, MEEND_HOLD, sCurve } from '../chunk-
|
|
2
|
-
export { ARC_RAW_RE, DEFAULT_SOUNDS_BASE, DRUM_KIT_BASE, GRACE_STEP, INSTRUMENTS, MEEND_HOLD, OCTAVE_OFFSET, SALAMANDER_BASE, SAMPLED_TAALS, SHUDDHA, TABLA_BPMS, TABLA_VARIATIONS, TONEJS_INSTRUMENTS_BASE, alignLyrics, buildSchedule, createBuffers, drumPattern, eventAt, glideTargets, graceTouches, instrumentSampleUrl, isArcRaw, meendContinuations, midiToSampleName, nearestSampleKey, nearestTablaBpm, normalizeBase, parseTonic, probeUrl, quantizeLoopEnd, sCurve, sampleFileName, santoorUrls, scheduleLines, subsetUrls, svaraSemitone, svaraToMidi, tablaBpms, tablaUrl, triggerGlide } from '../chunk-
|
|
1
|
+
import { DEFAULT_SOUNDS_BASE, INSTRUMENTS, SAMPLED_TAALS, buildSchedule, eventAt, lineAt, byRow, lineFor, quantizeLoopEnd, instrumentSampleUrl, probeUrl, scheduleLines, GRACE_STEP, normalizeBase, nearestTablaBpm, tablaBpms, graceTouches, midiToSampleName, glideTargets, triggerGlide, createSampler, createBuffers, tablaShiftSemitones, tablaUrl, TABLA_GRAIN_OVERLAP_SEC, TABLA_GRAIN_SEC, createDrumKit, drumPattern, createMetronome, TANPURA_PCS, createTanpura, parseTonic, lyricCues, alignLyrics, MEEND_HOLD, sCurve } from '../chunk-WEXTZRRB.js';
|
|
2
|
+
export { ARC_RAW_RE, DEFAULT_SOUNDS_BASE, DRUM_KIT_BASE, GRACE_STEP, INSTRUMENTS, MEEND_HOLD, OCTAVE_OFFSET, SALAMANDER_BASE, SAMPLED_TAALS, SHUDDHA, TABLA_BPMS, TABLA_VARIATIONS, TONEJS_INSTRUMENTS_BASE, alignLyrics, buildSchedule, createBuffers, drumPattern, eventAt, glideTargets, graceTouches, instrumentSampleUrl, isArcRaw, lyricCues, meendContinuations, midiToSampleName, nearestSampleKey, nearestTablaBpm, normalizeBase, parseTonic, probeUrl, quantizeLoopEnd, sCurve, sampleFileName, santoorUrls, scheduleLines, subsetUrls, svaraSemitone, svaraToMidi, tablaBpms, tablaUrl, triggerGlide } from '../chunk-WEXTZRRB.js';
|
|
3
3
|
import '../chunk-BSZ3WQUP.js';
|
|
4
|
-
import { TAALS } from '../chunk-
|
|
5
|
-
export { LAYS, LAY_SPEEDS, printedLay, resolveLaySpeeds, rowLay } from '../chunk-
|
|
4
|
+
import { TAALS } from '../chunk-K73Y46WU.js';
|
|
5
|
+
export { LAYS, LAY_SPEEDS, printedLay, resolveLaySpeeds, rowLay } from '../chunk-K73Y46WU.js';
|
|
6
6
|
|
|
7
7
|
// src/player/player.ts
|
|
8
8
|
var STOP_FADE_SEC = 0.5;
|
|
@@ -1104,6 +1104,38 @@ function midiRange2(schedule) {
|
|
|
1104
1104
|
}
|
|
1105
1105
|
return lo <= hi ? { lo, hi } : void 0;
|
|
1106
1106
|
}
|
|
1107
|
+
var AHEAD_SEC = 2;
|
|
1108
|
+
async function renderOffline(Tone, build, durationSec, channels, sampleRate) {
|
|
1109
|
+
const chunked = "suspend" in OfflineAudioContext.prototype && "positionX" in AudioListener.prototype;
|
|
1110
|
+
const context = chunked ? new Tone.OfflineContext(new OfflineAudioContext(channels, Math.ceil(durationSec * sampleRate), sampleRate)) : new Tone.OfflineContext(channels, durationSec, sampleRate);
|
|
1111
|
+
const raw = context.rawContext;
|
|
1112
|
+
const original = Tone.getContext();
|
|
1113
|
+
Tone.setContext(context);
|
|
1114
|
+
try {
|
|
1115
|
+
await build(context);
|
|
1116
|
+
} finally {
|
|
1117
|
+
Tone.setContext(original);
|
|
1118
|
+
}
|
|
1119
|
+
const clock = context;
|
|
1120
|
+
const run = (until) => {
|
|
1121
|
+
while (clock._currentTime <= Math.min(until, durationSec)) {
|
|
1122
|
+
clock.emit("tick");
|
|
1123
|
+
clock._currentTime += 128 / sampleRate;
|
|
1124
|
+
}
|
|
1125
|
+
};
|
|
1126
|
+
if (chunked) {
|
|
1127
|
+
run(2 * AHEAD_SEC);
|
|
1128
|
+
for (let t = AHEAD_SEC; t < durationSec; t += AHEAD_SEC) {
|
|
1129
|
+
void raw.suspend(t).then(() => {
|
|
1130
|
+
run(t + 2 * AHEAD_SEC);
|
|
1131
|
+
void raw.resume();
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
} else {
|
|
1135
|
+
run(Infinity);
|
|
1136
|
+
}
|
|
1137
|
+
return raw.startRendering();
|
|
1138
|
+
}
|
|
1107
1139
|
function pickDef(id, o) {
|
|
1108
1140
|
const def = o.customInstruments?.[id] ?? INSTRUMENTS[id];
|
|
1109
1141
|
if (def === void 0) return INSTRUMENTS.harmonium;
|
|
@@ -1132,7 +1164,8 @@ async function exportAudio(doc, options = {}) {
|
|
|
1132
1164
|
tonic: options.tonic,
|
|
1133
1165
|
baseOctave: options.baseOctave,
|
|
1134
1166
|
laySpeeds: options.laySpeeds,
|
|
1135
|
-
repeats: options.repeats ?? true
|
|
1167
|
+
repeats: options.repeats ?? true,
|
|
1168
|
+
excerpt: options.excerpt
|
|
1136
1169
|
});
|
|
1137
1170
|
const range = midiRange2(schedule);
|
|
1138
1171
|
const taalId = resolveTaal(doc, options.taal);
|
|
@@ -1145,7 +1178,8 @@ async function exportAudio(doc, options = {}) {
|
|
|
1145
1178
|
const def = pickDef(id, options);
|
|
1146
1179
|
const shift = rhythm !== "none" ? schedule.pickupBeats * spb : 0;
|
|
1147
1180
|
const durationSec = Math.max(schedule.totalBeats * spb + shift + (def.release ?? 1) + fadeOutSec + 0.5, 0.5);
|
|
1148
|
-
const rendered = await
|
|
1181
|
+
const rendered = await renderOffline(
|
|
1182
|
+
Tone,
|
|
1149
1183
|
async ({ transport }) => {
|
|
1150
1184
|
transport.bpm.value = bpm;
|
|
1151
1185
|
const master = new Tone.Gain(1).toDestination();
|
|
@@ -1292,11 +1326,16 @@ async function exportAudio(doc, options = {}) {
|
|
|
1292
1326
|
for (let c = 0; c < rendered.numberOfChannels; c++) chans.push(rendered.getChannelData(c));
|
|
1293
1327
|
const bytes = format === "mp3" ? await encodeMp3(chans, rendered.sampleRate, options.mp3Kbps) : encodeWav(chans, rendered.sampleRate);
|
|
1294
1328
|
const mimeType = format === "mp3" ? "audio/mpeg" : "audio/wav";
|
|
1329
|
+
const cues = options.lyrics === void 0 ? void 0 : lyricCues(schedule.events, alignLyrics(doc, options.lyrics), options.lyrics).map((cue) => ({
|
|
1330
|
+
sec: cue.beat * spb + shift,
|
|
1331
|
+
words: cue.words.map((word) => ({ sec: word.beat * spb + shift, text: word.text }))
|
|
1332
|
+
}));
|
|
1295
1333
|
return {
|
|
1296
1334
|
blob: new Blob([bytes], { type: mimeType }),
|
|
1297
1335
|
filename: `${safeName(doc.meta.title)}.${format}`,
|
|
1298
1336
|
mimeType,
|
|
1299
|
-
durationSec: rendered.duration
|
|
1337
|
+
durationSec: rendered.duration,
|
|
1338
|
+
...cues === void 0 ? {} : { cues }
|
|
1300
1339
|
};
|
|
1301
1340
|
}
|
|
1302
1341
|
function toInt16(f) {
|
|
@@ -1363,22 +1402,32 @@ async function loadLame() {
|
|
|
1363
1402
|
);
|
|
1364
1403
|
}
|
|
1365
1404
|
}
|
|
1366
|
-
async function
|
|
1405
|
+
async function mp3Stream(sampleRate = 44100, kbps = 192, channels = 1) {
|
|
1367
1406
|
const Mp3Encoder = await loadLame();
|
|
1368
|
-
const
|
|
1369
|
-
const enc = new Mp3Encoder(numCh, sampleRate, kbps);
|
|
1370
|
-
const left = floatToInt16(channels[0] ?? new Float32Array());
|
|
1371
|
-
const right = numCh > 1 ? floatToInt16(channels[1]) : void 0;
|
|
1372
|
-
const block = 1152;
|
|
1407
|
+
const enc = new Mp3Encoder(channels, sampleRate, kbps);
|
|
1373
1408
|
const out = [];
|
|
1374
|
-
|
|
1375
|
-
const l = left.subarray(i, i + block);
|
|
1376
|
-
const chunk = right ? enc.encodeBuffer(l, right.subarray(i, i + block)) : enc.encodeBuffer(l);
|
|
1409
|
+
const keep = (chunk) => {
|
|
1377
1410
|
if (chunk.length > 0) out.push(new Uint8Array(chunk));
|
|
1378
|
-
}
|
|
1379
|
-
const
|
|
1380
|
-
|
|
1381
|
-
|
|
1411
|
+
};
|
|
1412
|
+
const block = 1152;
|
|
1413
|
+
return {
|
|
1414
|
+
push(left, right) {
|
|
1415
|
+
for (let i = 0; i < left.length; i += block) {
|
|
1416
|
+
const l = left.subarray(i, i + block);
|
|
1417
|
+
keep(right ? enc.encodeBuffer(l, right.subarray(i, i + block)) : enc.encodeBuffer(l));
|
|
1418
|
+
}
|
|
1419
|
+
},
|
|
1420
|
+
end() {
|
|
1421
|
+
keep(enc.flush());
|
|
1422
|
+
return out;
|
|
1423
|
+
}
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
async function encodeMp3(channels, sampleRate, kbps = 192) {
|
|
1427
|
+
const numCh = Math.min(channels.length, 2);
|
|
1428
|
+
const mp3 = await mp3Stream(sampleRate, kbps, numCh);
|
|
1429
|
+
mp3.push(floatToInt16(channels[0] ?? new Float32Array()), numCh > 1 ? floatToInt16(channels[1]) : void 0);
|
|
1430
|
+
return concatBytes(mp3.end());
|
|
1382
1431
|
}
|
|
1383
1432
|
|
|
1384
1433
|
// src/player/midi.ts
|
|
@@ -1424,6 +1473,11 @@ function trackChunk(raw, head) {
|
|
|
1424
1473
|
const track = [...head];
|
|
1425
1474
|
let last = 0;
|
|
1426
1475
|
for (const e of raw) {
|
|
1476
|
+
if (e.meta) {
|
|
1477
|
+
track.push(...vlq(e.tick - last), ...e.meta);
|
|
1478
|
+
last = e.tick;
|
|
1479
|
+
continue;
|
|
1480
|
+
}
|
|
1427
1481
|
const status = e.status !== void 0 ? e.status | e.ch & 15 : (e.on ? 144 : 128) | e.ch & 15;
|
|
1428
1482
|
track.push(...vlq(e.tick - last), status, e.note & 127, e.vel & 127);
|
|
1429
1483
|
last = e.tick;
|
|
@@ -1431,22 +1485,22 @@ function trackChunk(raw, head) {
|
|
|
1431
1485
|
track.push(...vlq(0), 255, 47, 0);
|
|
1432
1486
|
return [77, 84, 114, 107, ...u32be(track.length), ...track];
|
|
1433
1487
|
}
|
|
1434
|
-
function
|
|
1488
|
+
function melodyEvents(schedule, offset = 0) {
|
|
1435
1489
|
const melody = [];
|
|
1436
1490
|
const hasGlide = schedule.events.some((ev) => ev.glide === true);
|
|
1437
1491
|
if (hasGlide) melody.push(...bendRangeSetup());
|
|
1438
1492
|
schedule.events.forEach((ev, i) => {
|
|
1439
1493
|
if (ev.glide === true) return;
|
|
1440
1494
|
for (const g of graceTouches(ev)) {
|
|
1441
|
-
const on = Math.max(Math.round(g.beat * PPQ), 0);
|
|
1495
|
+
const on = Math.max(Math.round(g.beat * PPQ) + offset, 0);
|
|
1442
1496
|
melody.push({ tick: on, on: true, note: g.midi, vel: 70, ch: 0 });
|
|
1443
|
-
melody.push({ tick: Math.max(on + 1, Math.round((g.beat + GRACE_STEP) * PPQ)), on: false, note: g.midi, vel: 0, ch: 0 });
|
|
1497
|
+
melody.push({ tick: Math.max(on + 1, Math.round((g.beat + GRACE_STEP) * PPQ) + offset), on: false, note: g.midi, vel: 0, ch: 0 });
|
|
1444
1498
|
}
|
|
1445
1499
|
if (ev.midi === null) return;
|
|
1446
|
-
const start = Math.round(ev.beat * PPQ);
|
|
1500
|
+
const start = Math.round(ev.beat * PPQ) + offset;
|
|
1447
1501
|
const targets = glideTargets(schedule.events, i);
|
|
1448
1502
|
const last = targets[targets.length - 1] ?? ev;
|
|
1449
|
-
const end = Math.max(Math.round((last.beat + last.durationBeats) * PPQ), start + 1);
|
|
1503
|
+
const end = Math.max(Math.round((last.beat + last.durationBeats) * PPQ) + offset, start + 1);
|
|
1450
1504
|
melody.push({ tick: start, on: true, note: ev.midi, vel: 100, ch: 0 });
|
|
1451
1505
|
melody.push({ tick: end, on: false, note: ev.midi, vel: 0, ch: 0 });
|
|
1452
1506
|
let from = ev;
|
|
@@ -1456,72 +1510,90 @@ function encodeMidi(schedule, opts) {
|
|
|
1456
1510
|
const u = n / BEND_STEPS;
|
|
1457
1511
|
const beat = glideStart + (to.beat - glideStart) * u;
|
|
1458
1512
|
const semis = from.midi - ev.midi + (to.midi - from.midi) * sCurve(u);
|
|
1459
|
-
melody.push(bendEvent(Math.round(beat * PPQ), semis));
|
|
1513
|
+
melody.push(bendEvent(Math.round(beat * PPQ) + offset, semis));
|
|
1460
1514
|
}
|
|
1461
1515
|
from = to;
|
|
1462
1516
|
}
|
|
1463
1517
|
if (targets.length > 0) melody.push(bendEvent(end, 0));
|
|
1464
1518
|
});
|
|
1519
|
+
return melody;
|
|
1520
|
+
}
|
|
1521
|
+
function drumEvents(schedule, drums, offset = 0) {
|
|
1522
|
+
const drum = [];
|
|
1523
|
+
for (const seg of schedule.tempo) {
|
|
1524
|
+
const pattern = typeof drums === "function" ? drums(seg) : drums;
|
|
1525
|
+
if (!pattern?.length) continue;
|
|
1526
|
+
const end = seg === schedule.tempo[schedule.tempo.length - 1] ? Math.ceil(schedule.totalBeats) : seg.endBeat;
|
|
1527
|
+
for (let k = 0; seg.beat + k / seg.scale < end - 1e-6; k++) {
|
|
1528
|
+
const note = DRUM_NOTE[pattern[k % pattern.length]];
|
|
1529
|
+
const t = Math.round((seg.beat + k / seg.scale) * PPQ) + offset;
|
|
1530
|
+
drum.push({ tick: t, on: true, note, vel: 100, ch: 9 });
|
|
1531
|
+
drum.push({ tick: t + Math.round(PPQ / 4), on: false, note, vel: 0, ch: 9 });
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
return drum;
|
|
1535
|
+
}
|
|
1536
|
+
function midiFile(chunks) {
|
|
1537
|
+
const format = chunks.length > 1 ? 1 : 0;
|
|
1538
|
+
const header = [77, 84, 104, 100, ...u32be(6), 0, format, chunks.length >> 8 & 255, chunks.length & 255, PPQ >> 8 & 255, PPQ & 255];
|
|
1539
|
+
return new Uint8Array([...header, ...chunks.flat()]);
|
|
1540
|
+
}
|
|
1541
|
+
function meta(type, data) {
|
|
1542
|
+
return [255, type, ...vlq(data.length), ...data];
|
|
1543
|
+
}
|
|
1544
|
+
function encodeMidi(schedule, opts) {
|
|
1465
1545
|
const usPerBeat = Math.round(6e7 / opts.bpm);
|
|
1466
1546
|
const head = [];
|
|
1467
1547
|
if (opts.name) head.push(...vlq(0), 255, 3, ...vlq(utf8(opts.name).length), ...utf8(opts.name));
|
|
1468
1548
|
head.push(...vlq(0), 255, 81, 3, usPerBeat >> 16 & 255, usPerBeat >> 8 & 255, usPerBeat & 255);
|
|
1469
|
-
const chunks = [trackChunk(
|
|
1549
|
+
const chunks = [trackChunk(melodyEvents(schedule), head)];
|
|
1470
1550
|
if (typeof opts.drums === "function" || opts.drums && opts.drums.length > 0) {
|
|
1471
|
-
const drum =
|
|
1472
|
-
for (const seg of schedule.tempo) {
|
|
1473
|
-
const pattern = typeof opts.drums === "function" ? opts.drums(seg) : opts.drums;
|
|
1474
|
-
if (!pattern?.length) continue;
|
|
1475
|
-
const end = seg === schedule.tempo[schedule.tempo.length - 1] ? Math.ceil(schedule.totalBeats) : seg.endBeat;
|
|
1476
|
-
for (let k = 0; seg.beat + k / seg.scale < end - 1e-6; k++) {
|
|
1477
|
-
const note = DRUM_NOTE[pattern[k % pattern.length]];
|
|
1478
|
-
const t = Math.round((seg.beat + k / seg.scale) * PPQ);
|
|
1479
|
-
drum.push({ tick: t, on: true, note, vel: 100, ch: 9 });
|
|
1480
|
-
drum.push({ tick: t + Math.round(PPQ / 4), on: false, note, vel: 0, ch: 9 });
|
|
1481
|
-
}
|
|
1482
|
-
}
|
|
1551
|
+
const drum = drumEvents(schedule, opts.drums);
|
|
1483
1552
|
chunks.push(trackChunk(drum, [...vlq(0), 255, 3, ...vlq(5), 68, 114, 117, 109, 115]));
|
|
1484
1553
|
}
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
chunks.length >> 8 & 255,
|
|
1495
|
-
chunks.length & 255,
|
|
1496
|
-
PPQ >> 8 & 255,
|
|
1497
|
-
PPQ & 255
|
|
1498
|
-
];
|
|
1499
|
-
return new Uint8Array([...header, ...chunks.flat()]);
|
|
1554
|
+
return midiFile(chunks);
|
|
1555
|
+
}
|
|
1556
|
+
function exportSchedule(doc, o) {
|
|
1557
|
+
return buildSchedule(doc, { tonic: o.tonic, baseOctave: o.baseOctave, laySpeeds: o.laySpeeds, repeats: o.repeats ?? true, excerpt: o.excerpt });
|
|
1558
|
+
}
|
|
1559
|
+
function taalDrums(seg) {
|
|
1560
|
+
if (seg.taal === null) return void 0;
|
|
1561
|
+
const id = seg.taal?.id;
|
|
1562
|
+
return drumPattern(id !== void 0 && id in TAALS ? TAALS[id] : { numBeats: 4, sam: 0 });
|
|
1500
1563
|
}
|
|
1501
1564
|
function safeName2(title) {
|
|
1502
1565
|
return (title ?? "").replace(/[\\/:*?"<>|]+/g, "").trim() || "swaralipi";
|
|
1503
1566
|
}
|
|
1504
1567
|
function exportMidi(doc, options = {}) {
|
|
1505
|
-
const schedule =
|
|
1506
|
-
tonic: options.tonic,
|
|
1507
|
-
baseOctave: options.baseOctave,
|
|
1508
|
-
laySpeeds: options.laySpeeds,
|
|
1509
|
-
repeats: options.repeats ?? true
|
|
1510
|
-
});
|
|
1568
|
+
const schedule = exportSchedule(doc, options);
|
|
1511
1569
|
const bpm = options.bpm ?? doc.meta.bpm ?? 90;
|
|
1512
|
-
const
|
|
1513
|
-
const id = seg.taal?.id;
|
|
1514
|
-
if (seg.taal === null) return void 0;
|
|
1515
|
-
return drumPattern(id !== void 0 && id in TAALS ? TAALS[id] : { numBeats: 4, sam: 0 });
|
|
1516
|
-
} : void 0;
|
|
1517
|
-
const bytes = encodeMidi(schedule, { bpm, name: options.name ?? doc.meta.title, drums });
|
|
1570
|
+
const bytes = encodeMidi(schedule, { bpm, name: options.name ?? doc.meta.title, drums: options.drums ? taalDrums : void 0 });
|
|
1518
1571
|
return {
|
|
1519
1572
|
blob: new Blob([bytes], { type: "audio/midi" }),
|
|
1520
1573
|
filename: `${safeName2(doc.meta.title)}.mid`,
|
|
1521
1574
|
mimeType: "audio/midi"
|
|
1522
1575
|
};
|
|
1523
1576
|
}
|
|
1577
|
+
function exportMidiSet(items, name) {
|
|
1578
|
+
const melody = [];
|
|
1579
|
+
const drum = [];
|
|
1580
|
+
let beat = 0;
|
|
1581
|
+
for (const { doc, options = {} } of items) {
|
|
1582
|
+
const schedule = exportSchedule(doc, options);
|
|
1583
|
+
const tick = beat * PPQ;
|
|
1584
|
+
const usPerBeat = Math.round(6e7 / (options.bpm ?? doc.meta.bpm ?? 90));
|
|
1585
|
+
const at = (bytes2) => ({ tick, on: false, note: 0, vel: 0, ch: 0, meta: bytes2 });
|
|
1586
|
+
melody.push(at(meta(81, [usPerBeat >> 16 & 255, usPerBeat >> 8 & 255, usPerBeat & 255])));
|
|
1587
|
+
melody.push(at(meta(6, utf8(options.name ?? doc.meta.title ?? ""))), ...melodyEvents(schedule, tick));
|
|
1588
|
+
if (options.drums) drum.push(...drumEvents(schedule, taalDrums, tick));
|
|
1589
|
+
beat += Math.ceil(schedule.totalBeats) + 2;
|
|
1590
|
+
}
|
|
1591
|
+
const chunks = [trackChunk(melody, [...vlq(0), ...meta(3, utf8(name))])];
|
|
1592
|
+
if (drum.length > 0) chunks.push(trackChunk(drum, [...vlq(0), ...meta(3, utf8("Drums"))]));
|
|
1593
|
+
const bytes = midiFile(chunks);
|
|
1594
|
+
return { blob: new Blob([bytes], { type: "audio/midi" }), filename: `${safeName2(name)}.mid`, mimeType: "audio/midi" };
|
|
1595
|
+
}
|
|
1524
1596
|
|
|
1525
|
-
export { SwaralipiPlayer, encodeMidi, encodeMp3, encodeWav, exportAudio, exportMidi };
|
|
1597
|
+
export { SwaralipiPlayer, encodeMidi, encodeMp3, encodeWav, exportAudio, exportMidi, exportMidiSet, mp3Stream };
|
|
1526
1598
|
//# sourceMappingURL=index.js.map
|
|
1527
1599
|
//# sourceMappingURL=index.js.map
|