Here: http://www.codeproject.com/Articles/501521/How-to-convert-between-most-audio-formats-in-NET
Skip the previous audio processing background knowledge. If you need it, complete it yourself.
Dry goods directly.
1. Audio channel conversion 1. Single-channel to stereo
Principle: dual-channel 16-bit sampling, each 16-bit is a channel, that is, two bytes; the next 16-bit is another channel, staggered.
private byte[] MonoToStereo(byte[] input){ byte[] output = new byte[input.Length * 2]; int outputIndex = 0; for (int n = 0; n < input.Length; n+=2) { // copy in the first 16 bit sample output[outputIndex++] = input[n]; output[outputIndex++] = input[n+1]; // now copy it in again output[outputIndex++] = input[n]; output[outputIndex++] = input[n+1]; } return output;}
2. Stereo to single channel
Principle: remove half of the data.
private byte[] StereoToMono(byte[] input){ byte[] output = new byte[input.Length / 2]; int outputIndex = 0; for (int n = 0; n < input.Length; n+=4) { // copy in the first 16 bit sample output[outputIndex++] = input[n]; output[outputIndex++] = input[n+1]; } return output;}
3. Mixed stereo to single channel
For mixed stereo sound, calculate the average of the left and right audio channels to obtain the single-channel value.
private byte[] MixStereoToMono(byte[] input){ byte[] output = new byte[input.Length / 2]; int outputIndex = 0; for (int n = 0; n < input.Length; n+=4) { int leftChannel = BitConverter.ToInt16(input,n); int rightChannel = BitConverter.ToInt16(input,n+2); int mixed = (leftChannel + rightChannel) / 2; byte[] outSample = BitConverter.GetBytes((short)mixed); // copy in the first 16 bit sample output[outputIndex++] = outSample[0]; output[outputIndex++] = outSample[1]; } return output;}
Ii. Bit Width Conversion
4. 16-bit to 32-bit float
Relatively simple. divide each 16bit (two bytes, and combine a short) by the maximum value of 16 bits to obtain a relative float value (between 0 and 1 ).
public float[] Convert16BitToFloat(byte[] input){ int inputSamples = input.Length / 2; // 16 bit input, so 2 bytes per sample float[] output = new float[inputSamples]; int outputIndex = 0; for(int n = 0; n < inputSamples; n++) { short sample = BitConverter.ToInt16(input,n*2); output[outputIndex++] = sample / 32768f; } return output;}
5. 24-bit to 32-bit float
This is a little troublesome. Take 24 bits from the original data each time, that is, 3 bytes, add a 0, convert it into an int, and divide it by the maximum value of three bytes, obtain a relative float value (between 0 and 1 ).
public float[] Convert24BitToFloat(byte[] input){ int inputSamples = input.Length / 3; // 24 bit input float[] output = new float[inputSamples]; int outputIndex = 0; var temp = new byte[4]; for(int n = 0; n < inputSamples; n++) { // copy 3 bytes in Array.Copy(input,n*3,temp,0,3); int sample = BitConverter.ToInt32(temp,0); output[outputIndex++] = sample / 16777216f; } return output;}
In fact, this method is equivalent to converting the linear fitting of three sampling points into two.
6. Restore data
The code restored in the two methods is the same (the information of one more vertex is lost, and only two bytes are restored ):
for (int sample = 0; sample < sourceSamples; sample++){ // adjust volume float sample32 = sourceBuffer[sample] * volume; // clip if (sample32 > 1.0f) sample32 = 1.0f; if (sample32 < -1.0f) sample32 = -1.0f; destBuffer[destOffset++] = (short)(sample32 * 32767);}
Iii. re-sampling
Sampling is a complex part of this article.
==============================, Principles ===============================
7. A simple re-sampling algorithm
The principle is to increase or decrease the distance between sampling points. Of course, it is obvious that if the new sampling rate is greater than the old one, it is meaningless, resulting in many simple repetition points.
If the new sampling rate is smaller than the old one, it will be pulled back at the existing point.
// Just about worst resampling algorithm possible:private float[] ResampleNaive(float[] inBuffer, int inputSampleRate, int outputSampleRate){ var outBuffer = new List<float>(); double ratio = (double) inputSampleRate / outputSampleRate; int outSample = 0; while (true) { int inBufferIndex = (int)(outSample++ * ratio); if (inBufferIndex < read) writer.WriteSample(inBuffer[inBufferIndex]); else break; } return outBuffer.ToArray(); }
=
Next part, convert the audio file format