fix acb_mix
This commit is contained in:
parent
abb4cd24cb
commit
1cc605012d
167
src/acb.js
167
src/acb.js
@ -111,90 +111,101 @@ async function mixAcb(acbPath, key, wavDir, mode, skip) {
|
|||||||
for (let i = 0; i < acb.CueTable.length; i++) {
|
for (let i = 0; i < acb.CueTable.length; i++) {
|
||||||
const Cue = acb.CueTable[i];
|
const Cue = acb.CueTable[i];
|
||||||
let samplingRate = 0, channelCount = 0;
|
let samplingRate = 0, channelCount = 0;
|
||||||
if (Cue.ReferenceType !== 3) debugger;
|
if (Cue.ReferenceType === 1) {
|
||||||
const Sequence = acb.SequenceTable[Cue.ReferenceIndex];
|
const Waveform = acb.WaveformTable[Cue.ReferenceIndex];
|
||||||
// Sequence.Type: 0 - Polyphonic, 1 - Sequential, Random, Random No Repeat, Switch, Shuffle Cue, Combo Sequential, Track Transition by Selector
|
const isMemory = Waveform.Streaming === 0;
|
||||||
const timeline = [];
|
const hcaBuffer = isMemory ? acb.memoryHcas[Waveform.MemoryAwbId] : acb.streamHcas[Waveform.StreamAwbPortNo][Waveform.StreamAwbId];
|
||||||
let size = 0;
|
const awbKey = isMemory ? acb.memoryHcas.config.key : acb.streamHcas[Waveform.StreamAwbPortNo].config.key;
|
||||||
for (let j = 0; j < Sequence.NumTracks; j++) {
|
const name = cueNameMap[i] + '.wav';
|
||||||
const index = Sequence.TrackIndex.readUInt16BE(j * 2);
|
const wavPath = path.join(wavDir, name);
|
||||||
const Track = acb.TrackTable[index];
|
await hca.decodeHcaToWav(hcaBuffer, key, awbKey, wavPath, 1, mode);
|
||||||
const TrackEvent = acb.TrackEventTable[Track.EventIndex];
|
} else if (Cue.ReferenceType === 2) {
|
||||||
const track = await parseCommand(acb, TrackEvent.Command, key);
|
console.log(`Unsupport ReferenceType: ${Cue.ReferenceType}`);
|
||||||
if (track.samplingRate) {
|
} else if (Cue.ReferenceType === 3) {
|
||||||
if (samplingRate === 0) samplingRate = track.samplingRate; else if (track.samplingRate !== samplingRate) throw new Error(`SamplingRate Different`);
|
const Sequence = acb.SequenceTable[Cue.ReferenceIndex];
|
||||||
}
|
// Sequence.Type: 0 - Polyphonic, 1 - Sequential, Random, Random No Repeat, Switch, Shuffle Cue, Combo Sequential, Track Transition by Selector
|
||||||
if (track.channelCount) {
|
const timeline = [];
|
||||||
if (channelCount === 0) channelCount = track.channelCount; else if (track.channelCount !== channelCount) throw new Error(`ChannelCount Different`);
|
let size = 0;
|
||||||
}
|
for (let j = 0; j < Sequence.NumTracks; j++) {
|
||||||
let time = 0;
|
const index = Sequence.TrackIndex.readUInt16BE(j * 2);
|
||||||
for (let k = 0; k < track.commands.length; k++) {
|
const Track = acb.TrackTable[index];
|
||||||
const command = track.commands[k];
|
const TrackEvent = acb.TrackEventTable[Track.EventIndex];
|
||||||
switch (command.type) {
|
const track = await parseCommand(acb, TrackEvent.Command, key);
|
||||||
case 0:
|
if (track.samplingRate) {
|
||||||
let m = 0;
|
if (samplingRate === 0) samplingRate = track.samplingRate; else if (track.samplingRate !== samplingRate) throw new Error(`SamplingRate Different`);
|
||||||
while (m < timeline.length && time > timeline[m].time) m++;
|
|
||||||
let offset = Math.round(time * samplingRate * channelCount / 1000);
|
|
||||||
if (offset % channelCount !== 0) offset += channelCount - offset % channelCount;
|
|
||||||
if (m == timeline.length) timeline.push({ time, offset, pcmDatas: [] });
|
|
||||||
const last = timeline[m].offset + command.pcmData.length;
|
|
||||||
if (last > size) size = last;
|
|
||||||
timeline[m].pcmDatas.push(command.pcmData);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
time += command.offset;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
if (track.channelCount) {
|
||||||
}
|
if (channelCount === 0) channelCount = track.channelCount; else if (track.channelCount !== channelCount) throw new Error(`ChannelCount Different`);
|
||||||
if (size === 0) continue;
|
|
||||||
const pcmData = new Float32Array(size);
|
|
||||||
if (timeline.length === 0) continue;
|
|
||||||
timeline.push({ offset: 0xFFFFFFFF, pcmDatas: [] });
|
|
||||||
const runnings = [];
|
|
||||||
let now = timeline[0].offset;
|
|
||||||
for (let i = 0; i < timeline.length; i++) {
|
|
||||||
const wave = timeline[i];
|
|
||||||
const len = wave.offset - now;
|
|
||||||
const pcmDatas = [];
|
|
||||||
let k = 0;
|
|
||||||
while (k < runnings.length) {
|
|
||||||
const running = runnings[k];
|
|
||||||
let end = running.offset + len;
|
|
||||||
if (end >= running.pcmData.length) {
|
|
||||||
pcmDatas.push(running.pcmData.slice(running.offset));
|
|
||||||
runnings.splice(k, 1);
|
|
||||||
} else {
|
|
||||||
pcmDatas.push(running.pcmData.slice(running.offset, end));
|
|
||||||
running.offset = end;
|
|
||||||
k++;
|
|
||||||
}
|
}
|
||||||
}
|
let time = 0;
|
||||||
for (let j = 0; j < wave.pcmDatas.length; j++) {
|
for (let k = 0; k < track.commands.length; k++) {
|
||||||
runnings.push({
|
const command = track.commands[k];
|
||||||
pcmData: wave.pcmDatas[j],
|
switch (command.type) {
|
||||||
offset: 0
|
case 0:
|
||||||
});
|
let m = 0;
|
||||||
}
|
while (m < timeline.length && time > timeline[m].time) m++;
|
||||||
k = now;
|
let offset = Math.round(time * samplingRate * channelCount / 1000);
|
||||||
if (pcmDatas.length > 0) {
|
if (offset % channelCount !== 0) offset += channelCount - offset % channelCount;
|
||||||
let max = 0;
|
if (m == timeline.length) timeline.push({ time, offset, pcmDatas: [] });
|
||||||
for (let j = 1; j < pcmDatas.length; j++) if (pcmDatas[j].length > max) max = j;
|
const last = timeline[m].offset + command.pcmData.length;
|
||||||
for (let j = 0; j < pcmDatas[max].length; j++) {
|
if (last > size) size = last;
|
||||||
let f = 0;
|
timeline[m].pcmDatas.push(command.pcmData);
|
||||||
for (let m = 0; m < pcmDatas.length; m++) {
|
break;
|
||||||
if (j < pcmDatas[m].length) f += pcmDatas[m][j];
|
case 1:
|
||||||
|
time += command.offset;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (f > 1.0) f = 1.0;
|
|
||||||
if (f < -1.0) f = -1.0;
|
|
||||||
pcmData[k++] = f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
now = wave.offset;
|
if (size === 0) continue;
|
||||||
|
const pcmData = new Float32Array(size);
|
||||||
|
if (timeline.length === 0) continue;
|
||||||
|
timeline.push({ offset: 0xFFFFFFFF, pcmDatas: [] });
|
||||||
|
const runnings = [];
|
||||||
|
let now = timeline[0].offset;
|
||||||
|
for (let i = 0; i < timeline.length; i++) {
|
||||||
|
const wave = timeline[i];
|
||||||
|
const len = wave.offset - now;
|
||||||
|
const pcmDatas = [];
|
||||||
|
let k = 0;
|
||||||
|
while (k < runnings.length) {
|
||||||
|
const running = runnings[k];
|
||||||
|
let end = running.offset + len;
|
||||||
|
if (end >= running.pcmData.length) {
|
||||||
|
pcmDatas.push(running.pcmData.slice(running.offset));
|
||||||
|
runnings.splice(k, 1);
|
||||||
|
} else {
|
||||||
|
pcmDatas.push(running.pcmData.slice(running.offset, end));
|
||||||
|
running.offset = end;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let j = 0; j < wave.pcmDatas.length; j++) {
|
||||||
|
runnings.push({
|
||||||
|
pcmData: wave.pcmDatas[j],
|
||||||
|
offset: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
k = now;
|
||||||
|
if (pcmDatas.length > 0) {
|
||||||
|
let max = 0;
|
||||||
|
for (let j = 1; j < pcmDatas.length; j++) if (pcmDatas[j].length > max) max = j;
|
||||||
|
for (let j = 0; j < pcmDatas[max].length; j++) {
|
||||||
|
let f = 0;
|
||||||
|
for (let m = 0; m < pcmDatas.length; m++) {
|
||||||
|
if (j < pcmDatas[m].length) f += pcmDatas[m][j];
|
||||||
|
}
|
||||||
|
if (f > 1.0) f = 1.0;
|
||||||
|
if (f < -1.0) f = -1.0;
|
||||||
|
pcmData[k++] = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
now = wave.offset;
|
||||||
|
}
|
||||||
|
const wavPath = path.join(wavDir, cueNameMap[i] + '.wav');
|
||||||
|
console.log(`Writing ${cueNameMap[i] + '.wav'}...`);
|
||||||
|
await hca.writeWavFile(wavPath, mode, channelCount, samplingRate, pcmData);
|
||||||
}
|
}
|
||||||
const wavPath = path.join(wavDir, cueNameMap[i] + '.wav');
|
|
||||||
console.log(`Writing ${cueNameMap[i] + '.wav'}...`);
|
|
||||||
await hca.writeWavFile(wavPath, mode, channelCount, samplingRate, pcmData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.mixAcb = mixAcb;
|
exports.mixAcb = mixAcb;
|
||||||
|
Loading…
Reference in New Issue
Block a user