XNA Creators Club Online
Page 1 of 1 (2 items)
Sort Posts: Previous Next

C# Audio Synthesis?

Last post 08/10/2009 16:52 by LetsGoOutside. 1 replies.
  • 08/10/2009 6:59

    C# Audio Synthesis?

    Sorry for the cross-post... meant to post this here...

    Hello! I'm working on a Surface app that involves some audio synthesis. I'm trying to use DirectSound, but have had no luck. This is my first C# app and while I've got the hang of most everything I've needed in XNA, the audio portion is killing me. I absolutely must be able to do *synthesis* -- no WAV files.

    Can anyone here recommend the best solution for this? If DirectSound is the way to go, then please take a look here and let me know what I'm doing wrong. This code runs, but I can't hear anything.

    1 // Imports 
    2 using Microsoft.DirectX.DirectSound; 
    3 using Microsoft.Xna.Framework; 
    4  
    5 namespace Orchestra.Audio 
    6
    7  
    8     // The class 
    9     public class Sample : Game 
    10     { 
    11  
    12         // Constructor 
    13         public Sample(double frequency, double time) { 
    14  
    15             // Set up device 
    16             Device device = new Device(); 
    17             device.SetCooperativeLevel(this.Window.Handle, CooperativeLevel.Priority); 
    18  
    19             // Set up wave format 
    20             WaveFormat wf = new WaveFormat(); 
    21             wf.AverageBytesPerSecond = 88200; 
    22             wf.BitsPerSample = 16; 
    23             wf.BlockAlign = 2; 
    24             wf.SamplesPerSecond = 44100; 
    25             wf.Channels = 1; 
    26             wf.FormatTag = WaveFormatTag.Pcm; 
    27              
    28             // Set up buffer description 
    29             BufferDescription bd = new BufferDescription(wf); 
    30             bd.BufferBytes = (int)(time * wf.SamplesPerSecond); 
    31             bd.Control3D = false
    32             bd.ControlEffects = true
    33             bd.ControlFrequency = true
    34             bd.ControlPan = true
    35             bd.ControlVolume = true
    36  
    37             // Set up buffer 
    38             SecondaryBuffer buffer = new SecondaryBuffer(bd, device); 
    39             buffer.Volume = (int)Volume.Max; 
    40             buffer.Frequency = (int)frequency; 
    41             System.Console.WriteLine((int)frequency); 
    42  
    43             // Play sound 
    44             buffer.Play(0, BufferPlayFlags.Default); 
    45          
    46         } 
    47  
    48     } 
    49  
    50

  • 08/10/2009 16:52 In reply to

    Re: C# Audio Synthesis?

    Nevermind, I figured it out.  Needed to write all the bytes of the waveform into the buffer to play it.  I misunderstood what "frequency" meant for the buffer class (it's just a filter).  I also had to change the scope a bit.  Here is the code that is producing synthesized audio now.

    1 using Microsoft.DirectX.DirectSound; 
    2 using System; 
    3  
    4 namespace Orchestra.Audio 
    5
    6  
    7     // The class 
    8     public class Oscillator 
    9     { 
    10  
    11         // Private Properties: 
    12         private BufferDescription bufferDesc; 
    13         private Device device; 
    14         private WaveFormat waveFormat; 
    15  
    16         // Constructor: 
    17         public Oscillator(Device device) 
    18         { 
    19  
    20             // Get the device 
    21             // (Create the device and set its priority in  
    22             //  the class containing the program window) 
    23             this.device = device; 
    24  
    25             // Set up wave format 
    26             waveFormat = new WaveFormat(); 
    27             waveFormat.FormatTag = WaveFormatTag.Pcm; 
    28             waveFormat.Channels = 1; 
    29             waveFormat.BitsPerSample = 16; 
    30             waveFormat.SamplesPerSecond = 44100; 
    31             waveFormat.BlockAlign = (short)(waveFormat.Channels * waveFormat.BitsPerSample / 8); 
    32             waveFormat.AverageBytesPerSecond = waveFormat.BlockAlign * waveFormat.SamplesPerSecond; 
    33  
    34             // Set up buffer description 
    35             bufferDesc = new BufferDescription(waveFormat); 
    36             bufferDesc.Control3D = false
    37             bufferDesc.ControlEffects = false
    38             bufferDesc.ControlFrequency = true
    39             bufferDesc.ControlPan = true
    40             bufferDesc.ControlVolume = true
    41             bufferDesc.DeferLocation = true
    42             bufferDesc.GlobalFocus = true
    43  
    44  
    45         } 
    46  
    47         // Play a sound (start frequency, end frequency (portamento), pan, hold time (ms), decay time (ms)) 
    48         public void play(double frequency1, double frequency2, int pan, double time, int decay) 
    49         { 
    50  
    51             // Convert decay to bytes 
    52             decay *= waveFormat.SamplesPerSecond / 1000; 
    53  
    54             // Set buffer length 
    55             bufferDesc.BufferBytes = (int)(time * waveFormat.SamplesPerSecond * waveFormat.Channels * waveFormat.BlockAlign / 1000) + decay; 
    56  
    57             // Create a byte buffer 
    58             int intLength = (int)(bufferDesc.BufferBytes); 
    59             char[] buffer = new char[intLength]; 
    60  
    61             // Set initial amplitude and frequency 
    62             double frequency = frequency1; 
    63  
    64             // Get the step amount between frequencies 
    65             double freqStep = (frequency2 - frequency1) / intLength; 
    66  
    67             // Iterate through time 
    68             for (int i = 0; i < intLength; i++) 
    69             { 
    70  
    71                 // Curve amp on each side 
    72                 double amplitude = 300.0; 
    73                 if (i < amplitude * 2) amplitude = (double)i / 2.0; 
    74                 if (i > intLength - decay) amplitude = (((double)intLength - (double)i) / (double)decay) * 300; 
    75  
    76                 // Add to sine 
    77                 buffer[i] = (char)(amplitude * Math.Sin((double)i * 2.0 * Math.PI * frequency / (double)waveFormat.SamplesPerSecond)); 
    78  
    79                 // Increment the frequency 
    80                 frequency += freqStep; 
    81  
    82             } 
    83  
    84             // Check buffer size
    85             int intMinBufferSize = (int)(150 * waveFormat.SamplesPerSecond * waveFormat.Channels * waveFormat.BlockAlign / 1000); 
    86             if (intLength < intMinBufferSize) 
    87             { 
    88  
    89                 // Create larger buffer 
    90                 char[] buffer2 = new char[intMinBufferSize]; 
    91                 buffer.CopyTo(buffer2, 0); 
    92  
    93                 // Iterate through rest of buffer 
    94                 for (int i = intLength; i < intMinBufferSize; i++) buffer2[i] = (char)0; 
    95  
    96                 // Copy over original buffer 
    97                 buffer = null
    98                 buffer = new char[buffer2.Length]; 
    99                 buffer2.CopyTo(buffer, 0); 
    100  
    101                 // Update buffer size 
    102                 bufferDesc.BufferBytes = buffer.Length; 
    103  
    104             } 
    105  
    106             // Set up audio buffer and play sound 
    107             try 
    108             { 
    109                 SecondaryBuffer bufferSound = new SecondaryBuffer(bufferDesc, device); 
    110                 bufferSound.Volume = (int)Volume.Max; 
    111                 bufferSound.Pan = pan; 
    112                 bufferSound.Write(0, buffer, LockFlag.None); 
    113                 bufferSound.Play(0, BufferPlayFlags.Default); 
    114             } 
    115             catch (Exception ex)  
    116             { 
    117                 Console.WriteLine(ex.Message); 
    118             } 
    119  
    120         } 
    121  
    122     } 
    123  
    124
    125  

Page 1 of 1 (2 items) Previous Next