|  | export function decodeBase64Audio( | 
					
						
						|  | base64String: string, | 
					
						
						|  | mimeType = 'audio/mpeg', | 
					
						
						|  | sampleRate = 44100, | 
					
						
						|  | numChannels = 1 | 
					
						
						|  | ): string { | 
					
						
						|  |  | 
					
						
						|  | const byteString = atob(base64String) | 
					
						
						|  | const byteArray = new Uint8Array(byteString.length) | 
					
						
						|  |  | 
					
						
						|  | for (let i = 0; i < byteString.length; i += 1) { | 
					
						
						|  | byteArray[i] = byteString.charCodeAt(i) | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | let blob: Blob | 
					
						
						|  |  | 
					
						
						|  | if (mimeType === 'audio/pcm16') { | 
					
						
						|  |  | 
					
						
						|  | const wavHeader = createWavHeader(byteArray.length, sampleRate, numChannels) | 
					
						
						|  | const wavData = new Uint8Array(wavHeader.length + byteArray.length) | 
					
						
						|  | wavData.set(wavHeader, 0) | 
					
						
						|  | wavData.set(byteArray, wavHeader.length) | 
					
						
						|  |  | 
					
						
						|  | blob = new Blob([wavData], { type: 'audio/wav' }) | 
					
						
						|  | } else { | 
					
						
						|  | blob = new Blob([byteArray], { type: mimeType }) | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | return URL.createObjectURL(blob) | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | function createWavHeader( | 
					
						
						|  | dataLength: number, | 
					
						
						|  | sampleRate: number, | 
					
						
						|  | numChannels: number | 
					
						
						|  | ): Uint8Array { | 
					
						
						|  | const header = new ArrayBuffer(44) | 
					
						
						|  | const view = new DataView(header) | 
					
						
						|  |  | 
					
						
						|  | const blockAlign = numChannels * 2 | 
					
						
						|  | const byteRate = sampleRate * blockAlign | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | view.setUint32(0, 0x52494646, false) | 
					
						
						|  | view.setUint32(4, 36 + dataLength, true) | 
					
						
						|  | view.setUint32(8, 0x57415645, false) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | view.setUint32(12, 0x666d7420, false) | 
					
						
						|  | 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, 16, true) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | view.setUint32(36, 0x64617461, false) | 
					
						
						|  | view.setUint32(40, dataLength, true) | 
					
						
						|  |  | 
					
						
						|  | return new Uint8Array(header) | 
					
						
						|  | } | 
					
						
						|  |  |