0
0

Hi,

I need to learn how to make a fade out of a sound file at an arbitrary point of the file. When I make a sound stop by setting paused or setting the volume to zero there follows some sound distortion. It is the same thing that happens if you for instance play a sound file in Audacity and then suddenly click stop, or if you start the sound file without a fade in. I believe that the only way to get rid of the sound distortion is to make a short fade out at the point where the sound is stopped. I also might have a need to make a fade in. I therefore wonder if someone could tell me what would be the best way to accomplish this using Fmod.

Thanks in advance.

  • Keitel
  • You must to post comments
0
0

Hi again,

I come to think that there maybe was something more needed to make this work. So after having looked at the manual once more, I added the following commands:

FMOD_System_CreateDSPByType(systemx, FMOD_DSP_TYPE_FADER, &dsp);
FMOD_Channel_AddDSP(channel[0],FMOD_CHANNELCONTROL_DSP_FADER, dsp);

and then it worked. So I hadn’t quite understood how to create this dsp functioning, which I’ve found somewhat difficult. I give the code below in case others should have the same or similar problems as me. This code is for Win Api and C:

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{

static unsigned long long dspclock;
static unsigned long long endclock;
FMOD_DSP *dsp;

static float volume = 0.5;  
static int xm, ym;
static HBRUSH brushcolor;

switch(msg)
{
case WM_CREATE:

                result = FMOD_System_Create(&system);

                FMOD_System_Init(system, 512, FMOD_INIT_NORMAL, NULL);

                result = FMOD_System_CreateSound(system, "flute0.wav", FMOD_CREATESAMPLE | FMOD_LOOP_NORMAL | FMOD_2D, 0,  &sound[0]);


case WM_PAINT :   

      brushcolor  = CreateSolidBrush(RGB(255,204,0));

      hdc = BeginPaint(hwnd, &ps);

      SelectObject(hdc, brushcolor); RoundRect(hdc,  600, 200, 650, 250,10,10);       
      EndPaint (hwnd, &ps) ;

      DeleteObject(brushcolor);


case WM_LBUTTONDOWN :

      xm = LOWORD (lParam);
      ym = HIWORD (lParam);

      if (xm > 600 &&   ym > 200 && xm < 650 &&  ym < 250) {        

            result = FMOD_System_PlaySound(system, sound[0], NULL, 1, &channel[0]);

            FMOD_Channel_SetVolume(channel[0], volume);

                            result = FMOD_Channel_SetPaused(channel[0], 0);

            FMOD_System_Update(systemx);
      }

      return 0; 

case WM_LBUTTONUP : 

     FMOD_System_CreateDSPByType(systemx, FMOD_DSP_TYPE_FADER, &dsp); 

     FMOD_Channel_AddDSP(channel[0],FMOD_CHANNELCONTROL_DSP_FADER, dsp);

             result = FMOD_Channel_GetDSPClock(channel[0], &dspclock, NULL);

         FMOD_System_Update(systemx);

         result =  FMOD_Channel_AddFadePoint(channel[0], dspclock, 1 );

     endclock = dspclock + 1000;

     result =  FMOD_Channel_AddFadePoint(channel[0], endclock, 0.0f );

     FMOD_System_Update(systemx);

     return 0;


case WM_DESTROY:

    PostQuitMessage(0);
        FMOD_System_Release(systemx);

}

return DefWindowProc(hwnd, msg, wParam, lParam);

}

This code will play the sound when the mouse button is down in the given area, and give a smooth and short fade out when released. One can off course extend the fade out by increasing the value of the variable endclock.

I then consider this case for solved. Thanks for all support.

Keitel

  • You must to post comments
0
0

Hi again,

I have implemented Fmod studio and added the addfadepoint function, but I don’t understand what more I need to make it work. I therefore wondered if you could give me the rest of the code needed to create the fade out?

Thanks in advance.

Keitel

  • You must to post comments
0
0

When using the fade point API, you always need to create two fade points: one at the beginning of your fade, and one at the end. The reason for this is that there is a default "fake" fade-point at DSP Clock time 0, and a volume 1.0. If you just set your fade point at the current DSP clock (we’ll say that it’s at 1,000,000 in this example) + whatever time (say, one second from now, which would usually be 48000), then the system will look at that and say "okay, I’m fading from time 0 at a volume of 1 to time 1,048,000 at a volume of 0, so I need to be at a volume of 1.0 – (1,000,000/1,048,000) = 0.0458, and fade to zero from there.

Instead, you add one fade point at the full volume at the current DSP clock (1,000,000 again in this example), and another at your desired fade-out time (1,048,000 again). Now the system says "okay, I’m fading from time 1,000,000 at a volume of 1 to time 1,048,000 at a volume of 0, so I need to be at a volume of 1.0 – ((1,000,000 – 1,000,000)/(1,048,000 – 1,000,000)) = 1.0 – (0/48,000) = 1.0, and then fade down to 0 volume over the next 48,000 clocks.

So, in short, you would call:
ChannelControl::getDSPClock(…);
ChannelControl::addFadePoint(currentClock, volume);
ChannelControl::addFadePoint(endOfFadeTime, 0.0f);

