Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Threading.Tasks;
- using NAudio.Wave;
- using UnityEngine;
- namespace JS
- {
- public static class AudioConverter
- {
- public static async Task<AudioClip> LoadAudioFile(string path)
- {
- var ext = Path.GetExtension(path);
- if (ext.Equals(".mp3"))
- return await LoadMp3File(path);
- if (ext.Equals(".wav"))
- return await LoadWavFile(path);
- throw new NotSupportedException($"File extension {ext} is not supported");
- }
- static async Task<AudioClip> LoadWavFile(string path)
- {
- var wavBytes = await File.ReadAllBytesAsync(path);
- return CreateAudioClipFromWavBytes(wavBytes);
- }
- static async Task<AudioClip> LoadMp3File(string path)
- {
- var mp3Bytes = await File.ReadAllBytesAsync(path);
- return await CreateAudioClipFromMp3Bytes(mp3Bytes);
- }
- public static async Task<AudioClip> CreateAudioClipFromMp3Bytes(byte[] mp3Bytes)
- {
- var wav = await ConvertMp3ToWav(mp3Bytes);
- return CreateAudioClipFromWavBytes(wav);
- }
- public static AudioClip CreateAudioClipFromWavBytes(byte[] wavData)
- {
- using var stream = new MemoryStream(wavData);
- using var reader = new BinaryReader(stream);
- // Read WAV header
- string header = new string(reader.ReadChars(4));
- if (header != "RIFF")
- {
- Debug.LogError("Invalid WAV file");
- return null;
- }
- reader.ReadInt32(); // File size
- reader.ReadChars(4); // WAVE
- reader.ReadChars(4); // fmt_
- reader.ReadInt32(); // Format chunk size
- reader.ReadInt16(); // Format
- int channels = reader.ReadInt16();
- int sampleRate = reader.ReadInt32();
- reader.ReadInt32(); // Byte rate
- reader.ReadInt16(); // Block align
- int bitDepth = reader.ReadInt16();
- // Locate data chunk
- while (new string(reader.ReadChars(4)) != "data")
- reader.BaseStream.Seek(-3, SeekOrigin.Current);
- int dataSize = reader.ReadInt32();
- byte[] rawData = reader.ReadBytes(dataSize);
- // Create AudioClip
- AudioClip audioClip = AudioClip.Create("GeneratedAudio", dataSize / (bitDepth / 8) / channels, channels, sampleRate, false);
- float[] audioData = new float[dataSize / (bitDepth / 8)];
- // Convert byte data to float data
- for (int i = 0; i < audioData.Length; i++)
- {
- switch (bitDepth)
- {
- case 8:
- audioData[i] = (rawData[i] - 128) / 128f;
- break;
- case 16:
- audioData[i] = BitConverter.ToInt16(rawData, i * 2) / 32768f;
- break;
- case 24:
- byte[] temp = new byte[4] { rawData[i * 3], rawData[i * 3 + 1], rawData[i * 3 + 2], 0 };
- audioData[i] = BitConverter.ToInt32(temp, 0) / 2147483648f;
- break;
- case 32:
- audioData[i] = BitConverter.ToInt32(rawData, i * 4) / 2147483648f;
- break;
- default:
- throw new NotSupportedException("Only 8, 16, 24 and 32 bit audio data is supported.");
- }
- }
- // Set data to AudioClip and return
- audioClip.SetData(audioData, 0);
- return audioClip;
- }
- public static async Task<byte[]> ConvertMp3ToWav(byte[] mp3Data)
- {
- using var mp3Stream = new MemoryStream(mp3Data);
- await using var mp3Reader = new Mp3FileReader(mp3Stream);
- using var wavStream = new MemoryStream();
- await using (var wavWriter = new WaveFileWriter(wavStream, mp3Reader.WaveFormat))
- {
- var buffer = new byte[4096];
- int bytesRead;
- while ((bytesRead = await mp3Reader.ReadAsync(buffer, 0, buffer.Length)) > 0)
- await wavWriter.WriteAsync(buffer, 0, bytesRead);
- }
- return wavStream.ToArray();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement