(api: alphaTab.AlphaTabApi, trackItems: readonly TrackItem[] = [])
| 31 | } |
| 32 | |
| 33 | export async function exportAudio(api: alphaTab.AlphaTabApi, trackItems: readonly TrackItem[] = []): Promise<void> { |
| 34 | if (!api.score) { |
| 35 | return; |
| 36 | } |
| 37 | const options = new alphaTab.synth.AudioExportOptions(); |
| 38 | options.sampleRate = 44100; |
| 39 | options.masterVolume = api.masterVolume; |
| 40 | options.metronomeVolume = api.metronomeVolume; |
| 41 | if (api.playbackRange) { |
| 42 | options.playbackRange = api.playbackRange; |
| 43 | } |
| 44 | |
| 45 | const soloed = new Set<number>(); |
| 46 | for (const item of trackItems) { |
| 47 | const idx = item.track.index; |
| 48 | const ratio = item.getVolume() / Math.max(1, item.track.playbackInfo.volume); |
| 49 | options.trackVolume.set(idx, item.isMuted() ? 0 : ratio); |
| 50 | if (item.isSoloed()) { |
| 51 | soloed.add(idx); |
| 52 | } |
| 53 | } |
| 54 | if (soloed.size > 0) { |
| 55 | for (const t of api.score.tracks) { |
| 56 | if (!soloed.has(t.index)) { |
| 57 | options.trackVolume.set(t.index, 0); |
| 58 | } |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | options.soundFonts = [await fetchSoundFont(Paths.soundFont)]; |
| 63 | |
| 64 | const exporter = await api.exportAudio(options); |
| 65 | let generated: Float32Array | undefined; |
| 66 | let totalSamples = 0; |
| 67 | try { |
| 68 | while (true) { |
| 69 | const chunk = await exporter.render(500); |
| 70 | if (!chunk) { |
| 71 | break; |
| 72 | } |
| 73 | if (!generated) { |
| 74 | generated = new Float32Array(options.sampleRate * (chunk.endTime / 1000) * 2); |
| 75 | } |
| 76 | const needed = totalSamples + chunk.samples.length; |
| 77 | if (generated.length < needed) { |
| 78 | const grown = new Float32Array(needed); |
| 79 | grown.set(generated, 0); |
| 80 | generated = grown; |
| 81 | } |
| 82 | generated.set(chunk.samples, totalSamples); |
| 83 | totalSamples += chunk.samples.length; |
| 84 | } |
| 85 | } finally { |
| 86 | exporter.destroy(); |
| 87 | } |
| 88 | |
| 89 | if (!generated) { |
| 90 | return; |
no test coverage detected