Hope that helps!

  • You must to post comments
0
0

Thank you for your explanation. I think I almost got it, but there is still something I haven’t understood. If you kindly could look at the following example:

[code:1b6lwcu9]

unsigned long long *dspclock = 0;
unsigned long long *parentclock = 0;
unsigned long long *endclock = 0;
static float volume = 0.5;
static HBRUSH brushcolor;

switch(msg)
{
case WM_CREATE:
result = FMOD_System_Create(&systemx);
FMOD_System_Init(systemx, 512, FMOD_INIT_NORMAL, NULL);
result = FMOD_System_CreateSound(systemx, "harmonium0.wav", FMOD_CREATESAMPLE | FMOD_LOOP_NORMAL | FMOD_2D, 0, &sound[0]);

case WM_PAINT :
brushcolor = CreateSolidBrush(RGB(255,204,0));
hdc = BeginPaint(hwnd, &ps);
SelectObject(hdc, brushcolor); RoundRect(hdc, 600, 200, 650, 250,10,10);
EndPaint (hwnd, &ps) ;
DeleteObject(brushcolor);

case WM_LBUTTONDOWN :

      xm = LOWORD (lParam);
      ym = HIWORD (lParam);

      if (xm &gt; 600 &amp;&amp;    ym &gt; 200 &amp;&amp; xm &lt; 650 &amp;&amp;  ym &lt; 250) {       

            result = FMOD_System_PlaySound(systemx, sound[0], NULL, 1, &amp;channel[0]);
            FMOD_Channel_SetVolume(channel[0], volume);
                            result = FMOD_Channel_SetPaused(channel[0], 0);
            FMOD_System_Update(systemx);
      }

      return 0; 

case WM_LBUTTONUP : 

      result = FMOD_Channel_GetDSPClock(channel[0], dspclock, parentclock);
      result =  FMOD_Channel_AddFadePoint(channel[0], *dspclock, volume );
              endclock = dspclock + 5000;
      result =  FMOD_Channel_AddFadePoint(channel[0], *endclock, 0.0f );
      FMOD_System_Update(systemx);
      return 0;

}
[/code:1b6lwcu9]

As seen from the code, the sound file is to be played in a loop as long as the mouse button is held down at the point. When the mouse button is released there should be an immedaite, short fade out, instead of an abrupt sound stop with "setpaused." As it is now the program crashes when I release the mouse button, while the dspclock value is 0. I don’t quite understand the purpose of the parentclock variable neither.

Thanks in advance.

Keitel

  • You must to post comments
0
0

The parentclock value is only used if you’re interested in it. You can pass in NULL in your example.

The reason your code is crashing is because you’re passing in a pointer to an unsigned long long, rather than the address of a valid unsigned long long.

Try changing your code to read:
[code:2hf7fb0a]
unsigned long long dspclock = 0;
unsigned long long endclock = 0;
// ...
result = FMOD_Channel_GetDSPClock(channel[0], &dspclock, parentclock);
result = FMOD_Channel_AddFadePoint(channel[0], dspclock, volume );
endclock = dspclock + 5000;
result = FMOD_Channel_AddFadePoint(channel[0], endclock, 0.0f );[/code:2hf7fb0a]
Also, you should be calling FMOD_System_Update() frequently (like every frame or every update…in a windows app like this you might try setting up a WM_TIMER to do the updates).

Hope that helps!

  • You must to post comments
0
0

Since I haven’t received any answer till now, I assume that there is no such functionalitiety in FMod. But I have to have it. Could anyone give any suggestions what I should do? Do I have to find another sound system, which by the way would be a great pity, and in case which system should I choose. I am quite stuck on this. Have been browsing around on internet just to get more and more confused. Any suggestions would be appreciated.

  • Keitel
  • You must to post comments
0
0

With FMOD 4, you’ll have to implement the volume changes yourself using Channel::setVolume() over time.

If you’re using FMOD Studio, you can use Channel::addFadePoint() to effect fades over time.

Hope that helps!

  • You must to post comments
0
0

Thank you for your answer. I am programming in C Winapi, which has a timer functionality. I have tried to do a gradual volume reduction using Setvolume with the timer set to very short time intervals, from 1 to 5 msec, but the fade out does not become perfectly smooth. There are stille some scratching sounds.

Keitel

  • You must to post comments
0
0

Switch the API to FMOD Studio, the FMOD 5 low level interface is very similar. You can just use Channel::addFadePoint to get smooth sample accurate fades.

  • You must to post comments
0
0

Thank you. That was great news. I have just downloaded FMod studio and are going to check it out.

Keitel

  • You must to post comments
0
0

I have done the changes to the variables, and now the program doesn’t crash. But there is still something wrong, because I don’t get any fading effect. Whatever value I add to the “endclock” variable, I just get the same effect as if I was using setpaused.

I have also added more system update commands, but could you also explain what you mean by “frame” in this context?

Keitel

  • You must to post comments
Showing 11 results
Your Answer

Please first to submit.