Advertisement
apieceoffruit

NAudioConverter

Dec 13th, 2023 (edited)
1,049
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.54 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Threading.Tasks;
  6. using NAudio.Wave;
  7. using UnityEngine;
  8. namespace JS
  9. {
  10.     public static class AudioConverter
  11.     {
  12.         public static async Task<AudioClip> LoadAudioFile(string path)
  13.         {
  14.             var ext = Path.GetExtension(path);
  15.             if (ext.Equals(".mp3"))
  16.                 return await LoadMp3File(path);
  17.             if (ext.Equals(".wav"))
  18.                 return await LoadWavFile(path);
  19.            
  20.             throw new NotSupportedException($"File extension {ext} is not supported");
  21.         }
  22.  
  23.         static async Task<AudioClip> LoadWavFile(string path)
  24.         {
  25.             var wavBytes = await File.ReadAllBytesAsync(path);
  26.             return CreateAudioClipFromWavBytes(wavBytes);
  27.         }
  28.  
  29.         static async Task<AudioClip> LoadMp3File(string path)
  30.         {
  31.            var mp3Bytes = await File.ReadAllBytesAsync(path);
  32.            return await CreateAudioClipFromMp3Bytes(mp3Bytes);
  33.         }
  34.  
  35.         public static async Task<AudioClip> CreateAudioClipFromMp3Bytes(byte[] mp3Bytes)
  36.         {
  37.             var wav = await ConvertMp3ToWav(mp3Bytes);
  38.             return CreateAudioClipFromWavBytes(wav);
  39.         }
  40.        
  41.         public static AudioClip CreateAudioClipFromWavBytes(byte[] wavData)
  42.         {
  43.             using var stream = new MemoryStream(wavData);
  44.             using var reader = new BinaryReader(stream);
  45.             // Read WAV header
  46.             string header = new string(reader.ReadChars(4));
  47.            
  48.             if (header != "RIFF")
  49.             {
  50.                 Debug.LogError("Invalid WAV file");
  51.                 return null;
  52.             }
  53.             reader.ReadInt32(); // File size
  54.             reader.ReadChars(4); // WAVE
  55.             reader.ReadChars(4); // fmt_
  56.             reader.ReadInt32(); // Format chunk size
  57.             reader.ReadInt16(); // Format
  58.             int channels = reader.ReadInt16();
  59.             int sampleRate = reader.ReadInt32();
  60.             reader.ReadInt32(); // Byte rate
  61.             reader.ReadInt16(); // Block align
  62.             int bitDepth = reader.ReadInt16();
  63.  
  64.             // Locate data chunk
  65.             while (new string(reader.ReadChars(4)) != "data")
  66.                 reader.BaseStream.Seek(-3, SeekOrigin.Current);
  67.  
  68.             int dataSize = reader.ReadInt32();
  69.             byte[] rawData = reader.ReadBytes(dataSize);
  70.  
  71.             // Create AudioClip
  72.             AudioClip audioClip = AudioClip.Create("GeneratedAudio", dataSize / (bitDepth / 8) / channels, channels, sampleRate, false);
  73.             float[] audioData = new float[dataSize / (bitDepth / 8)];
  74.  
  75.             // Convert byte data to float data
  76.             for (int i = 0; i < audioData.Length; i++)
  77.             {
  78.                 switch (bitDepth)
  79.                 {
  80.                     case 8:
  81.                         audioData[i] = (rawData[i] - 128) / 128f;
  82.                         break;
  83.                     case 16:
  84.                         audioData[i] = BitConverter.ToInt16(rawData, i * 2) / 32768f;
  85.                         break;
  86.                     case 24:
  87.                         byte[] temp = new byte[4] { rawData[i * 3], rawData[i * 3 + 1], rawData[i * 3 + 2], 0 };
  88.                         audioData[i] = BitConverter.ToInt32(temp, 0) / 2147483648f;
  89.                         break;
  90.                     case 32:
  91.                         audioData[i] = BitConverter.ToInt32(rawData, i * 4) / 2147483648f;
  92.                         break;
  93.                     default:
  94.                         throw new NotSupportedException("Only 8, 16, 24 and 32 bit audio data is supported.");
  95.                 }
  96.             }
  97.  
  98.             // Set data to AudioClip and return
  99.             audioClip.SetData(audioData, 0);
  100.             return audioClip;
  101.         }
  102.            
  103.         public static async Task<byte[]> ConvertMp3ToWav(byte[] mp3Data)
  104.         {
  105.             using var mp3Stream = new MemoryStream(mp3Data);
  106.             await using var mp3Reader = new Mp3FileReader(mp3Stream);
  107.             using var wavStream = new MemoryStream();
  108.             await using (var wavWriter = new WaveFileWriter(wavStream, mp3Reader.WaveFormat))
  109.             {
  110.                 var buffer = new byte[4096];
  111.                 int bytesRead;
  112.                 while ((bytesRead = await mp3Reader.ReadAsync(buffer, 0, buffer.Length)) > 0)
  113.                     await wavWriter.WriteAsync(buffer, 0, bytesRead);
  114.             }
  115.             return wavStream.ToArray();
  116.         }
  117.     }
  118. }
  119.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement