@real-music-packages/web-core 0.34.0 → 0.34.1

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/audio.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  SALAMANDER_URLS_FULL,
12
12
  createSalamanderSampler,
13
13
  generateReverb
14
- } from "./chunk-JVGAABTK.js";
14
+ } from "./chunk-74TMWRNK.js";
15
15
 
16
16
  // src/engine.ts
17
17
  var browser = typeof window !== "undefined";
@@ -49,7 +49,11 @@ function createSalamanderSampler(Tone, opts) {
49
49
  urls: opts.urls,
50
50
  baseUrl: opts.baseUrl,
51
51
  release: opts.release,
52
- attack: opts.attack,
52
+ // Never let `undefined` through: Tone.Sampler stores it verbatim, each
53
+ // note's source then gets `fadeIn: undefined`, and toSeconds(undefined)
54
+ // means "now" — a fade-in equal to the context's clock. Audibly, every
55
+ // chord after the first swells in like a pad, slower as playback runs.
56
+ attack: opts.attack ?? 0,
53
57
  onload: opts.onload,
54
58
  onerror: opts.onerror
55
59
  });
@@ -73,4 +77,4 @@ export {
73
77
  createSalamanderSampler,
74
78
  generateReverb
75
79
  };
76
- //# sourceMappingURL=chunk-JVGAABTK.js.map
80
+ //# sourceMappingURL=chunk-74TMWRNK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/salamander.ts","../src/audioHelpers.ts"],"sourcesContent":["export const SALAMANDER_CDN_BASE = 'https://tonejs.github.io/audio/salamander/';\n\n/** 8-anchor sample set (Stave uses these from the CDN). */\nexport const SALAMANDER_URLS_8: Record<string, string> = {\n C2: 'C2.mp3', 'F#2': 'Fs2.mp3', C3: 'C3.mp3', 'F#3': 'Fs3.mp3',\n C4: 'C4.mp3', 'F#4': 'Fs4.mp3', C5: 'C5.mp3', 'F#5': 'Fs5.mp3',\n};\n\n/** Full chromatic-anchor set A0..C8 (RET ships these locally under /audio/salamander/). */\nexport const SALAMANDER_URLS_FULL: Record<string, string> = {\n A0: 'A0.mp3', C1: 'C1.mp3', 'D#1': 'Ds1.mp3', 'F#1': 'Fs1.mp3', A1: 'A1.mp3',\n C2: 'C2.mp3', 'D#2': 'Ds2.mp3', 'F#2': 'Fs2.mp3', A2: 'A2.mp3',\n C3: 'C3.mp3', 'D#3': 'Ds3.mp3', 'F#3': 'Fs3.mp3', A3: 'A3.mp3',\n C4: 'C4.mp3', 'D#4': 'Ds4.mp3', 'F#4': 'Fs4.mp3', A4: 'A4.mp3',\n C5: 'C5.mp3', 'D#5': 'Ds5.mp3', 'F#5': 'Fs5.mp3', A5: 'A5.mp3',\n C6: 'C6.mp3', 'D#6': 'Ds6.mp3', 'F#6': 'Fs6.mp3', A6: 'A6.mp3',\n C7: 'C7.mp3', 'D#7': 'Ds7.mp3', 'F#7': 'Fs7.mp3', A7: 'A7.mp3',\n C8: 'C8.mp3',\n};\n","// Tone is provided by the consumer (peer dep); type loosely to avoid coupling.\ntype ToneModule = any; // eslint-disable-line @typescript-eslint/no-explicit-any\n\nexport interface SalamanderSamplerOpts {\n urls: Record<string, string>;\n baseUrl: string;\n release: number;\n volumeDb?: number;\n attack?: number;\n onload?: () => void;\n onerror?: (e: unknown) => void;\n /** Route the sampler straight to the speakers. Default true (preserves the\n * inline behavior both engines had). Pass false to build a custom signal\n * chain off the sampler instead (e.g. the promo mastering bus). */\n connectToDestination?: boolean;\n}\n\n/** Create a Salamander Tone.Sampler. By default routed to destination, mirroring\n * the exact `new Tone.Sampler({...}).toDestination()` both engines did inline.\n * With `connectToDestination:false` it returns an unrouted sampler so the caller\n * can insert a mastering chain. */\nexport function createSalamanderSampler(Tone: ToneModule, opts: SalamanderSamplerOpts) {\n const sampler = new Tone.Sampler({\n urls: opts.urls,\n baseUrl: opts.baseUrl,\n release: opts.release,\n // Never let `undefined` through: Tone.Sampler stores it verbatim, each\n // note's source then gets `fadeIn: undefined`, and toSeconds(undefined)\n // means \"now\" — a fade-in equal to the context's clock. Audibly, every\n // chord after the first swells in like a pad, slower as playback runs.\n attack: opts.attack ?? 0,\n onload: opts.onload,\n onerror: opts.onerror,\n });\n if (opts.connectToDestination !== false) sampler.toDestination();\n if (opts.volumeDb !== undefined) sampler.volume.value = opts.volumeDb;\n return sampler;\n}\n\n/** Generate a Tone.Reverb, racing reverb.generate() against a timeout so it can\n * never hang init on iOS. Returns the reverb if generated, else null. Caller\n * wires routing (toDestination / reroute). Mirrors RET's addReverbInBackground. */\nexport async function generateReverb(\n Tone: ToneModule,\n opts: { decay: number; wet: number },\n timeoutMs: number,\n): Promise<any | null> { // eslint-disable-line @typescript-eslint/no-explicit-any\n const reverb = new Tone.Reverb(opts);\n const ok = await Promise.race([\n reverb.generate().then(() => true),\n new Promise<boolean>((r) => setTimeout(() => r(false), timeoutMs)),\n ]);\n return ok ? reverb : null;\n}\n"],"mappings":";AAAO,IAAM,sBAAsB;AAG5B,IAAM,oBAA4C;AAAA,EACvD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,IAAI;AAAA,EAAU,OAAO;AAAA,EACrD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,IAAI;AAAA,EAAU,OAAO;AACvD;AAGO,IAAM,uBAA+C;AAAA,EAC1D,IAAI;AAAA,EAAU,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACpE,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AACN;;;ACGO,SAAS,wBAAwB,MAAkB,MAA6B;AACrF,QAAM,UAAU,IAAI,KAAK,QAAQ;AAAA,IAC/B,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,SAAS,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,IAKd,QAAQ,KAAK,UAAU;AAAA,IACvB,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,EAChB,CAAC;AACD,MAAI,KAAK,yBAAyB,MAAO,SAAQ,cAAc;AAC/D,MAAI,KAAK,aAAa,OAAW,SAAQ,OAAO,QAAQ,KAAK;AAC7D,SAAO;AACT;AAKA,eAAsB,eACpB,MACA,MACA,WACqB;AACrB,QAAM,SAAS,IAAI,KAAK,OAAO,IAAI;AACnC,QAAM,KAAK,MAAM,QAAQ,KAAK;AAAA,IAC5B,OAAO,SAAS,EAAE,KAAK,MAAM,IAAI;AAAA,IACjC,IAAI,QAAiB,CAAC,MAAM,WAAW,MAAM,EAAE,KAAK,GAAG,SAAS,CAAC;AAAA,EACnE,CAAC;AACD,SAAO,KAAK,SAAS;AACvB;","names":[]}
package/dist/promo.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  SALAMANDER_URLS_FULL,
5
5
  createSalamanderSampler,
