/// /** * Base64로 인코딩된 오디오 데이터를 Uint8Array로 디코딩하는 유틸리티 함수입니다. * @param {string} base64 - Base64 인코딩된 문자열 (data URI 접두사 없이 순수 데이터) * @returns {Uint8Array} - 디코딩된 바이트 배열 */ export function decodeBase64(base64: string): Uint8Array { // `atob` 함수를 사용하여 Base64 문자열을 이진 문자열로 디코딩합니다. const binaryString = atob(base64); const len = binaryString.length; // 디코딩된 바이트를 저장할 Uint8Array를 생성합니다. const bytes = new Uint8Array(len); // 각 문자의 ASCII 코드를 바이트 배열에 저장합니다. for (let i = 0; i < len; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes; } /** * PCM 오디오 데이터를 AudioBuffer 객체로 디코딩하는 비동기 함수입니다. * 웹 오디오 API를 사용하여 브라우저에서 오디오를 재생하거나 처리하기 위해 사용됩니다. * * @param {Uint8Array} data - 디코딩할 PCM 오디오 데이터 (Uint8Array 형식) * @param {AudioContext} ctx - 현재 사용 중인 AudioContext 인스턴스 * @param {number} sampleRate - 오디오 샘플 레이트 (기본값: 24000 Hz) * @param {number} numChannels - 오디오 채널 수 (기본값: 1, 모노) * @returns {Promise} - 디코딩된 AudioBuffer 객체 */ export async function decodeAudioData( data: Uint8Array, ctx: AudioContext, sampleRate: number = 24000, numChannels: number = 1, ): Promise { // 16비트 정렬을 확인하고 필요한 경우 버퍼 크기를 조정합니다. // (createBuffer는 짝수 길이의 버퍼를 선호할 수 있습니다.) let buffer = data.buffer; if (buffer.byteLength % 2 !== 0) { const newBuffer = new ArrayBuffer(buffer.byteLength + 1); new Uint8Array(newBuffer).set(data); buffer = newBuffer; } // Int16Array로 데이터를 해석하여 16비트 PCM 데이터를 처리합니다. const dataInt16 = new Int16Array(buffer); // 총 프레임 수를 계산합니다 (샘플 수 / 채널 수). const frameCount = dataInt16.length / numChannels; // AudioBuffer를 생성합니다. (채널 수, 프레임 수, 샘플 레이트) const audioBuffer = ctx.createBuffer(numChannels, frameCount, sampleRate); // 각 오디오 채널에 대해 데이터를 처리합니다. for (let channel = 0; channel < numChannels; channel++) { // 현재 채널의 데이터를 가져옵니다 (Float32Array). const channelData = audioBuffer.getChannelData(channel); for (let i = 0; i < frameCount; i++) { // Int16 값을 Float32 범위 [-1.0, 1.0]으로 변환합니다. // 16비트 부호 있는 정수(short)의 최대값은 32767이므로 이 값으로 나눕니다. channelData[i] = dataInt16[i * numChannels + channel] / 32768.0; } } return audioBuffer; } /** * AudioBuffer 객체를 WAV 형식의 Blob으로 변환하는 함수입니다. * 이렇게 생성된 Blob은 HTML