public static void ADPCM2Wav(Stream input, Stream output) { RiffTags riff = new RiffTags(input); // Remove unnecissary tags foreach (string key in riff.Keys.ToArray()) { if (key != "fmt " && key != "data") { riff.Remove(key); } } if (riff.FileType != "WAVE") { throw new Exception("Input is not a WAVE file!"); } WaveFmt fmt = WaveFmt.Read(riff["fmt "].Data); if (fmt.Format != 20) { throw new Exception("Input is not ADPCM format!"); } if (fmt.Channels != 2) { throw new Exception("Input does not have 2 channels!"); } if (fmt.BitsPerSample != 4) { throw new Exception("Input does not have 4 bits per sample!"); } byte[] data = riff["data"].Data; byte[] adpcm = new byte[data.Length]; short[] wavSamples = new short[data.Length * 2]; Buffer.BlockCopy(data, 0, adpcm, 0, data.Length); ADPCM2PCM2(wavSamples, 0, adpcm, 0); ADPCM2PCM(wavSamples, 0, adpcm, 0, adpcm.Length / 2); ADPCM2PCM(wavSamples, wavSamples.Length / 2, adpcm, adpcm.Length / 2, adpcm.Length / 2); //Interleave(wavSamples); byte[] wavData = new byte[wavSamples.Length * sizeof(short)]; Buffer.BlockCopy(wavSamples, 0, wavData, 0, wavData.Length); fmt.Format = 1; fmt.BitsPerSample = 16; fmt.UpdateValues(); riff["fmt "] = new RiffTag("fmt ", fmt.ToBytes()); riff["data"] = new RiffTag("data", wavData); riff.Save(output); }
private static byte[] ReadADPCM(string file, ref int convSampleRate, bool ffmpeg) { try { using (FileStream stream = File.OpenRead(file)) { RiffTags riff = new RiffTags(stream); if (riff.FileType != "WAVE") { throw new Exception("File is a not a wave file!"); } byte[] fmt = riff["fmt "].Data; short type = BitConverter.ToInt16(fmt, 0); if (type != 20) { throw new Exception("File file is not ADPCM!"); } short channels = BitConverter.ToInt16(fmt, 2); int sampleRate = BitConverter.ToInt32(fmt, 4); int bitsPerSample = BitConverter.ToInt16(fmt, 14); if (type == 20 && channels >= 1 && channels <= 2 && sampleRate <= 4000 && bitsPerSample == 4) { convSampleRate = sampleRate; byte[] data = riff["data"].Data; byte[] newData = new byte[data.Length]; int halfLength = data.Length / 2; for (int i = 0, j = 0; i < data.Length; i += 2, j++) { newData[i + 0] = data[j]; newData[i + 1] = data[halfLength + j]; } return(newData); } //else if (ffmpeg) { throw new Exception("Unexpected ffmpeg output!"); //} } } catch (FileNotFoundException) { throw; } catch (Exception ex) { //if (ffmpeg) throw; } return(Convert(file, convSampleRate)); }
public static byte[] Wav2ADPCMData(Stream input, out int sampleRate) { RiffTags riff = new RiffTags(input); // Remove unnecissary tags foreach (string key in riff.Keys.ToArray()) { if (key != "fmt " && key != "data") { riff.Remove(key); } } if (riff.FileType != "WAVE") { throw new Exception("Input is not a WAVE file!"); } WaveFmt fmt = WaveFmt.Read(riff["fmt "].Data); if (fmt.Format != 1) { throw new Exception("Input is not PCM format!"); } if (fmt.Channels != 2) { throw new Exception("Input does not have 2 channels!"); } if (fmt.BitsPerSample != 16) { throw new Exception("Input does not have 16 bits per sample!"); } byte[] data = riff["data"].Data; short[] wavSamples = new short[data.Length / 2]; byte[] adpcm = new byte[data.Length / 4]; Buffer.BlockCopy(data, 0, wavSamples, 0, data.Length); /*Deinterleave(wavSamples); * PCM2ADPCM(adpcm, 0, wavSamples, 0, adpcm.Length / 2); * PCM2ADPCM(adpcm, adpcm.Length / 2, wavSamples, wavSamples.Length / 2, adpcm.Length / 2);*/ PCM2ADPCM2(adpcm, 0, wavSamples, 0); sampleRate = fmt.SampleRate; return(adpcm); }
private static byte[] ReadPCM(string file, ref int convSampleRate, bool ffmpeg) { try { using (FileStream stream = File.OpenRead(file)) { RiffTags riff = new RiffTags(stream); if (riff.FileType != "WAVE") { throw new Exception("File is a not a wave file!"); } byte[] fmt = riff["fmt "].Data; short type = BitConverter.ToInt16(fmt, 0); if (type != 1) { throw new Exception("Wave file is not PCM!"); } short channels = BitConverter.ToInt16(fmt, 2); int sampleRate = BitConverter.ToInt32(fmt, 4); int bitsPerSample = BitConverter.ToInt16(fmt, 14); if (type == 1 && channels == 1 && sampleRate <= 4000 && bitsPerSample == 8) { convSampleRate = sampleRate; return(UnsignedToSigned8BitPCM(riff["data"].Data)); } else if (ffmpeg) { throw new Exception("Unexpected ffmpeg output!"); } } } catch (FileNotFoundException) { throw; } catch (Exception ex) { if (ffmpeg) { throw; } } return(Convert(file, convSampleRate)); }
public static byte[] Wav2PCMs8Data(Stream input, out int sampleRate) { RiffTags riff = new RiffTags(input); // Remove unnecissary tags foreach (string key in riff.Keys.ToArray()) { if (key != "fmt " && key != "data") { riff.Remove(key); } } if (riff.FileType != "WAVE") { throw new Exception("Input is not a WAVE file!"); } WaveFmt fmt = WaveFmt.Read(riff["fmt "].Data); if (fmt.Format != 1) { throw new Exception("Input is not PCM format!"); } if (fmt.Channels != 2) { throw new Exception("Input does not have 2 channels!"); } if (fmt.BitsPerSample != 16) { throw new Exception("Input does not have 16 bits per sample!"); } byte[] data = riff["data"].Data; short[] wavSamples = new short[data.Length / 2]; Buffer.BlockCopy(data, 0, wavSamples, 0, data.Length); int pcmLength = data.Length / 2; if (pf.HasFlag(PCMFlags.S16LE) || pf.HasFlag(PCMFlags.S16BE)) { pcmLength *= 2; } if (pf.HasFlag(PCMFlags.MonoL) || pf.HasFlag(PCMFlags.MonoR)) { pcmLength /= 2; } byte[] pcm = new byte[pcmLength]; if (pf.HasFlag(PCMFlags.Deinterleave)) { Deinterleave(wavSamples); } for (int w = 0, p = 0; w < wavSamples.Length; w += 2, p += 2) { short sample = 0; if (pf.HasFlag(PCMFlags.MonoLR)) { sample = (short)((wavSamples[w + 0] + wavSamples[w + 1]) / 2); } else if (pf.HasFlag(PCMFlags.MonoR)) { sample = wavSamples[w + 1]; } else if (pf.HasFlag(PCMFlags.MonoL)) { sample = wavSamples[w + 0]; } else { sample = wavSamples[w]; w--; } if (pf.HasFlag(PCMFlags.S16LE)) { //Signed 16-bit LITTLE ENDIAN: pcm[p + 0] = unchecked ((byte)(sample & 0xFF)); pcm[p + 1] = unchecked ((byte)((sample >> 8) & 0xFF)); } else if (pf.HasFlag(PCMFlags.S16BE)) { //Signed 16-bit BIG ENDIAN: pcm[p + 0] = unchecked ((byte)((sample >> 8) & 0xFF)); pcm[p + 1] = unchecked ((byte)(sample & 0xFF)); } else { //Signed 8-bit: pcm[p] = unchecked ((byte)((sample >> 8) & 0xFF)); p--; } } /*int outSampleCount = wavSamples * //byte[] pcm = new byte[data.Length / 2];//; * bool? s16e = true;// null; * //s16e (stereo) * if (s16e.HasValue) * pcm = new byte[data.Length]; * //pcm = new byte[data.Length]; * //s16e = true; * //s8 (stereo) * //pcm = new byte[data.Length / 2]; * //byte[] pcm = new byte[data.Length / 4]; * Buffer.BlockCopy(data, 0, wavSamples, 0, data.Length); * * //Deinterleave(wavSamples); * //PCM2ADPCM(adpcm, 0, wavSamples, 0, adpcm.Length / 2); * //PCM2ADPCM(adpcm, adpcm.Length / 2, wavSamples, wavSamples.Length / 2, adpcm.Length / 2); * PCM2PCMs82(pcm, 0, wavSamples, 0, s16e);*/ sampleRate = fmt.SampleRate; return(pcm); }
public static bool MaximizeWavVolume(string inputFile, out string outputFile) { RiffTags riff = new RiffTags(inputFile); // Remove unnecissary tags foreach (string key in riff.Keys.ToArray()) { if (key != "fmt " && key != "data") { riff.Remove(key); } } if (riff.FileType != "WAVE") { throw new Exception("Input is not a WAVE file!"); } WaveFmt fmt = WaveFmt.Read(riff["fmt "].Data); if (fmt.Format != 1) { throw new Exception("Input is not PCM format!"); } if (fmt.Channels != 2) { throw new Exception("Input does not have 2 channels!"); } if (fmt.BitsPerSample != 16) { throw new Exception("Input does not have 16 bits per sample!"); } if (fmt.SampleRate > 5000) { throw new Exception("Sample rate must be 5000Hz or less!"); } byte[] data = riff["data"].Data; short[] wavSamples = new short[data.Length / 2]; Buffer.BlockCopy(data, 0, wavSamples, 0, data.Length); short max = 0; short min = 0; for (int i = 0; i < wavSamples.Length; i++) { max = Math.Max(max, wavSamples[i]); min = Math.Min(min, wavSamples[i]); } // Silent File if (min == 0 && max == 0) { outputFile = inputFile; return(false); } // Lazy maximum volume checking const short range = 32; if (min <= (short.MinValue + range) || max >= (short.MaxValue - range)) { outputFile = inputFile; return(false); } double maxScale = (double)short.MaxValue / max; double minScale = (double)short.MinValue / min; double scale = Math.Min(maxScale, minScale); for (int i = 0; i < wavSamples.Length; i++) { wavSamples[i] = (short)(wavSamples[i] * scale); } byte[] wavData = new byte[wavSamples.Length * sizeof(short)]; Buffer.BlockCopy(wavSamples, 0, wavData, 0, wavData.Length); outputFile = Path.Combine(Directory.GetCurrentDirectory(), "wiimote.maximized.wav"); riff["data"] = new RiffTag("data", wavData); riff.Save(outputFile); return(false); }