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 that emulates a Boss DD-500 digital delay and processes
- // live input and output in real-time using CSCore:
- using CSCore;
- using CSCore.CoreAudioAPI;
- using CSCore.SoundIn;
- using CSCore.Streams;
- using CSCore.Streams.SampleConverter;
- using System;
- public class BossDD500Delay
- {
- private readonly WaveIn soundIn;
- private readonly ISoundOut soundOut;
- private readonly IWaveSource delayLine;
- private readonly int delayTimeInMs;
- private readonly float feedbackLevel;
- private readonly float mixLevel;
- private readonly int sampleRate;
- public BossDD500Delay(int delayTimeInMs, float feedbackLevel, float mixLevel, int sampleRate)
- {
- this.delayTimeInMs = delayTimeInMs;
- this.feedbackLevel = feedbackLevel;
- this.mixLevel = mixLevel;
- this.sampleRate = sampleRate;
- // Create a delay line with the specified delay time
- delayLine = new DelayLineSource(delayTimeInMs, sampleRate);
- // Set up sound input and output
- soundIn = new WaveInEvent();
- soundIn.Device = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Capture, Role.Multimedia);
- soundIn.WaveFormat = new WaveFormat(sampleRate, 16, soundIn.WaveFormat.Channels);
- soundIn.Start();
- soundOut = new WasapiOut();
- soundOut.Device = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
- soundOut.Initialize(new SampleToWaveSource(new SoundInSource(soundIn)), delayLine.ToWaveSource());
- soundOut.Play();
- }
- private class DelayLineSource : IWaveSource
- {
- private readonly ISampleSource source;
- private readonly float[] delayBuffer;
- private int delayBufferIndex;
- public WaveFormat WaveFormat => source.WaveFormat;
- public DelayLineSource(int delayTimeInMs, int sampleRate)
- {
- source = new NotifyingSampleSource(new SoundInSource(new WaveInEvent()
- {
- Device = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Multimedia),
- WaveFormat = new WaveFormat(sampleRate, 16, 2)
- }));
- delayBuffer = new float[(int)Math.Ceiling(delayTimeInMs / 1000f * sampleRate) * 2];
- delayBufferIndex = 0;
- }
- public int Read(float[] buffer, int offset, int count)
- {
- int read = source.Read(buffer, offset, count);
- for (int i = 0; i < read; i += 2)
- {
- float left = buffer[i + offset];
- float right = buffer[i + offset + 1];
- // Apply feedback to delay buffer
- delayBuffer[delayBufferIndex] = left + delayBuffer[delayBufferIndex] * feedbackLevel;
- delayBuffer[delayBufferIndex + 1] = right + delayBuffer[delayBufferIndex + 1] * feedbackLevel;
- // Mix dry and delayed signal
- buffer[i + offset] = left * (1 - mixLevel) + delayBuffer[delayBufferIndex] * mixLevel;
- buffer[i + offset + 1] = right * (1 - mixLevel) + delayBuffer[delayBufferIndex + 1] * mixLevel;
- // Increment delay buffer index
- delayBufferIndex = (delayBufferIndex + 2) % delayBuffer.Length;
- }
- return read;
- }
- public void Dispose()
- {
- source.Dispose();
- }
- public event EventHandler<SampleEventArgs> Sample;
- }
- }
- /*
- To use this class, you can create an instance of BossDD500Delay and
- provide the desired delay time, feedback level, mix level, and
- samplerate in the constructor. For example:
- */
- BossDD500Delay dd500 = new BossDD500Delay(500, 0.5f, 0.5f, 44100);
- /*
- This creates a new instance of BossDD500Delay with a delay time of 500ms,
- a feedback level of 0.5, a mix level of 0.5, and a sample rate of 44100Hz.
- You can then capture and process the live input and output by registering
- event handlers for the DataAvailable event of the WaveInEvent object and
- the PlaybackStopped event of the WasapiOut object. For example:
- */
- soundIn.DataAvailable += (sender, e) =>
- {
- byte[] buffer = new byte[e.ByteCount];
- e.Data.Read(buffer, 0, buffer.Length);
- soundOut.Write(buffer, 0, buffer.Length);
- };
- soundOut.PlaybackStopped += (sender, e) =>
- {
- soundIn.Stop();
- soundIn.Dispose();
- soundOut.Dispose();
- };
- /*
- This registers an event handler for the DataAvailable event of the WaveInEvent
- object that reads the input data into a buffer and writes it to the delay line
- via the Write method of the WasapiOut object. It also registers an event handler
- for the PlaybackStopped event of the WasapiOut object that stops and disposes of
- the WaveInEvent and WasapiOut objects when playback is complete.
- Note that this is just a basic example and there are many ways to modify and
- improve the implementation to better suit your needs. For example, you could
- add additional delay line parameters such as modulation, filtering, and stereo
- panning, or add UI controls to adjust the delay time, feedback level, and mix
- level in real-time.
- */
Advertisement
Add Comment
Please, Sign In to add comment