@adatechnology/game-audio 0.1.2 → 0.2.0

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.js CHANGED
@@ -283,8 +283,8 @@ function finishModulator(pending, sourceFrequency) {
283
283
  const depth = typeof modulator.depth === "object" && "scaleOf" in modulator.depth ? sourceFrequency * modulator.depth.factor : pending.depth ?? 0;
284
284
  return { target: modulator.target, ...modulator.wave ? { wave: modulator.wave } : {}, rate: pending.rate, depth, ...modulator.base === void 0 ? {} : { base: modulator.base } };
285
285
  }
286
- function finishEnvelope(envelope, duration, level) {
287
- return envelope.map(([time, value, curve, fixed2]) => ({ time: timeOf(time, duration), value: fixed2 === "fixed" ? value : value * level, curve }));
286
+ function finishEnvelope(envelope2, duration, level) {
287
+ return envelope2.map(([time, value, curve, fixed2]) => ({ time: timeOf(time, duration), value: fixed2 === "fixed" ? value : value * level, curve }));
288
288
  }
289
289
  function planLayer(layer, scope, defaults, levelInEnvelope, soundLevel) {
290
290
  const pending = drawLayer(layer, scope);
@@ -523,6 +523,83 @@ function noiseClassRecipe(row, id = `sfx_${row.id}`) {
523
523
  }
524
524
  var GAME_SFX_BANK = { id: "game_sfx", sounds: [...GAME_SFX_CLASSES, GAME_SFX_FALLBACK].map((row) => noiseClassRecipe(row)) };
525
525
 
526
+ // src/recipes/scene.ts
527
+ var ATTACK = 2e-3;
528
+ function lengthOf(d, attack) {
529
+ if (typeof d === "number") return attack + d;
530
+ if (Array.isArray(d)) return [attack + d[0], attack + d[1]];
531
+ return { ...d, add: (d.add ?? 0) + attack };
532
+ }
533
+ var envelope = (attack) => [
534
+ [0, 1e-4, "set", "fixed"],
535
+ [attack, 1, "exp"],
536
+ ["1d", 1e-4, "exp", "fixed"]
537
+ ];
538
+ function sceneNoise(o) {
539
+ const a = o.a ?? ATTACK;
540
+ const over = typeof o.d === "number" ? o.d : 0;
541
+ return {
542
+ filters: {
543
+ mode: "serial",
544
+ bank: [{ type: o.type ?? "lowpass", frequency: o.f2 === void 0 ? { set: o.f } : { set: o.f, to: o.f2, curve: "exp", over }, q: o.q ?? 0.7 }]
545
+ },
546
+ duration: lengthOf(o.d, a),
547
+ gain: o.vol,
548
+ ...o.delay === void 0 ? {} : { at: o.delay },
549
+ ...o.wet === void 0 ? {} : { wet: o.wet },
550
+ source: { kind: "noise", offset: "random", offsetScale: 1.5, loop: true },
551
+ envelope: envelope(a)
552
+ };
553
+ }
554
+ function sceneTone(o) {
555
+ return {
556
+ source: { kind: "osc", wave: o.wave ?? "sine", frequency: { from: o.f, to: o.f2 ?? "from", curve: "exp", over: "duration" } },
557
+ duration: lengthOf(o.d, ATTACK),
558
+ gain: o.vol,
559
+ ...o.delay === void 0 ? {} : { at: o.delay },
560
+ ...o.wet === void 0 ? {} : { wet: o.wet },
561
+ envelope: envelope(ATTACK)
562
+ };
563
+ }
564
+ function sceneVoice(o) {
565
+ return {
566
+ duration: lengthOf(o.d, 0),
567
+ gain: o.vol,
568
+ wet: 0.45,
569
+ source: {
570
+ kind: "formant_voice",
571
+ wave: o.wave ?? "sawtooth",
572
+ frequency: { from: o.f0, to: o.f1, curve: "linear", over: "duration" },
573
+ vibrato: { rate: [4, 10], depth: 0.08 },
574
+ formants: [
575
+ { frequency: o.fA, q: 4 },
576
+ { frequency: o.fB, q: 6 }
577
+ ],
578
+ breath: { frequency: o.fB, q: 1.1, gain: o.noise },
579
+ mix: 3.2
580
+ },
581
+ envelope: [
582
+ [0, 1e-4, "set", "fixed"],
583
+ [0.1, 1, "exp"],
584
+ ["0.6d", 1, "set"],
585
+ ["1d", 1e-4, "exp", "fixed"]
586
+ ]
587
+ };
588
+ }
589
+ var sceneMany = (count, make) => Array.from({ length: count }, make);
590
+ function sceneRecipe(id, layers, line, options = {}) {
591
+ return {
592
+ id,
593
+ bus: options.bus ?? "world",
594
+ pan: true,
595
+ layers,
596
+ falloff: DISTANCE_CURVES.art_scene,
597
+ ...options.vars ? { vars: options.vars } : {},
598
+ ...options.group ? { group: options.group } : {},
599
+ sources: [`cena:${line}`]
600
+ };
601
+ }
602
+
526
603
  // src/library/crowd_rumble.json
527
604
  var crowd_rumble_default = {
528
605
  id: "crowd_rumble",
@@ -1076,10 +1153,10 @@ function realizeCalls(plan, target) {
1076
1153
  assign(filter.frequency, band.frequency, time);
1077
1154
  if (band.q !== void 0) filter.Q.value = band.q;
1078
1155
  }
1079
- const envelope = context.createGain();
1080
- applyEnvelope(envelope.gain, layer.envelope, time);
1081
- oscillator.connect(envelope);
1082
- envelope.connect(filter);
1156
+ const envelope2 = context.createGain();
1157
+ applyEnvelope(envelope2.gain, layer.envelope, time);
1158
+ oscillator.connect(envelope2);
1159
+ envelope2.connect(filter);
1083
1160
  oscillator.start(time);
1084
1161
  oscillator.stop(end(layer, time));
1085
1162
  return oscillator;
@@ -1116,12 +1193,12 @@ function realizeNoiseLayer(plan, layer, target) {
1116
1193
  rampTo(node.frequency, filter.frequency, time);
1117
1194
  return node;
1118
1195
  });
1119
- const envelope = context.createGain();
1120
- applyEnvelope(envelope.gain, layer.envelope, time);
1196
+ const envelope2 = context.createGain();
1197
+ applyEnvelope(envelope2.gain, layer.envelope, time);
1121
1198
  let tail = source;
1122
1199
  for (const filter of filters) tail = tail.connect(filter);
1123
- tail.connect(envelope);
1124
- envelope.connect(outputStage(plan, layer, target));
1200
+ tail.connect(envelope2);
1201
+ envelope2.connect(outputStage(plan, layer, target));
1125
1202
  source.start(time, layer.source.kind === "noise" ? layer.source.offset : 0);
1126
1203
  source.stop(end2(layer, time));
1127
1204
  return [source];
@@ -1135,10 +1212,10 @@ function realizeToneLayer(plan, layer, target) {
1135
1212
  assign(oscillator.frequency, layer.source.frequency, time);
1136
1213
  rampTo(oscillator.frequency, layer.source.frequency, time);
1137
1214
  }
1138
- const envelope = context.createGain();
1139
- applyEnvelope(envelope.gain, layer.envelope, time);
1140
- oscillator.connect(envelope);
1141
- envelope.connect(outputStage(plan, layer, target));
1215
+ const envelope2 = context.createGain();
1216
+ applyEnvelope(envelope2.gain, layer.envelope, time);
1217
+ oscillator.connect(envelope2);
1218
+ envelope2.connect(outputStage(plan, layer, target));
1142
1219
  oscillator.start(time);
1143
1220
  oscillator.stop(end2(layer, time));
1144
1221
  return [oscillator];
@@ -1167,10 +1244,10 @@ function realizeVoiceLayer(plan, layer, target) {
1167
1244
  breathBand.connect(breathLevel);
1168
1245
  for (const formant of formants) formant.connect(mix);
1169
1246
  breathLevel.connect(mix);
1170
- const envelope = context.createGain();
1171
- applyEnvelope(envelope.gain, layer.envelope, time);
1172
- mix.connect(envelope);
1173
- envelope.connect(outputStage(plan, layer, target));
1247
+ const envelope2 = context.createGain();
1248
+ applyEnvelope(envelope2.gain, layer.envelope, time);
1249
+ mix.connect(envelope2);
1250
+ envelope2.connect(outputStage(plan, layer, target));
1174
1251
  const stop = end2(layer, time);
1175
1252
  oscillator.start(time);
1176
1253
  vibrato.start(time);
@@ -1208,17 +1285,17 @@ function realizeSiren(plan, target) {
1208
1285
  return { lfo, depth, target: modulator.target };
1209
1286
  });
1210
1287
  const lfos = depths.map(({ lfo }) => lfo);
1211
- const envelope = context.createGain();
1212
- applyEnvelope(envelope.gain, layer.envelope, time);
1213
- for (const { depth, target: modulated } of depths) if (modulated === "gain") depth.connect(envelope.gain);
1288
+ const envelope2 = context.createGain();
1289
+ applyEnvelope(envelope2.gain, layer.envelope, time);
1290
+ for (const { depth, target: modulated } of depths) if (modulated === "gain") depth.connect(envelope2.gain);
1214
1291
  const filters = (layer.filters?.bank ?? []).map((filter) => filterNode(context, filter, time));
1215
1292
  let tail = oscillator;
1216
1293
  for (const filter of filters) tail = tail.connect(filter);
1217
- tail.connect(envelope);
1218
- envelope.connect(target.output);
1294
+ tail.connect(envelope2);
1295
+ envelope2.connect(target.output);
1219
1296
  if (layer.wet && target.wet) {
1220
1297
  const send = gainNode(context, layer.wet);
1221
- envelope.connect(send);
1298
+ envelope2.connect(send);
1222
1299
  send.connect(target.wet);
1223
1300
  }
1224
1301
  const stop = end2(layer, time);
@@ -1234,11 +1311,11 @@ function noiseLayer(layer, target, time) {
1234
1311
  const { context } = target;
1235
1312
  const source = noiseSource(target, layer.source.kind === "noise" && layer.source.loop);
1236
1313
  const filters = (layer.filters?.bank ?? []).map((filter) => filterNode(context, filter, time));
1237
- const envelope = context.createGain();
1238
- applyEnvelope(envelope.gain, layer.envelope, time);
1314
+ const envelope2 = context.createGain();
1315
+ applyEnvelope(envelope2.gain, layer.envelope, time);
1239
1316
  let tail = source;
1240
1317
  for (const filter of filters) tail = tail.connect(filter);
1241
- tail.connect(envelope).connect(target.output);
1318
+ tail.connect(envelope2).connect(target.output);
1242
1319
  source.start(time, layer.source.kind === "noise" ? layer.source.offset : 0);
1243
1320
  source.stop(time + layer.duration + layer.tail);
1244
1321
  return source;
@@ -1251,9 +1328,9 @@ function toneLayer(layer, target, time) {
1251
1328
  assign(oscillator.frequency, layer.source.frequency, time);
1252
1329
  rampTo(oscillator.frequency, layer.source.frequency, time);
1253
1330
  }
1254
- const envelope = context.createGain();
1255
- applyEnvelope(envelope.gain, layer.envelope, time);
1256
- oscillator.connect(envelope).connect(target.output);
1331
+ const envelope2 = context.createGain();
1332
+ applyEnvelope(envelope2.gain, layer.envelope, time);
1333
+ oscillator.connect(envelope2).connect(target.output);
1257
1334
  oscillator.start(time);
1258
1335
  oscillator.stop(time + layer.duration + layer.tail);
1259
1336
  return oscillator;
@@ -1810,8 +1887,8 @@ function createAudioTestModule(options = {}) {
1810
1887
  const layers2 = planned.layers.map((layer, index) => {
1811
1888
  const source = layer.source.kind === "noise" ? `noise@${layer.source.offset.toFixed(4)}` : layer.source.kind === "osc" ? `${layer.source.wave}@${layer.source.frequency.value ?? layer.source.frequency.from}` : layer.source.kind;
1812
1889
  const filters = (layer.filters?.bank ?? []).map((filter) => `${filter.type}@${(filter.frequency.value ?? filter.frequency.from ?? 0).toFixed(1)}`).join(" ");
1813
- const envelope = layer.envelope.map((point) => `${point.time.toFixed(3)}:${point.value.toPrecision(3)}`).join(" ");
1814
- return ` ${text.sheet.layer} ${index + 1}: ${source} at ${layer.at.toFixed(3)} for ${layer.duration.toFixed(3)} ${filters} [${envelope}]`;
1890
+ const envelope2 = layer.envelope.map((point) => `${point.time.toFixed(3)}:${point.value.toPrecision(3)}`).join(" ");
1891
+ return ` ${text.sheet.layer} ${index + 1}: ${source} at ${layer.at.toFixed(3)} for ${layer.duration.toFixed(3)} ${filters} [${envelope2}]`;
1815
1892
  });
1816
1893
  return [head, ...layers2].join("\n");
1817
1894
  };
@@ -2057,6 +2134,11 @@ export {
2057
2134
  planSound,
2058
2135
  realize,
2059
2136
  resolveMix,
2137
+ sceneMany,
2138
+ sceneNoise,
2139
+ sceneRecipe,
2140
+ sceneTone,
2141
+ sceneVoice,
2060
2142
  streamFor,
2061
2143
  streamSeed,
2062
2144
  unlockContext