6
6
  generateReverb
7
- } from "./chunk-JVGAABTK.js";
7
+ } from "./chunk-74TMWRNK.js";
8
8
 
9
9
  // src/promo.ts
10
10
  function parseMidi(buf) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@real-music-packages/web-core",
3
- "version": "0.34.0",
3
+ "version": "0.34.1",
4
4
  "description": "Shared music-theory + audio primitives for the music-suite web apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/salamander.ts","../src/audioHelpers.ts"],"sourcesContent":["export const SALAMANDER_CDN_BASE = 'https://tonejs.github.io/audio/salamander/';\n\n/** 8-anchor sample set (Stave uses these from the CDN). */\nexport const SALAMANDER_URLS_8: Record<string, string> = {\n C2: 'C2.mp3', 'F#2': 'Fs2.mp3', C3: 'C3.mp3', 'F#3': 'Fs3.mp3',\n C4: 'C4.mp3', 'F#4': 'Fs4.mp3', C5: 'C5.mp3', 'F#5': 'Fs5.mp3',\n};\n\n/** Full chromatic-anchor set A0..C8 (RET ships these locally under /audio/salamander/). */\nexport const SALAMANDER_URLS_FULL: Record<string, string> = {\n A0: 'A0.mp3', C1: 'C1.mp3', 'D#1': 'Ds1.mp3', 'F#1': 'Fs1.mp3', A1: 'A1.mp3',\n C2: 'C2.mp3', 'D#2': 'Ds2.mp3', 'F#2': 'Fs2.mp3', A2: 'A2.mp3',\n C3: 'C3.mp3', 'D#3': 'Ds3.mp3', 'F#3': 'Fs3.mp3', A3: 'A3.mp3',\n C4: 'C4.mp3', 'D#4': 'Ds4.mp3', 'F#4': 'Fs4.mp3', A4: 'A4.mp3',\n C5: 'C5.mp3', 'D#5': 'Ds5.mp3', 'F#5': 'Fs5.mp3', A5: 'A5.mp3',\n C6: 'C6.mp3', 'D#6': 'Ds6.mp3', 'F#6': 'Fs6.mp3', A6: 'A6.mp3',\n C7: 'C7.mp3', 'D#7': 'Ds7.mp3', 'F#7': 'Fs7.mp3', A7: 'A7.mp3',\n C8: 'C8.mp3',\n};\n","// Tone is provided by the consumer (peer dep); type loosely to avoid coupling.\ntype ToneModule = any; // eslint-disable-line @typescript-eslint/no-explicit-any\n\nexport interface SalamanderSamplerOpts {\n urls: Record<string, string>;\n baseUrl: string;\n release: number;\n volumeDb?: number;\n attack?: number;\n onload?: () => void;\n onerror?: (e: unknown) => void;\n /** Route the sampler straight to the speakers. Default true (preserves the\n * inline behavior both engines had). Pass false to build a custom signal\n * chain off the sampler instead (e.g. the promo mastering bus). */\n connectToDestination?: boolean;\n}\n\n/** Create a Salamander Tone.Sampler. By default routed to destination, mirroring\n * the exact `new Tone.Sampler({...}).toDestination()` both engines did inline.\n * With `connectToDestination:false` it returns an unrouted sampler so the caller\n * can insert a mastering chain. */\nexport function createSalamanderSampler(Tone: ToneModule, opts: SalamanderSamplerOpts) {\n const sampler = new Tone.Sampler({\n urls: opts.urls,\n baseUrl: opts.baseUrl,\n release: opts.release,\n attack: opts.attack,\n onload: opts.onload,\n onerror: opts.onerror,\n });\n if (opts.connectToDestination !== false) sampler.toDestination();\n if (opts.volumeDb !== undefined) sampler.volume.value = opts.volumeDb;\n return sampler;\n}\n\n/** Generate a Tone.Reverb, racing reverb.generate() against a timeout so it can\n * never hang init on iOS. Returns the reverb if generated, else null. Caller\n * wires routing (toDestination / reroute). Mirrors RET's addReverbInBackground. */\nexport async function generateReverb(\n Tone: ToneModule,\n opts: { decay: number; wet: number },\n timeoutMs: number,\n): Promise<any | null> { // eslint-disable-line @typescript-eslint/no-explicit-any\n const reverb = new Tone.Reverb(opts);\n const ok = await Promise.race([\n reverb.generate().then(() => true),\n new Promise<boolean>((r) => setTimeout(() => r(false), timeoutMs)),\n ]);\n return ok ? reverb : null;\n}\n"],"mappings":";AAAO,IAAM,sBAAsB;AAG5B,IAAM,oBAA4C;AAAA,EACvD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,IAAI;AAAA,EAAU,OAAO;AAAA,EACrD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,IAAI;AAAA,EAAU,OAAO;AACvD;AAGO,IAAM,uBAA+C;AAAA,EAC1D,IAAI;AAAA,EAAU,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACpE,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AAAA,EAAU,OAAO;AAAA,EAAW,OAAO;AAAA,EAAW,IAAI;AAAA,EACtD,IAAI;AACN;;;ACGO,SAAS,wBAAwB,MAAkB,MAA6B;AACrF,QAAM,UAAU,IAAI,KAAK,QAAQ;AAAA,IAC/B,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,SAAS,KAAK;AAAA,IACd,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,EAChB,CAAC;AACD,MAAI,KAAK,yBAAyB,MAAO,SAAQ,cAAc;AAC/D,MAAI,KAAK,aAAa,OAAW,SAAQ,OAAO,QAAQ,KAAK;AAC7D,SAAO;AACT;AAKA,eAAsB,eACpB,MACA,MACA,WACqB;AACrB,QAAM,SAAS,IAAI,KAAK,OAAO,IAAI;AACnC,QAAM,KAAK,MAAM,QAAQ,KAAK;AAAA,IAC5B,OAAO,SAAS,EAAE,KAAK,MAAM,IAAI;AAAA,IACjC,IAAI,QAAiB,CAAC,MAAM,WAAW,MAAM,EAAE,KAAK,GAAG,SAAS,CAAC;AAAA,EACnE,CAAC;AACD,SAAO,KAAK,SAAS;AACvB;","names":[]}