Better code quality
This commit is contained in:
@ -1,13 +1,70 @@
|
||||
import { encodeWAV } from '../../lib/bytebeat/wavEncoder'
|
||||
import type { BitDepth } from '../../lib/bytebeat/types'
|
||||
|
||||
export type { BitDepth }
|
||||
export type BitDepth = 8 | 16 | 24
|
||||
|
||||
export interface ExportOptions {
|
||||
sampleRate: number
|
||||
bitDepth?: BitDepth
|
||||
}
|
||||
|
||||
function encodeWAV(samples: Float32Array, sampleRate: number, bitDepth: BitDepth): Blob {
|
||||
const numChannels = 1
|
||||
const bytesPerSample = bitDepth / 8
|
||||
const blockAlign = numChannels * bytesPerSample
|
||||
const byteRate = sampleRate * blockAlign
|
||||
const dataSize = samples.length * bytesPerSample
|
||||
const bufferSize = 44 + dataSize
|
||||
|
||||
const buffer = new ArrayBuffer(bufferSize)
|
||||
const view = new DataView(buffer)
|
||||
|
||||
const writeString = (offset: number, string: string) => {
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
view.setUint8(offset + i, string.charCodeAt(i))
|
||||
}
|
||||
}
|
||||
|
||||
writeString(0, 'RIFF')
|
||||
view.setUint32(4, 36 + dataSize, true)
|
||||
writeString(8, 'WAVE')
|
||||
writeString(12, 'fmt ')
|
||||
view.setUint32(16, 16, true)
|
||||
view.setUint16(20, 1, true)
|
||||
view.setUint16(22, numChannels, true)
|
||||
view.setUint32(24, sampleRate, true)
|
||||
view.setUint32(28, byteRate, true)
|
||||
view.setUint16(32, blockAlign, true)
|
||||
view.setUint16(34, bitDepth, true)
|
||||
writeString(36, 'data')
|
||||
view.setUint32(40, dataSize, true)
|
||||
|
||||
const maxValue = Math.pow(2, bitDepth - 1) - 1
|
||||
let offset = 44
|
||||
|
||||
for (let i = 0; i < samples.length; i++) {
|
||||
const sample = Math.max(-1, Math.min(1, samples[i]))
|
||||
const intSample = Math.round(sample * maxValue)
|
||||
|
||||
if (bitDepth === 8) {
|
||||
view.setUint8(offset, intSample + 128)
|
||||
offset += 1
|
||||
} else if (bitDepth === 16) {
|
||||
view.setInt16(offset, intSample, true)
|
||||
offset += 2
|
||||
} else if (bitDepth === 24) {
|
||||
const bytes = [
|
||||
intSample & 0xff,
|
||||
(intSample >> 8) & 0xff,
|
||||
(intSample >> 16) & 0xff
|
||||
]
|
||||
view.setUint8(offset, bytes[0])
|
||||
view.setUint8(offset + 1, bytes[1])
|
||||
view.setUint8(offset + 2, bytes[2])
|
||||
offset += 3
|
||||
}
|
||||
}
|
||||
|
||||
return new Blob([buffer], { type: 'audio/wav' })
|
||||
}
|
||||
|
||||
export function exportToWav(
|
||||
samples: Float32Array,
|
||||
options: ExportOptions
|
||||
|
||||
Reference in New Issue
Block a user