fix: honor the soundfont -> baseUrl config
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { SAMPLER_CONSTANTS } from '../../constants/coreConstants';
|
import { SAMPLER_CONSTANTS } from '../../constants/coreConstants';
|
||||||
import { FLUIDR3_INSTRUMENT_MAP } from '../../constants/generalMidiConstants';
|
import { FLUIDR3_INSTRUMENT_MAP } from '../../constants/generalMidiConstants';
|
||||||
|
import { ConfigManager } from '../config/ConfigManager';
|
||||||
import * as Tone from 'tone';
|
import * as Tone from 'tone';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,7 +13,7 @@ export class KGToneBuffersPool {
|
|||||||
|
|
||||||
// Map to store ToneAudioBuffers by instrument name
|
// Map to store ToneAudioBuffers by instrument name
|
||||||
private bufferMap: Map<string, Tone.ToneAudioBuffers> = new Map();
|
private bufferMap: Map<string, Tone.ToneAudioBuffers> = new Map();
|
||||||
|
|
||||||
// Map to store loading promises to prevent duplicate loading and handle race conditions
|
// Map to store loading promises to prevent duplicate loading and handle race conditions
|
||||||
private loadingPromises: Map<string, Promise<Tone.ToneAudioBuffers>> = new Map();
|
private loadingPromises: Map<string, Promise<Tone.ToneAudioBuffers>> = new Map();
|
||||||
|
|
||||||
@@ -89,16 +90,16 @@ export class KGToneBuffersPool {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const buffers = await loadingPromise;
|
const buffers = await loadingPromise;
|
||||||
|
|
||||||
// Cache the fully loaded buffers
|
// Cache the fully loaded buffers
|
||||||
this.bufferMap.set(name, buffers);
|
this.bufferMap.set(name, buffers);
|
||||||
console.log(`KGToneBuffersPool: Cached loaded buffers for ${name}`);
|
console.log(`KGToneBuffersPool: Cached loaded buffers for ${name}`);
|
||||||
|
|
||||||
// Remove from loading promises since it's complete
|
// Remove from loading promises since it's complete
|
||||||
this.loadingPromises.delete(name);
|
this.loadingPromises.delete(name);
|
||||||
this.emitLoadingEvent({ type: 'end', instrument: name });
|
this.emitLoadingEvent({ type: 'end', instrument: name });
|
||||||
console.log(`[KGToneBuffersPool] end: Active load count: ${this.getActiveLoadCount()}`);
|
console.log(`[KGToneBuffersPool] end: Active load count: ${this.getActiveLoadCount()}`);
|
||||||
|
|
||||||
return buffers;
|
return buffers;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Remove failed loading promise so it can be retried
|
// Remove failed loading promise so it can be retried
|
||||||
@@ -115,21 +116,26 @@ export class KGToneBuffersPool {
|
|||||||
* Create ToneAudioBuffers for an instrument
|
* Create ToneAudioBuffers for an instrument
|
||||||
*/
|
*/
|
||||||
private async createToneAudioBuffers(name: string): Promise<Tone.ToneAudioBuffers> {
|
private async createToneAudioBuffers(name: string): Promise<Tone.ToneAudioBuffers> {
|
||||||
|
const configManager = ConfigManager.instance();
|
||||||
|
if (!configManager.getIsInitialized()) {
|
||||||
|
await configManager.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
// Get instrument configuration from constants
|
|
||||||
const fluidConfig = SAMPLER_CONSTANTS.TONE_SAMPLERS.FLUID;
|
|
||||||
const instrumentName = name;
|
const instrumentName = name;
|
||||||
|
|
||||||
if (!instrumentName) {
|
if (!instrumentName) {
|
||||||
throw new Error(`Unknown instrument: ${name}`);
|
throw new Error(`Unknown instrument: ${name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate URL mapping for all keys from A0 to Bb7
|
const baseUrl = (ConfigManager.instance().get('general.soundfont.base_url') as string)
|
||||||
const urls = this.generateKeyUrls(fluidConfig.url, instrumentName);
|
|| SAMPLER_CONSTANTS.TONE_SAMPLERS.FLUID.url;
|
||||||
|
|
||||||
|
const urls = this.generateKeyUrls(baseUrl, instrumentName);
|
||||||
|
|
||||||
console.log(`Loading ToneAudioBuffers for ${name} (${instrumentName})...`);
|
console.log(`Loading ToneAudioBuffers for ${name} (${instrumentName})...`);
|
||||||
|
|
||||||
// Create ToneAudioBuffers with onload callback
|
// Create ToneAudioBuffers with onload callback
|
||||||
const buffers = new Tone.ToneAudioBuffers(
|
const buffers = new Tone.ToneAudioBuffers(
|
||||||
urls,
|
urls,
|
||||||
@@ -140,7 +146,7 @@ export class KGToneBuffersPool {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Don't cache until loading is complete - this will be handled in getToneAudioBuffers
|
// Don't cache until loading is complete - this will be handled in getToneAudioBuffers
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error creating ToneAudioBuffers for ${name}:`, error);
|
console.error(`Error creating ToneAudioBuffers for ${name}:`, error);
|
||||||
reject(error);
|
reject(error);
|
||||||
@@ -158,23 +164,23 @@ export class KGToneBuffersPool {
|
|||||||
// get the range of the instrument.
|
// get the range of the instrument.
|
||||||
// TODO: make the sound library name configurable.
|
// TODO: make the sound library name configurable.
|
||||||
const range = FLUIDR3_INSTRUMENT_MAP[instrumentName]?.pitchRange || [21, 108];
|
const range = FLUIDR3_INSTRUMENT_MAP[instrumentName]?.pitchRange || [21, 108];
|
||||||
|
|
||||||
// Note names in order (using flats instead of sharps where applicable)
|
// Note names in order (using flats instead of sharps where applicable)
|
||||||
const noteNames = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B'];
|
const noteNames = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B'];
|
||||||
|
|
||||||
// Generate keys from A0 to C8 (MIDI notes 21 to 108)
|
// Generate keys from A0 to C8 (MIDI notes 21 to 108)
|
||||||
for (let midiNote = range[0]; midiNote <= range[1]; midiNote++) {
|
for (let midiNote = range[0]; midiNote <= range[1]; midiNote++) {
|
||||||
const octave = Math.floor((midiNote - 12) / 12);
|
const octave = Math.floor((midiNote - 12) / 12);
|
||||||
const noteIndex = (midiNote - 12) % 12;
|
const noteIndex = (midiNote - 12) % 12;
|
||||||
const noteName = noteNames[noteIndex];
|
const noteName = noteNames[noteIndex];
|
||||||
const keyName = `${noteName}${octave}`;
|
const keyName = `${noteName}${octave}`;
|
||||||
|
|
||||||
// Generate URL for this key
|
// Generate URL for this key
|
||||||
urls[keyName] = `${baseUrl}${instrumentName}-mp3/${keyName}.mp3`;
|
urls[keyName] = `${baseUrl}${instrumentName}-mp3/${keyName}.mp3`;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Generated ${Object.keys(urls).length} key URLs for ${instrumentName} from A0 to Bb7`);
|
console.log(`Generated ${Object.keys(urls).length} key URLs for ${instrumentName} from A0 to Bb7`);
|
||||||
|
|
||||||
return urls;
|
return urls;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +202,7 @@ export class KGToneBuffersPool {
|
|||||||
// Clear both maps
|
// Clear both maps
|
||||||
this.bufferMap.clear();
|
this.bufferMap.clear();
|
||||||
this.loadingPromises.clear();
|
this.loadingPromises.clear();
|
||||||
|
|
||||||
console.log("KGToneBuffersPool disposed successfully");
|
console.log("KGToneBuffersPool disposed successfully");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error disposing KGToneBuffersPool:", error);
|
console.error("Error disposing KGToneBuffersPool:", error);
|
||||||
@@ -207,7 +213,7 @@ export class KGToneBuffersPool {
|
|||||||
* Preload buffers for specific instruments (optional performance optimization)
|
* Preload buffers for specific instruments (optional performance optimization)
|
||||||
*/
|
*/
|
||||||
public async preloadInstruments(instrumentNames: string[]): Promise<void> {
|
public async preloadInstruments(instrumentNames: string[]): Promise<void> {
|
||||||
const loadPromises = instrumentNames.map(name =>
|
const loadPromises = instrumentNames.map(name =>
|
||||||
this.getToneAudioBuffers(name).catch(error => {
|
this.getToneAudioBuffers(name).catch(error => {
|
||||||
console.warn(`Failed to preload ${name}:`, error);
|
console.warn(`Failed to preload ${name}:`, error);
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user