• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1328
  • Last Modified:

DirectSound Frequency change causes "click" on Audio

I am trying to generate a continuous tone with DirectX (C#, VS 2003.NET) and vary the frequency on the fly. It appears to work except that everytime the frequency changes I get a "blip or click" (some unwanted noise) on the sound. Should I should generate my own data instead of opening a generic tone file and varying the frequency at which it plays? This would allow re-writing it (I think) on the fly....

This was supposed to take 15 minutes..... ha ha ha
You get 500 points for this question. I don't know if it is easy or difficult, I just know I want to get it done yesterday.

            static Device applicationDevice = null;
            static SecondaryBuffer applicationBuffer = null;
            static string strFileName = @"c:\Tone1.wav";
            BufferPlayFlags PlayFlags  =  BufferPlayFlags.Looping ;
            BufferDescription desc = new BufferDescription();


            public void InitApplicationBuffer()
            {
                  if (null != applicationBuffer)
                              applicationBuffer.Dispose();

                  desc.ControlFrequency  = true;
                  desc.ControlPan = true;
                  desc.ControlVolume = true;
                  desc.GlobalFocus = true ;

                  applicationBuffer = new SecondaryBuffer(strFileName, desc, applicationDevice);
                  applicationBuffer.Pan = 0;
                  applicationBuffer.Volume = -1000;
            }

            public void PlayNote(int freq)
            {

                  if( applicationBuffer == null)
                        return ;

                  try
                  {
                        applicationBuffer.Stop();
                        applicationBuffer.Frequency = freq;
                        applicationBuffer.SetCurrentPosition(0);
                        
                                if(firstrun == true)
                        {
                              applicationBuffer.Play(0, PlayFlags);
                              firstrun = false ;
                        }

                  }
                  catch(Exception e)
                  {
                        MessageBox.Show(null, e.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
                  }

            }
0
shawnricker
Asked:
shawnricker
  • 4
  • 3
2 Solutions
 
Jose ParrotGraphics ExpertCommented:
Hi,

   applicationBuffer.Stop();           <---- here the program stops the sound
   applicationBuffer.Frequency = freq;
   applicationBuffer.SetCurrentPosition(0);
        if(firstrun == true)
        {
             applicationBuffer.Play(0, PlayFlags);  <-- here restarts the sound

In theory, the timeframe between STOP and PLAY, in a Pentium 4, is negligenciable. I am not sure that if this program was in C the problem would not exist. A few weeks ago I had a chance to compare two programs with absolutely the same algorithm, one in Visual C++ 6.0 and other in C# .net 2003. One of them was 30 times faster. The C program, of course.

Two tests:
- code in C/C++ just to compare.
- try the following modifications:

  applicationBuffer.Frequency = freq;
  // applicationBuffer.Stop();           <---- (1) first try to not stop
  // applicationBuffer.SetCurrentPosition(0); <--- (2) try to not rewind
        if(firstrun == true)
        {
             applicationBuffer.Play(0, PlayFlags);

I am not sure if must stop to the frequency change make effect.
If you can accept a small delay to the new frequency, good. If not, maybe you can edit the tone to be shorter, thus having an acceptable delay.

Jose
 
0
 
shawnrickerAuthor Commented:
Jose,
I am new to C# but very experienced in C/C++ and I am sure you are correct that C# is much slower. With respect to your comments, I continued to work with this and I posted my code snippet with a mistake, I had already commented out the two lines you suggested to no avail. I have also tried cloning the buffer and starting to play the clone before stopping the buffer with the previous frequency which also did not work. I wonder if only one buffer can play at a time? I will try to play two tones simultaneously to find out, if I can't then cloning will never help.

Thanks for your effort.
0
 
Jose ParrotGraphics ExpertCommented:
Hi,

If the click is something not well treated inside the runtime, may be a little trick could minimize or even solve the problem. The idea is

       if(firstrun == true)
       {
             applicationBuffer.volume(low);
             applicationBuffer.Play(0, PlayFlags);
             applicationBuffer.volume(normal);

I don't have a guide here, so the "volume" statement should be incorrect, but I'm sure you get it.

Another suggestion is to use MIDI, instead of wave. If you want just tones, MIDI is perfect to that: from triangle and square waves to flutes and sci-fi UFO sounds. You change the tones just changing the notes. MIDI was made to that!

Jose
0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
gran88Commented:
Ah, but MIDI is platform dependent.  It runs using the basic DirectX Midi Sound Library, whatever they call it, and the instruments can change depending on the drivers/devices you have installed.  Just a little tidbit.
0
 
Jose ParrotGraphics ExpertCommented:
If you are using DirectX with C#, VS 2003.NET you are already totally platform dependent: Microsoft. MIDI will use absolutelly the same DirectX C#, VS 2003.NET...

Jose
0
 
Jose ParrotGraphics ExpertCommented:
Think a bit more... you're right, as MIDI boards can have different synthetizers, samplings with different final sounds.

But, as your question is about continuous tone, no noticeable differences will happen between an 8 bits Creative Sound Blasterof the 90's and the last Audigy2 when the waveform is a triangle or square. With a advantage over wave playing: no clicks.

Jose
0
 
shawnrickerAuthor Commented:
I am still here and still very much interested in resolving this. I will look into MIDI and let you know what I find. Time has been short lately but I am persistant to a fault.

Thanks
0
 
shawnrickerAuthor Commented:
I apologize to the moderators. Really this issue is unresolved but nobody seems to care on the user end. I split the points for the effort.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now