How to set frequency, channel and bit rate while writing wav file

645 Views Asked by At

Here is my code used to record audio and write the audioclip as wav

 public void startRec()
     {
         aud = Microphone.Start ( null, false, 10, 16000 );

     }
 public void stopRec()
     {
         Microphone.End(null);        
         Save ("test",aud);
          }
 public static bool Save(string filename, AudioClip clip) {
         if (!filename.ToLower().EndsWith(".wav")) {
             filename += ".wav";
         }

         string rootpath = Application.dataPath;

         var filepath = rootpath+"/"+filename;

         Debug.Log(filepath);

         // Make sure directory exists if user is saving to sub dir.
         Directory.CreateDirectory(Path.GetDirectoryName(filepath));

         using (var fileStream = CreateEmpty(filepath)) {

             ConvertAndWrite(fileStream, clip);

             WriteHeader(fileStream, clip);
         }

         return true; // TODO: return false if there's a failure saving the file
     }

 static void ConvertAndWrite(FileStream fileStream, AudioClip clip) {

         var samples = new float[clip.samples];

         clip.GetData(samples, 0);

         Int16[] intData = new Int16[samples.Length];
         //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]

         Byte[] bytesData = new Byte[samples.Length * 2];
         //bytesData array is twice the size of
         //dataSource array because a float converted in Int16 is 2 bytes.

         const float rescaleFactor = 32767; //to convert float to Int16

         for (int i = 0; i<samples.Length; i++) {
             intData[i] = (short) (samples[i] * rescaleFactor);
             Byte[] byteArr = new Byte[2];
             byteArr = BitConverter.GetBytes(intData[i]);
             byteArr.CopyTo(bytesData, i * 2);
         }

         fileStream.Write(bytesData, 0, bytesData.Length);
     }

     static void WriteHeader(FileStream fileStream, AudioClip clip) {

         var hz = clip.frequency;
         var channels = clip.channels;
         var samples = clip.samples;

         fileStream.Seek(0, SeekOrigin.Begin);

         Byte[] riff = System.Text.Encoding.UTF8.GetBytes("RIFF");
         fileStream.Write(riff, 0, 4);

         Byte[] chunkSize = BitConverter.GetBytes(fileStream.Length - 8);
         fileStream.Write(chunkSize, 0, 4);

         Byte[] wave = System.Text.Encoding.UTF8.GetBytes("WAVE");
         fileStream.Write(wave, 0, 4);

         Byte[] fmt = System.Text.Encoding.UTF8.GetBytes("fmt ");
         fileStream.Write(fmt, 0, 4);

         Byte[] subChunk1 = BitConverter.GetBytes(16);
         fileStream.Write(subChunk1, 0, 4);

         UInt16 two = 2;
         UInt16 one = 1;

         Byte[] audioFormat = BitConverter.GetBytes(one);
         fileStream.Write(audioFormat, 0, 2);

         Byte[] numChannels = BitConverter.GetBytes(channels);
         fileStream.Write(numChannels, 0, 2);

         Byte[] sampleRate = BitConverter.GetBytes(hz);
         fileStream.Write(sampleRate, 0, 4);

         Byte[] byteRate = BitConverter.GetBytes(hz * channels * 2); // sampleRate * bytesPerSample*number of channels, here 44100*2*2
         fileStream.Write(byteRate, 0, 4);

         UInt16 blockAlign = (ushort) (channels * 2);
         fileStream.Write(BitConverter.GetBytes(blockAlign), 0, 2);

         UInt16 bps = 16;
         Byte[] bitsPerSample = BitConverter.GetBytes(bps);
         fileStream.Write(bitsPerSample, 0, 2);

         Byte[] datastring = System.Text.Encoding.UTF8.GetBytes("data");
         fileStream.Write(datastring, 0, 4);

         Byte[] subChunk2 = BitConverter.GetBytes(samples * channels * 2);
         fileStream.Write(subChunk2, 0, 4);

         fileStream.Close();
     }

I have used the script from this link https://gist.github.com/darktable/2317063 to save audio file. The above code records a wav file and save but when we try to play it back the audio quality and modulation of recorded voice is changed but it plays the recorded one.

I need to convert this wav file to base 64 and pass it it to ispeech api but it says as bad audio data. so we contacted the support team of ispeech they said us to set sample rate = 16khz bit rate = 16 bit channel = mono

But I tried to set these values but couldn't able set in this code Iam new to unity and c# so any help to solve this thanks in advance.

0

There are 0 best solutions below