@ryohey/wavelet
Advanced tools
Comparing version 0.7.1 to 0.7.2
@@ -889,6 +889,2 @@ const audioDataToAudioBuffer = (audioData) => { | ||
var bin = {}; | ||
Object.defineProperty(bin, '__esModule', { value: true }); | ||
class Stream { | ||
@@ -994,3 +990,3 @@ constructor(data, offset) { | ||
"modLfoToVolume", | ||
undefined, | ||
undefined, // 14 | ||
"chorusEffectsSend", | ||
@@ -1001,3 +997,3 @@ "reverbEffectsSend", | ||
undefined, | ||
undefined, | ||
undefined, // 18,19,20 | ||
"delayModLFO", | ||
@@ -1024,3 +1020,3 @@ "freqModLFO", | ||
"instrument", | ||
undefined, | ||
undefined, // 42 | ||
"keyRange", | ||
@@ -1032,3 +1028,3 @@ "velRange", | ||
"initialAttenuation", | ||
undefined, | ||
undefined, // 49 | ||
"endloopAddrsCoarseOffset", | ||
@@ -1039,3 +1035,3 @@ "coarseTune", | ||
"sampleModes", | ||
undefined, | ||
undefined, // 55 | ||
"scaleTuning", | ||
@@ -1261,3 +1257,3 @@ "exclusiveClass", | ||
const result = parseRiffChunk(chunk, input); | ||
return Object.assign(Object.assign({}, result), { samples: loadSample(result.sampleHeaders, result.samplingData.offset, input) }); | ||
return Object.assign(Object.assign({}, result), { samples: loadSample(result.sampleHeaders, result.samplingData.offsetMSB, result.samplingData.offsetLSB, input) }); | ||
} | ||
@@ -1283,7 +1279,8 @@ function getChunkList(chunk, data, expectedType, expectedSignature) { | ||
function parseSdtaList(chunk, data) { | ||
var _a; | ||
const chunkList = getChunkList(chunk, data, "LIST", "sdta"); | ||
if (chunkList.length !== 1) { | ||
throw new Error("TODO"); | ||
} | ||
return chunkList[0]; | ||
return { | ||
offsetMSB: chunkList[0].offset, | ||
offsetLSB: (_a = chunkList[1]) === null || _a === void 0 ? void 0 : _a.offset, | ||
}; | ||
} | ||
@@ -1333,5 +1330,6 @@ function parseChunk(chunk, data, type, clazz, terminate) { | ||
} | ||
function loadSample(sampleHeader, samplingDataOffset, data) { | ||
function loadSample(sampleHeader, samplingDataOffsetMSB, samplingDataOffsetLSB, data) { | ||
return sampleHeader.map((header) => { | ||
let sample = new Int16Array(new Uint8Array(data.subarray(samplingDataOffset + header.start * 2, samplingDataOffset + header.end * 2)).buffer); | ||
let sample = new Int16Array(new Uint8Array(data.subarray(samplingDataOffsetMSB + header.start * 2, samplingDataOffsetMSB + header.end * 2)).buffer); | ||
// TODO: support 24bit sample | ||
if (header.sampleRate > 0) { | ||
@@ -1454,146 +1452,2 @@ const adjust = adjustSampleData(sample, header.sampleRate); | ||
/** | ||
* Parser で読み込んだサウンドフォントのデータを | ||
* Synthesizer から利用しやすい形にするクラス | ||
*/ | ||
class SoundFont { | ||
constructor(parsed) { | ||
this.parsed = parsed; | ||
} | ||
getPresetZone(presetHeaderIndex) { | ||
return getPresetGenerators(this.parsed, presetHeaderIndex); | ||
} | ||
getInstrumentZone(instrumentZoneIndex) { | ||
return createGeneraterObject(getInstrumentZone(this.parsed, instrumentZoneIndex)); | ||
} | ||
getInstrumentZoneIndexes(instrumentID) { | ||
return getInstrumentZoneIndexes(this.parsed, instrumentID); | ||
} | ||
getInstrumentKey(bankNumber, instrumentNumber, key, velocity = 100) { | ||
const presetHeaderIndex = this.parsed.presetHeaders.findIndex((p) => p.preset === instrumentNumber && p.bank === bankNumber); | ||
if (presetHeaderIndex < 0) { | ||
console.warn("preset not found: bank=%s instrument=%s", bankNumber, instrumentNumber); | ||
return null; | ||
} | ||
const presetGenerators = getPresetGenerators(this.parsed, presetHeaderIndex); | ||
// Last Preset Generator must be instrument | ||
const lastPresetGenertor = presetGenerators[presetGenerators.length - 1]; | ||
if (lastPresetGenertor.type !== "instrument" || | ||
isNaN(Number(lastPresetGenertor.value))) { | ||
throw new Error("Invalid SoundFont: invalid preset generator: expect instrument"); | ||
} | ||
const instrumentID = lastPresetGenertor.value; | ||
const instrumentZones = getInstrumentGenerators(this.parsed, instrumentID).map(createGeneraterObject); | ||
// 最初のゾーンがsampleID を持たなければ global instrument zone | ||
let globalInstrumentZone; | ||
const firstInstrumentZone = instrumentZones[0]; | ||
if (firstInstrumentZone.sampleID === undefined) { | ||
globalInstrumentZone = instrumentZones[0]; | ||
} | ||
// keyRange と velRange がマッチしている Generator を探す | ||
const instrumentZone = instrumentZones.find((i) => { | ||
if (i === globalInstrumentZone) { | ||
return false; // global zone を除外 | ||
} | ||
let isInKeyRange = false; | ||
if (i.keyRange) { | ||
isInKeyRange = key >= i.keyRange.lo && key <= i.keyRange.hi; | ||
} | ||
let isInVelRange = true; | ||
if (i.velRange) { | ||
isInVelRange = velocity >= i.velRange.lo && velocity <= i.velRange.hi; | ||
} | ||
return isInKeyRange && isInVelRange; | ||
}); | ||
if (!instrumentZone) { | ||
console.warn("instrument not found: bank=%s instrument=%s", bankNumber, instrumentNumber); | ||
return null; | ||
} | ||
if (instrumentZone.sampleID === undefined) { | ||
throw new Error("Invalid SoundFont: sampleID not found"); | ||
} | ||
const gen = Object.assign(Object.assign(Object.assign({}, defaultInstrumentZone), removeUndefined$1(globalInstrumentZone || {})), removeUndefined$1(instrumentZone)); | ||
const sample = this.parsed.samples[gen.sampleID]; | ||
const sampleHeader = this.parsed.sampleHeaders[gen.sampleID]; | ||
const tune = gen.coarseTune + gen.fineTune / 100; | ||
const basePitch = tune + | ||
sampleHeader.pitchCorrection / 100 - | ||
(gen.overridingRootKey || sampleHeader.originalPitch); | ||
const scaleTuning = gen.scaleTuning / 100; | ||
return { | ||
sample, | ||
sampleRate: sampleHeader.sampleRate, | ||
sampleName: sampleHeader.sampleName, | ||
sampleModes: gen.sampleModes, | ||
playbackRate: (key) => Math.pow(Math.pow(2, 1 / 12), (key + basePitch) * scaleTuning), | ||
modEnvToPitch: gen.modEnvToPitch / 100, | ||
scaleTuning, | ||
start: gen.startAddrsCoarseOffset * 32768 + gen.startAddrsOffset, | ||
end: gen.endAddrsCoarseOffset * 32768 + gen.endAddrsOffset, | ||
loopStart: sampleHeader.loopStart + | ||
gen.startloopAddrsCoarseOffset * 32768 + | ||
gen.startloopAddrsOffset, | ||
loopEnd: sampleHeader.loopEnd + | ||
gen.endloopAddrsCoarseOffset * 32768 + | ||
gen.endloopAddrsOffset, | ||
volDelay: convertTime$1(gen.delayVolEnv), | ||
volAttack: convertTime$1(gen.attackVolEnv), | ||
volHold: convertTime$1(gen.holdVolEnv), | ||
volDecay: convertTime$1(gen.decayVolEnv), | ||
volSustain: gen.sustainVolEnv / 1000, | ||
volRelease: convertTime$1(gen.releaseVolEnv), | ||
modDelay: convertTime$1(gen.delayModEnv), | ||
modAttack: convertTime$1(gen.attackModEnv), | ||
modHold: convertTime$1(gen.holdModEnv), | ||
modDecay: convertTime$1(gen.decayModEnv), | ||
modSustain: gen.sustainModEnv / 1000, | ||
modRelease: convertTime$1(gen.releaseModEnv), | ||
keyRange: gen.keyRange, | ||
velRange: gen.velRange, | ||
initialFilterFc: gen.initialFilterFc, | ||
modEnvToFilterFc: gen.modEnvToFilterFc, | ||
initialFilterQ: gen.initialFilterQ, | ||
initialAttenuation: gen.initialAttenuation, | ||
freqVibLFO: gen.freqVibLFO | ||
? convertTime$1(gen.freqVibLFO) * 8.176 | ||
: undefined, | ||
pan: gen.pan, | ||
}; | ||
} | ||
// presetNames[bankNumber][presetNumber] = presetName | ||
getPresetNames() { | ||
const bank = {}; | ||
this.parsed.presetHeaders.forEach((preset) => { | ||
if (!bank[preset.bank]) { | ||
bank[preset.bank] = {}; | ||
} | ||
bank[preset.bank][preset.preset] = preset.presetName; | ||
}); | ||
return bank; | ||
} | ||
} | ||
// value = 1200log2(sec) で表される時間を秒単位に変換する | ||
function convertTime$1(value) { | ||
return Math.pow(2, value / 1200); | ||
} | ||
function removeUndefined$1(obj) { | ||
const result = {}; | ||
for (let key in obj) { | ||
if (obj[key] !== undefined) { | ||
result[key] = obj[key]; | ||
} | ||
} | ||
return result; | ||
} | ||
bin.SoundFont = SoundFont; | ||
bin.convertTime = convertTime$1; | ||
var createGeneraterObject_1 = bin.createGeneraterObject = createGeneraterObject; | ||
var defaultInstrumentZone_1 = bin.defaultInstrumentZone = defaultInstrumentZone; | ||
var getInstrumentGenerators_1 = bin.getInstrumentGenerators = getInstrumentGenerators; | ||
bin.getInstrumentZone = getInstrumentZone; | ||
bin.getInstrumentZoneIndexes = getInstrumentZoneIndexes; | ||
var getPresetGenerators_1 = bin.getPresetGenerators = getPresetGenerators; | ||
var parse_1 = bin.parse = parse; | ||
function getPresetZones(generators) { | ||
@@ -1628,3 +1482,3 @@ let instrumentsGlobal = {}; | ||
const parseSamplesFromSoundFont = (data) => { | ||
const parsed = parse_1(data); | ||
const parsed = parse(data); | ||
const result = []; | ||
@@ -1647,7 +1501,7 @@ const convertedSampleBuffers = {}; | ||
const presetHeader = parsed.presetHeaders[i]; | ||
const presetGenerators = getPresetGenerators_1(parsed, i); | ||
const presetGenerators = getPresetGenerators(parsed, i); | ||
const presetZones = getPresetZones(presetGenerators); | ||
for (const presetZone of presetZones.instruments) { | ||
const instrumentID = presetZone.instrument; | ||
const instrumentZones = getInstrumentGenerators_1(parsed, instrumentID).map(createGeneraterObject_1); | ||
const instrumentZones = getInstrumentGenerators(parsed, instrumentID).map(createGeneraterObject); | ||
// 最初のゾーンがsampleID を持たなければ global instrument zone | ||
@@ -1662,3 +1516,3 @@ let globalInstrumentZone; | ||
const sampleHeader = parsed.sampleHeaders[sampleID]; | ||
const { velRange: defaultVelRange, ...generatorDefault } = defaultInstrumentZone_1; | ||
const { velRange: defaultVelRange, ...generatorDefault } = defaultInstrumentZone; | ||
const gen = { | ||
@@ -1665,0 +1519,0 @@ ...generatorDefault, |
{ | ||
"name": "@ryohey/wavelet", | ||
"version": "0.7.1", | ||
"version": "0.7.2", | ||
"description": "A wavetable synthesizer that never stops the UI thread created by AudioWorklet.", | ||
@@ -16,3 +16,3 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@ryohey/sf2parser": "^1.2.0", | ||
"@ryohey/sf2parser": "^1.2.1", | ||
"midifile-ts": "^1.5.1" | ||
@@ -19,0 +19,0 @@ }, |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
60
504546
4984
Updated@ryohey/sf2parser@^1.2.1