audio-mixer-engine 1.3.6 → 1.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.
@@ -992,12 +992,8 @@ class Dl extends Ql {
992
992
  const U = this.activeSources.get(l);
993
993
  U && (U.forEach((F) => {
994
994
  try {
995
- if (F.loop)
996
- F.stop();
997
- else {
998
- const Z = this.engine.audioContext.currentTime, d = F._velocityGain;
999
- d && d.gain.linearRampToValueAtTime(0, Z + 0.05), F.stop(Z + 0.05);
1000
- }
995
+ const Z = F._velocityGain, d = this.engine.audioContext.currentTime, Q = F.loop ? 0.15 : 0.03;
996
+ Z && (Z.gain.setValueAtTime(Z.gain.value, d), Z.gain.exponentialRampToValueAtTime(1e-4, d + Q)), F.stop(d + Q);
1001
997
  } catch {
1002
998
  }
1003
999
  }), U.clear(), this.activeSources.delete(l));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "audio-mixer-engine",
3
- "version": "1.3.6",
3
+ "version": "1.3.7",
4
4
  "description": "Audio engine library for audio mixer applications with MIDI parsing, playback, and synthesis",
5
5
  "main": "dist/audio-mixer-engine.cjs.js",
6
6
  "module": "dist/audio-mixer-engine.es.js",
@@ -138,21 +138,15 @@ export default class LightweightChannelHandle extends ChannelHandle {
138
138
  // Stop all sources for this pitch
139
139
  sources.forEach(source => {
140
140
  try {
141
- // For looping samples, stop immediately
142
- // For non-looping samples, they'll stop naturally
143
- if (source.loop) {
144
- source.stop();
145
- } else {
146
- // Piano notes decay naturally - but we can stop them early if needed
147
- // Apply a quick fade-out for better sound quality
148
- const now = this.engine.audioContext.currentTime;
149
- // Get the velocity gain node (it's connected between source and output)
150
- const velocityGain = source._velocityGain;
151
- if (velocityGain) {
152
- velocityGain.gain.linearRampToValueAtTime(0, now + 0.05); // 50ms fade
153
- }
154
- source.stop(now + 0.05);
141
+ const velocityGain = source._velocityGain;
142
+ const now = this.engine.audioContext.currentTime;
143
+ const fadeTime = source.loop ? 0.15 : 0.03; // longer fade for looping (vocal) sources
144
+ if (velocityGain) {
145
+ // Anchor current value before ramping — prevents jump-to-1 artefact
146
+ velocityGain.gain.setValueAtTime(velocityGain.gain.value, now);
147
+ velocityGain.gain.exponentialRampToValueAtTime(0.0001, now + fadeTime);
155
148
  }
149
+ source.stop(now + fadeTime);
156
150
  } catch (e) {
157
151
  // Source may already be stopped
158
152
  }