public IWaveProvider Resample(IWaveProvider inputProvider) { var output = inputProvider; if (_inFormat.Encoding == WaveFormatEncoding.IeeeFloat) { //This needs to change if the Discord sound format changes output = new WaveFloatTo16Provider(inputProvider); _log.Debug("Resampling from IeeeFloat using FloatTo16Provider"); } else if (_inFormat.BitsPerSample != SoundSettings.DiscordFormat.BitsPerSample) { output = new WaveFormatConversionProvider(new WaveFormat(_inFormat.SampleRate, SoundSettings.DiscordFormat.BitsPerSample, _inFormat.Channels), output); _log.Debug($"Resampling from {_inFormat.BitsPerSample} to {SoundSettings.DiscordFormat.BitsPerSample} bit using FormatConversionProvider"); } if (_inFormat.Channels != SoundSettings.DiscordFormat.Channels) { output = new WaveFormatConversionProvider(new WaveFormat(_inFormat.SampleRate, SoundSettings.DiscordFormat.BitsPerSample, SoundSettings.DiscordFormat.Channels), output); _log.Debug($"Resampling from {_inFormat.Channels} to {SoundSettings.DiscordFormat.Channels} using FormatConversionProbider"); } if (_inFormat.SampleRate != SoundSettings.DiscordFormat.SampleRate) { output = new WaveFormatConversionProvider(SoundSettings.DiscordFormat, output); _log.Debug($"Resampling from {_inFormat.SampleRate} to {SoundSettings.DiscordFormat.SampleRate} using FormatConversionProbider"); } return(output); }
public void shutDown() { _waveInStream.StopRecording(); _waveIn16Stream = null; _waveTemp = null; _waveInStream.Dispose(); _waveInStream = null; }
public Speakers() { _recording = false; _soundServer = new UDPServer(0); _waveInStream = new WasapiLoopbackCapture(); _waveTemp = new WaveInProvider(_waveInStream); _waveIn16Stream = new WaveFloatTo16Provider(_waveTemp); //Console.Out.WriteLine("Sample rate: " + _waveInStream.WaveFormat.SampleRate); /*Console.Out.WriteLine("\nEnconding: " + _waveInStream.WaveFormat.Encoding); * Console.Out.WriteLine("Sample rate: " + _waveInStream.WaveFormat.SampleRate); * Console.Out.WriteLine("Bits per sample: " + _waveInStream.WaveFormat.BitsPerSample); * Console.Out.WriteLine("Channels: " + _waveInStream.WaveFormat.Channels);*/ }
static void Main(string[] args) { var fileName = @"C:\Users\milkitic\Downloads\HuΣeR Vs. SYUNN feat.いちか - 狂水一華.mp3"; var obj = new AudioDataHelper(fileName); var data = obj.GetData(out var waveFormat); var memoryStream = new MemoryStream(data); var waveStream = new RawSourceWaveStream(memoryStream, waveFormat); var p = new WaveFloatTo16Provider(waveStream); WaveFileWriter.CreateWaveFile("a.wav", p); var reader = new Mp3FileReaderBase(fileName, format => new DmoMp3FrameDecompressor(format)); WaveFileWriter.CreateWaveFile("b.wav", reader); }
private void initAudioRecorder() { if (audio != null) { audio.DataAvailable -= Audio_DataAvailable; audio.RecordingStopped -= Audio_RecordingStopped; audio.Dispose(); } if (blankplayer != null) { blankplayer.Dispose(); } audio = new WasapiLoopbackCapture(device); sourceFormat = audio.WaveFormat; if (sourceProvider == null) { sourceProvider = new BufferedWaveProvider(sourceFormat); sourceProvider.ReadFully = false; wfto16prov = new WaveFloatTo16Provider(sourceProvider); monovolumeprovider = new StereoToMonoProvider16(wfto16prov); formatconv = new WaveFormatConversionProvider(new WaveFormat(24000, 16, 1), monovolumeprovider); } text_encoding.Text = sourceFormat.Encoding.ToString(); //var client = device.AudioClient.AudioRenderClient; blankplayer = new WasapiOut(device, AudioClientShareMode.Shared, false, 0); silence = new SilenceProvider(sourceFormat).ToSampleProvider(); AudioDevice_Text.ForeColor = Color.Black; try { blankplayer.Init(silence); } catch { AudioDevice_Text.ForeColor = Color.Red; } audio.DataAvailable += Audio_DataAvailable; audio.RecordingStopped += Audio_RecordingStopped; AudioMonitor = device.AudioMeterInformation; }
public static void ApplyAutoTune(string fileToProcess, string tempFile, AutoTuneSettings autotuneSettings) { using (WaveFileReader waveFileReader = new WaveFileReader(fileToProcess)) { IWaveProvider source = new Wave16ToFloatProvider(waveFileReader); IWaveProvider sourceProvider = new AutoTuneWaveProvider(source, autotuneSettings); IWaveProvider waveProvider = new WaveFloatTo16Provider(sourceProvider); using (WaveFileWriter waveFileWriter = new WaveFileWriter(tempFile, waveProvider.WaveFormat)) { byte[] array = new byte[8192]; int num; do { num = waveProvider.Read(array, 0, array.Length); waveFileWriter.Write(array, 0, num); }while (num != 0 && waveFileWriter.Length < waveFileReader.Length); } } }
public static void ApplyAutoTune(string fileToProcess, string tempFile, AutoTuneSettings autotuneSettings) { using (var reader = new WaveFileReader(fileToProcess)) { IWaveProvider stream32 = new Wave16ToFloatProvider(reader); IWaveProvider streamEffect = new AutoTuneWaveProvider(stream32, autotuneSettings); IWaveProvider stream16 = new WaveFloatTo16Provider(streamEffect); using (var converted = new WaveFileWriter(tempFile, stream16.WaveFormat)) { // buffer length needs to be a power of 2 for FFT to work nicely // however, make the buffer too long and pitches aren't detected fast enough // successful buffer sizes: 8192, 4096, 2048, 1024 // (some pitch detection algorithms need at least 2048) var buffer = new byte[8192]; int bytesRead; do { bytesRead = stream16.Read(buffer, 0, buffer.Length); converted.Write(buffer, 0, bytesRead); } while (bytesRead != 0 && converted.Length < reader.Length); } } }
public AudioPassthrough(HotkeyAudioDevice input, HotkeyAudioDevice output, AutoTuneSettings autoTuneSettings) { LastPauseOrStart = new DateTime(2000, 1, 1); _autoTuneSettings = autoTuneSettings; _waveSource = new WaveIn(); WaveSource.DeviceNumber = input.AudioDeviceId; //WaveSource.WaveFormat = new WaveFormat(); WaveSource.WaveFormat = WaveFormat.CreateIeeeFloatWaveFormat(44100, 1); WaveSource.RecordingStopped += WaveSource_RecordingStopped; WaveSource.DataAvailable += WaveSource_DataAvailable; //WaveSource.BufferMilliseconds = 300; //_waveInProvider = new JoeWaveInProvider(WaveSource); //StereoToMonoProvider16 stereoToMonoprovider = new StereoToMonoProvider16(_waveInProvider); //_wave16ToFloatProvider = new Wave16ToFloatProvider(stereoToMonoprovider); //var test3 = ; MemoryStream = new MemoryStream(new byte[8192]); var rawSourceStream = new RawSourceWaveStream(MemoryStream, WaveFormat.CreateIeeeFloatWaveFormat(44100, 1)); //_autoTuner = new AutoTuneWaveProvider(_wave16ToFloatProvider, AutoTuneSettings); _autoTuner = new AutoTuneWaveProvider(rawSourceStream, AutoTuneSettings); _waveFloatTo16Provider = new WaveFloatTo16Provider(_autoTuner); _monoToStereoProvider = new MonoToStereoProvider16(_waveFloatTo16Provider); //_monoToStereoProvider = new MonoToStereoProvider16(_autoTuner); _waveOutput = new WaveOutEvent(); WaveOutput.DeviceNumber = output.AudioDeviceId; WaveOutput.PlaybackStopped += WaveOutput_PlaybackStopped; WaveOutput.Init(_monoToStereoProvider); //JoeWaveOutEvent joeWaveOut = new JoeWaveOutEvent(); //joeWaveOut.DeviceNumber = output.AudioDeviceId; //joeWaveOut.DesiredLatency = 329; //joeWaveOut.NumberOfBuffers = 7; //joeWaveOut.Init(_monoToStereoProvider); //DirectSoundDeviceInfo foundDeviceInfo = null; //foreach (DirectSoundDeviceInfo deviceInfo in DirectSoundOut.Devices) //{ // if (deviceInfo.Description.Contains(output.AudioDeviceName)) // { // foundDeviceInfo = deviceInfo; // break; // } //} //if (foundDeviceInfo != null) //{ // DirectSoundOutput = new DirectSoundOut(foundDeviceInfo.Guid, 300); // DirectSoundOutput.PlaybackStopped += DirectSoundOutput_PlaybackStopped; // DirectSoundOutput.Init(_monoToStereoProvider); //} }
/// <summary> /// Cast the byte stream into a float buffer and launch the pitch detection, /// the smooth maker and raise events in case if the standard deviation is too high. /// </summary> /// <param name="buffer">Byte buffer corresponding to the raw signal.</param> /// <param name="bytesRecorded">Number of frames in the buffer.</param> public void pitchComputePeak(byte[] buffer, int bytesRecorded) { Stream stream = new MemoryStream(buffer); var reader = new RawSourceWaveStream(stream, recordingFormat); IWaveProvider stream32 = new Wave16ToFloatProvider(reader); PitchWaveProvider streamEffect = new PitchWaveProvider(stream32, this); IWaveProvider stream16 = new WaveFloatTo16Provider(streamEffect); var buffert = new byte[1024]; int bytesRead; do { bytesRead = stream16.Read(buffert, 0, buffert.Length); } while (bytesRead != 0); reader.Close(); stream.Close(); // Calculate the volume of the voice long totalSquare = 0; for (int i = 0; i < buffer.Length; i += 2) { short sample = (short)(buffer[i] | (buffer[i + 1] << 8)); totalSquare += sample * sample; } long meanSquare = 2 * totalSquare / buffert.Length; double rms = Math.Sqrt(meanSquare); double volume = rms / 32768.0; // volume is between 0.0 and 1.0 // I used the average of 8 values to have a better result than just with the volume value tabVol[0] = tabVol[1]; tabVol[1] = tabVol[2]; tabVol[2] = tabVol[3]; tabVol[3] = tabVol[4]; tabVol[4] = tabVol[5]; tabVol[5] = tabVol[6]; tabVol[6] = tabVol[7]; tabVol[7] = volume; volume = tabVol.Average(); // To compare easily the volume value I use an integer volume *= 10; volume = Convert.ToInt32(volume); //wiggle = the WIGGLE_SIZE(= 170) last elenents from pitchList if (pitchList.Count > WIGGLE_SIZE) { for (i = 0; i < WIGGLE_SIZE; i++) { wiggle[i] = pitchList[pitchList.Count - (WIGGLE_SIZE + 1) + i]; } } int newValues = pitchList.Count - oldPitchListSize; oldPitchListSize = pitchList.Count; for (i = newValues; i > 0; i--) { DrawingSheetAvatarViewModel.backgroundXMLVoiceRecordingEventStream?.Invoke(this, pitchList[pitchList.Count - 1 - i]); } this.PitchSmoothing(); if (canSendEvent) { lock (Lock) { double sd1 = StdDevTShort(); double sd2 = StdDevLong(); double sd = StdDev(); // each time the function is called we shift the values tab[0] = tab[1]; tab[1] = tab[2]; tab[2] = tab[3]; tab[3] = tab[4]; tab[4] = tab[5]; tab[5] = tab[6]; tab[6] = tab[7]; tab[7] = sd2; // If the rising is over, permit to don't count a peak as a rising up and down in a row if (tab[0] == 0 || tab[tab.Length - 1] == 0 || (tab[0] <= beginningValue + 5 && tab[0] >= beginningValue - 5 && advancementCounter > 2)) { state = 0; beginningValue = 0; advancementCounter = 0; } else { // If the curve is flat if (state == 0) { // Calculate the wanted index int indMax = localMaximum(tab); int indMin = localMinimum(tab); // If there is a big rising up if (tab[indMax] > tab[0] + peakThreshold) { state = 1; beginningValue = tab[0]; advancementCounter = 0; } // Or if there is a big rising down else if (tab[indMin] < tab[0] - peakThreshold) { state = -1; beginningValue = tab[0]; advancementCounter = 0; } else { beginningValue = 0; advancementCounter = 0; } } // If the curve is growing up or down else { double average = 0.0; // Calculate the average of the seven last value for (int cpt = 1; cpt < tab.Length - 1; cpt++) { average += tab[cpt]; } average /= tab.Length - 1; // The curve is flat, so it reinitialize all if (average > tab[0] - 3 && average < tab[0] + 3) { beginningValue = 0; advancementCounter = 0; state = 0; } // The counter advance else { advancementCounter++; } } } // All the feedback files of the different tests //using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Public\TestFolder\test.txt", true)) //{ // file.WriteLine("frame n" + k + " -- state : " + state); //} //using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Public\TestFolder\testShort.txt", true)) //{ // file.WriteLine(sd1); //} //using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Public\TestFolder\testLong.txt", true)) //{ // file.WriteLine(sd2); //} //using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Public\TestFolder\testVol.txt", true)) //{ // file.WriteLine("frame n" + k + " -- state : " + volume); //} // For testing the efficient of the peak detection we used the boring event to display the feedback. // ASu has now changed this to use a peak event if (volume >= 2) //volumethreshold) { if (state == 1) //&& !this.sent) { PeakEvent(this, new InstantFeedback("Rising Tone")); //this.sent = true; } if (state == -1) //&& !this.sent) { PeakEvent(this, new InstantFeedback("Falling Tone")); //this.sent = true; } } k++; i++; } } }
/// <summary> /// Cast the byte stream into a float buffer and launch the pitch detection, /// the smooth maker and raise events in case if the standard deviation is too high. /// </summary> /// <param name="buffer">Byte buffer corresponding to the raw signal.</param> /// <param name="bytesRecorded">Number of frames in the buffer.</param> public void pitchCompute(byte[] buffer, int bytesRecorded) { Stream stream = new MemoryStream(buffer); var reader = new RawSourceWaveStream(stream, recordingFormat); IWaveProvider stream32 = new Wave16ToFloatProvider(reader); PitchWaveProvider streamEffect = new PitchWaveProvider(stream32, this); IWaveProvider stream16 = new WaveFloatTo16Provider(streamEffect); var buffert = new byte[1024]; int bytesRead; do { bytesRead = stream16.Read(buffert, 0, buffert.Length); } while (bytesRead != 0); reader.Close(); stream.Close(); this.PitchSmoothing(); if (canSendEvent && !MainWindow.main.audioProvider.replayMode) { lock (Lock) { double sd1 = StdDevTShort(); double sd2 = StdDevLong(); double sd = StdDev(); //Console.WriteLine("SD =" + sd + " Threshiold " + Threshold + "sd1 = " + sd1); if ((sd <= Threshold && sd != 0.0) && pitchList.Last() > 0 && !this.sent) { BoringEvent(this, new LongFeedback("", true)); this.sent = true; } if ((sd > Threshold || sd == 0.0) && this.sent) { BoringEvent(this, new LongFeedback("", false)); this.sent = false; } /* There is something wrong with the way the above code. The tooBoringText displays at the beginning of a boring episode * and then disappears after a few seconds. Then it flashes up again at the end of a boring episode for a few seconds * I tried to model the code below on the emotion recognition code which also uses long feedback and responds very quickly * to a change in facial expression. */ // Too much variation /* if (sd > ThresholdVariation && !this.sent && pitchList.Last() > 0) * { * BoringEvent(this, new LongFeedback(tooMuchVariationText, true)); * this.sent = true; * } * if (sd <= ThresholdVariation || sd == 0.0 && this.sent) * { * BoringEvent(this, new LongFeedback(tooMuchVariationText, false)); * this.sent = false; * } */ i++; } } }