Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /***********************************************************
- ** **
- ** Codesnippets written by Madwin for MMP 2023 **
- ** **
- ** Not to be used freely. the code still has errors **
- ** It's intended to be used as starting point. **
- ** Code has not been checked and might still need **
- ** (a lot of) work. **
- ** **
- ** © MadMedia Productions 2023 **
- ** **
- ***********************************************************/
- // C# class Harmonist effect in real-time
- using NAudio.Wave;
- using NAudio.Wasapi;
- public class HarmonistEffect
- {
- private WasapiCapture capture;
- private WasapiOut output;
- private BufferedWaveProvider waveBuffer;
- private TDHSolaProvider pitchShifter;
- private MixingWaveProvider32 mixer;
- private WaveFormat format;
- private int bufferMilliseconds;
- private float harmonyLevel;
- private float harmonyInterval;
- private float harmonyDetune;
- public HarmonistEffect(int sampleRate, int channels, int bufferMilliseconds, float harmonyLevel, float harmonyInterval, float harmonyDetune)
- {
- this.format = new WaveFormat(sampleRate, 16, channels);
- this.bufferMilliseconds = bufferMilliseconds;
- this.harmonyLevel = harmonyLevel;
- this.harmonyInterval = harmonyInterval;
- this.harmonyDetune = harmonyDetune;
- // Initialize wave buffer with the specified buffer size and sample rate
- this.waveBuffer = new BufferedWaveProvider(format) {
- BufferDuration = TimeSpan.FromMilliseconds(bufferMilliseconds)
- };
- // Create a TDHSolaProvider with the desired detune and interval
- float frequencyShift = (float) Math.Pow(2, harmonyInterval / 12);
- this.pitchShifter = new TDHSolaProvider(waveBuffer.ToWaveProvider(), frequencyShift, harmonyDetune);
- // Create a mixing wave provider to combine the input signal with the pitch shifted signal
- this.mixer = new MixingWaveProvider32();
- mixer.AddInputStream(waveBuffer.ToWaveProvider()); // add input signal
- mixer.AddInputStream(pitchShifter); // add pitch shifted signal
- // Adjust the level of the harmony effect
- this.mixer.Volume = harmonyLevel;
- }
- public void Start()
- {
- // Initialize WasapiCapture and WasapiOut with the specified format and buffer size
- this.capture = new WasapiCapture(AudioClientShareMode.Shared, false, bufferMilliseconds) {
- WaveFormat = format
- };
- this.output = new WasapiOut(AudioClientShareMode.Shared, false, bufferMilliseconds) {
- LatencyMilliseconds = 100 // add some extra latency to avoid buffer underruns
- };
- // Set up event handlers to process audio input and output
- capture.DataAvailable += OnDataAvailable;
- output.Play();
- capture.StartRecording();
- }
- public void Stop()
- {
- // Stop and dispose of WasapiCapture and WasapiOut
- capture?.StopRecording();
- capture?.Dispose();
- output?.Stop();
- output?.Dispose();
- }
- private void OnDataAvailable(object sender, WaveInEventArgs e)
- {
- // Add the new audio samples to the wave buffer
- waveBuffer.AddSamples(e.Buffer, 0, e.BytesRecorded);
- // Read the mixed and processed audio samples from the mixing wave provider
- byte[] buffer = new byte[e.BytesRecorded];
- int bytesRead = mixer.Read(buffer, 0, e.BytesRecorded);
- // Write the processed audio samples to WasapiOut
- output?.Write(buffer, 0, bytesRead);
- }
- }
- /*
- You can create an instance of the HarmonistEffect class
- with the desired parameters (sample rate, buffer size,
- harmony level, interval, and detune) and call the Start()
- method to begin processing live audio input. You can call
- the Stop() method to stop processing and release resources.
- Note that the TDHSolaProvider may introduce some latency,
- especially if the pitch shift interval is large. To minimize
- latency, you can set the LatencyMilliseconds property of the
- WasapiOut object to a small value, but be aware that this may
- increase the risk of buffer underruns. You can also experiment
- with different pitch shift intervals and buffer sizes to find
- a balance between latency and quality.
- Here's an example usage:
- // Create a HarmonistEffect object with the desired parameters
- HarmonistEffect harmonist = new HarmonistEffect(
- sampleRate: 44100,
- channels: 2,
- bufferMilliseconds: 100,
- harmonyLevel: 0.5f,
- harmonyInterval: 7, // pitch shift up by a perfect fifth (7 semitones)
- harmonyDetune: 5 // detune the harmony by 5 cents
- );
- // Start processing live audio input
- harmonist.Start();
- // Wait for user input to stop processing
- Console.WriteLine("Press any key to stop...");
- Console.ReadKey();
- // Stop processing and release resources
- harmonist.Stop();
- /*
- This example creates a HarmonistEffect object that pitches up
- the input signal by a perfect fifth (7 semitones) and detunes
- the harmony by 5 cents. The harmonyLevel parameter controls the
- level of the harmony effect relative to the input signal. The
- Start() method begins processing live audio input from the
- default audio input device, and the Stop() method stops
- processing and releases resources when the user presses any key.
- */
Advertisement
Add Comment
Please, Sign In to add comment