Madwin74

Boss DD500 Digital Delay v2

May 9th, 2023
861
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.84 KB | Source Code | 0 0
  1. /***********************************************************
  2.  **                                                       **
  3.  **   Codesnippets written by Madwin for MMP 2023         **
  4.  **                                                       **
  5.  **   Not to be used freely. the code still has errors    **
  6.  **   It's intended to be used as starting point.         **
  7.  **   Code has not been checked and might still need      **
  8.  **   (a lot of) work.                                    **
  9.  **                                                       **
  10.  **   © MadMedia Productions 2023                         **
  11.  **                                                       **
  12.  ***********************************************************/
  13.  
  14.  
  15.  
  16.  
  17. //  C# class that emulates a Boss DD-500 digital delay and processes
  18. //  live input and output in real-time using CSCore:
  19.  
  20.  
  21.  
  22. using CSCore;
  23. using CSCore.CoreAudioAPI;
  24. using CSCore.SoundIn;
  25. using CSCore.Streams;
  26. using CSCore.Streams.SampleConverter;
  27. using System;
  28.  
  29. public class BossDD500Delay
  30. {
  31.     private readonly WaveIn soundIn;
  32.     private readonly ISoundOut soundOut;
  33.     private readonly IWaveSource delayLine;
  34.     private readonly int delayTimeInMs;
  35.     private readonly float feedbackLevel;
  36.     private readonly float mixLevel;
  37.     private readonly int sampleRate;
  38.  
  39.     public BossDD500Delay(int delayTimeInMs, float feedbackLevel, float mixLevel, int sampleRate)
  40.     {
  41.         this.delayTimeInMs = delayTimeInMs;
  42.         this.feedbackLevel = feedbackLevel;
  43.         this.mixLevel = mixLevel;
  44.         this.sampleRate = sampleRate;
  45.  
  46.         // Create a delay line with the specified delay time
  47.         delayLine = new DelayLineSource(delayTimeInMs, sampleRate);
  48.  
  49.         // Set up sound input and output
  50.         soundIn = new WaveInEvent();
  51.         soundIn.Device = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Capture, Role.Multimedia);
  52.         soundIn.WaveFormat = new WaveFormat(sampleRate, 16, soundIn.WaveFormat.Channels);
  53.         soundIn.Start();
  54.  
  55.         soundOut = new WasapiOut();
  56.         soundOut.Device = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
  57.         soundOut.Initialize(new SampleToWaveSource(new SoundInSource(soundIn)), delayLine.ToWaveSource());
  58.         soundOut.Play();
  59.     }
  60.  
  61.     private class DelayLineSource : IWaveSource
  62.     {
  63.         private readonly ISampleSource source;
  64.         private readonly float[] delayBuffer;
  65.         private int delayBufferIndex;
  66.  
  67.         public WaveFormat WaveFormat => source.WaveFormat;
  68.  
  69.         public DelayLineSource(int delayTimeInMs, int sampleRate)
  70.         {
  71.             source = new NotifyingSampleSource(new SoundInSource(new WaveInEvent()
  72.             {
  73.                 Device = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Multimedia),
  74.                 WaveFormat = new WaveFormat(sampleRate, 16, 2)
  75.             }));
  76.  
  77.             delayBuffer = new float[(int)Math.Ceiling(delayTimeInMs / 1000f * sampleRate) * 2];
  78.             delayBufferIndex = 0;
  79.         }
  80.  
  81.         public int Read(float[] buffer, int offset, int count)
  82.         {
  83.             int read = source.Read(buffer, offset, count);
  84.  
  85.             for (int i = 0; i < read; i += 2)
  86.             {
  87.                 float left = buffer[i + offset];
  88.                 float right = buffer[i + offset + 1];
  89.  
  90.                 // Apply feedback to delay buffer
  91.                 delayBuffer[delayBufferIndex] = left + delayBuffer[delayBufferIndex] * feedbackLevel;
  92.                 delayBuffer[delayBufferIndex + 1] = right + delayBuffer[delayBufferIndex + 1] * feedbackLevel;
  93.  
  94.                 // Mix dry and delayed signal
  95.                 buffer[i + offset] = left * (1 - mixLevel) + delayBuffer[delayBufferIndex] * mixLevel;
  96.                 buffer[i + offset + 1] = right * (1 - mixLevel) + delayBuffer[delayBufferIndex + 1] * mixLevel;
  97.  
  98.                 // Increment delay buffer index
  99.                 delayBufferIndex = (delayBufferIndex + 2) % delayBuffer.Length;
  100.             }
  101.  
  102.             return read;
  103.         }
  104.  
  105.         public void Dispose()
  106.         {
  107.             source.Dispose();
  108.         }
  109.  
  110.         public event EventHandler<SampleEventArgs> Sample;
  111.     }
  112. }
  113.  
  114. /*
  115. To use this class, you can create an instance of BossDD500Delay and
  116. provide the desired delay time, feedback level, mix level, and
  117. samplerate in the constructor. For example:
  118. */
  119.  
  120.  
  121. BossDD500Delay dd500 = new BossDD500Delay(500, 0.5f, 0.5f, 44100);
  122.  
  123. /*
  124. This creates a new instance of BossDD500Delay with a delay time of 500ms,
  125. a feedback level of 0.5, a mix level of 0.5, and a sample rate of 44100Hz.
  126.  
  127. You can then capture and process the live input and output by registering
  128. event handlers for the DataAvailable event of the WaveInEvent object and
  129. the PlaybackStopped event of the WasapiOut object. For example:
  130. */
  131.  
  132.  
  133.  
  134. soundIn.DataAvailable += (sender, e) =>
  135. {
  136.     byte[] buffer = new byte[e.ByteCount];
  137.     e.Data.Read(buffer, 0, buffer.Length);
  138.     soundOut.Write(buffer, 0, buffer.Length);
  139. };
  140.  
  141. soundOut.PlaybackStopped += (sender, e) =>
  142. {
  143.     soundIn.Stop();
  144.     soundIn.Dispose();
  145.     soundOut.Dispose();
  146. };
  147.  
  148.  
  149. /*
  150. This registers an event handler for the DataAvailable event of the WaveInEvent
  151. object that reads the input data into a buffer and writes it to the delay line
  152. via the Write method of the WasapiOut object. It also registers an event handler
  153. for the PlaybackStopped event of the WasapiOut object that stops and disposes of
  154. the WaveInEvent and WasapiOut objects when playback is complete.
  155.  
  156. Note that this is just a basic example and there are many ways to modify and
  157. improve the implementation to better suit your needs. For example, you could
  158. add additional delay line parameters such as modulation, filtering, and stereo
  159. panning, or add UI controls to adjust the delay time, feedback level, and mix
  160. level in real-time.
  161. */
Advertisement
Add Comment
Please, Sign In to add comment