0
0

Hi,
I get a crash with the following scenario. Using 20 hardware channels and no software channels. One channel (A) is playing a 5 minute stream(FSOUND_Stream_PlayEx). I then start a process that tries to play 20+ short sounds (FSOUND_PlaySoundEx) and since they all have the same priority as the first channel it gets booted.

I keep a list of playing sounds (so I can update volume, frequency and so on) that I tick on a regular basis and clean up sounds when they are done playing.

On the first tick after A is booted by fmod the tick function realises that A is not playing (FSOUND_IsPlaying) and subsequently tries to close it with FSOUND_StreamClose. This ends up in an Access Violation in FSOUND_Output_DSound_Sample_Free. However if I make the 20+ samples streamed (FSOUND_Stream_PlayEx) then all is well.

I obviously have plenty of workarounds for this crash but would like to know if I am doing something wrong here or whether I should implement one of them. I saw an earlier posting complaining about FSOUND_Stream_Close where the problem was that the sample was getting freed twice but that does not seem to be the case here…

Using fmod 3.62, windows 2000 and directx 9

  • You must to post comments
0
0

Bad choice of words on my half, there is only one thread in our application so that is not the problem.

I am a little afraid that I am not using stuff as was intended so I reproduced the crash on your ‘3d’ sample. Hopefully this helps.
Obviosly I had to make some changes to the code. I changed samp1 to mimic my situation (a FSOUND_HW2D sound), limited hardware channels and added the fsound_isplaying check in the main loop, freeing the sample if it has stopped.

Run, once it starts playing, push and hold ‘3’ and you should get the same crash. Here is my main.cpp:

[code:32jtdoh8]
//===============================================================================================
// 3D.EXE
// Copyright (c), Firelight Technologies Pty, Ltd, 1999-2003.
//
// This test shows EAX, DS3D and Software all being used together and the simple commands needed
// to set up some 3d audio.
// This application also displays the use of FSOUND_GetDriverCaps to get information on the
// 3D capabilities of the selected driver
//===============================================================================================

include <stdio.h>

include <stdlib.h>

include <math.h>

if defined(WIN32) || defined(WATCOMC)

#include &lt;conio.h&gt;
#include &lt;windows.h&gt;

else

#include &quot;../../api/inc/wincompat.h&quot;

endif

include "../../api/inc/fmod.h"

include "../../api/inc/fmod_errors.h" // optional

define INTERFACE_UPDATETIME 50 // 50ms update for interface

/*
[
[DESCRIPTION]

[PARAMETERS]

[RETURN_VALUE]

[REMARKS]

[SEE_ALSO]

]
*/
void Close(FSOUND_SAMPLE *samp1, FSOUND_SAMPLE *samp2, FSOUND_SAMPLE *samp3)
{
// you dont need to free samples if you let fsound’s sample manager look after samples, as
// it will free them all for you.
FSOUND_Sample_Free(samp1);
FSOUND_Sample_Free(samp2);
FSOUND_Sample_Free(samp3);

FSOUND_Close();

}

/*
[
[DESCRIPTION]

[PARAMETERS]

[RETURN_VALUE]

[REMARKS]

[SEE_ALSO]

]
*/
int main()
{
FSOUND_SAMPLE *samp1 = NULL, *samp2 = NULL, *samp3 = NULL;
char key, listenerflag = 1;
int driver, i = 0, channel1 = -1, channel2 = -1;
float listenerpos[3] = { 0,0,0 };

if (FSOUND_GetVersion() &lt; FMOD_VERSION)
{
    printf(&quot;Error : You are using the wrong DLL version!  You should be using FMOD %.02f\n&quot;, FMOD_VERSION);
    return 1;
}

// ==========================================================================================
// SELECT OUTPUT METHOD
// ==========================================================================================

printf(&quot;---------------------------------------------------------\n&quot;);    
printf(&quot;Output Type\n&quot;);    
printf(&quot;---------------------------------------------------------\n&quot;);    

if defined(WIN32) || defined(CYGWIN32) || defined(WATCOMC)

printf(&quot;1 - Direct Sound\n&quot;);
printf(&quot;2 - Windows Multimedia Waveout\n&quot;);
printf(&quot;3 - ASIO\n&quot;);

elif defined(linux)

printf(&quot;1 - OSS - Open Sound System\n&quot;);
printf(&quot;2 - ESD - Elightment Sound Daemon\n&quot;);
printf(&quot;3 - ALSA 0.9 - Advanced Linux Sound Architecture\n&quot;);   

endif

printf(&quot;4 - NoSound\n&quot;);
printf(&quot;---------------------------------------------------------\n&quot;);    // print driver names
printf(&quot;Press a corresponding number or ESC to quit\n&quot;);

do
{
    key = getch();
} while (key != 27 &amp;&amp; key &lt; '1' &amp;&amp; key &gt; '4');

switch (key)
{

if defined(WIN32) || defined(CYGWIN32) || defined(WATCOMC)

    case '1' :  FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND);
                break;
    case '2' :  FSOUND_SetOutput(FSOUND_OUTPUT_WINMM);
                break;
    case '3' :  FSOUND_SetOutput(FSOUND_OUTPUT_ASIO);
                break;

elif defined(linux)

    case '1' :  FSOUND_SetOutput(FSOUND_OUTPUT_OSS);
                break;
    case '2' :  FSOUND_SetOutput(FSOUND_OUTPUT_ESD);
                break;
    case '3' :  FSOUND_SetOutput(FSOUND_OUTPUT_ALSA);
                break;

endif

    case '4' :  FSOUND_SetOutput(FSOUND_OUTPUT_NOSOUND);
                break;
    default  :  return 1; 
}


// ==========================================================================================
// SELECT DRIVER
// ==========================================================================================

// The following list are the drivers for the output method selected above.
printf(&quot;---------------------------------------------------------\n&quot;);    
switch (FSOUND_GetOutput())
{
    case FSOUND_OUTPUT_NOSOUND: printf(&quot;NoSound&quot;); break;

if defined(WIN32) || defined(CYGWIN32) || defined(WATCOMC)

    case FSOUND_OUTPUT_WINMM:   printf(&quot;Windows Multimedia Waveout&quot;); break;
    case FSOUND_OUTPUT_DSOUND:  printf(&quot;Direct Sound&quot;); break;
    case FSOUND_OUTPUT_ASIO:    printf(&quot;ASIO&quot;); break;

elif defined(linux)

    case FSOUND_OUTPUT_OSS:     printf(&quot;Open Sound System&quot;); break;
    case FSOUND_OUTPUT_ESD:     printf(&quot;Enlightment Sound Daemon&quot;); break;
    case FSOUND_OUTPUT_ALSA:    printf(&quot;Alsa&quot;); break;

endif

};
printf(&quot; Driver list\n&quot;);    
printf(&quot;---------------------------------------------------------\n&quot;);    

for (i=0; i &lt; FSOUND_GetNumDrivers(); i++) 
{
    printf(&quot;%d - %s\n&quot;, i+1, FSOUND_GetDriverName(i));    // print driver names
    {
        unsigned int caps = 0;

        FSOUND_GetDriverCaps(i, &amp;caps);

        if (caps &amp; FSOUND_CAPS_HARDWARE)
            printf(&quot;  * Driver supports hardware 3D sound!\n&quot;);
        if (caps &amp; FSOUND_CAPS_EAX2)
            printf(&quot;  * Driver supports EAX 2 reverb!\n&quot;);
        if (caps &amp; FSOUND_CAPS_EAX3)
            printf(&quot;  * Driver supports EAX 3 reverb!\n&quot;);
    }
}
printf(&quot;---------------------------------------------------------\n&quot;);    // print driver names
printf(&quot;Press a corresponding number or ESC to quit\n&quot;);

do
{
    key = getch();
    if (key == 27) 
        return 0;
    driver = key - '1';
} while (driver &lt; 0 || driver &gt;= FSOUND_GetNumDrivers());

FSOUND_SetDriver(driver);                    // Select sound card (0 = default)

{
    unsigned int caps = 0;

    FSOUND_GetDriverCaps(FSOUND_GetDriver(), &amp;caps);

    printf(&quot;---------------------------------------------------------\n&quot;);    
    printf(&quot;Driver capabilities\n&quot;);
    printf(&quot;---------------------------------------------------------\n&quot;);    
    if (!caps)
        printf(&quot;- This driver will support software mode only.\n  It does not properly support 3D sound hardware.\n&quot;);
    if (caps &amp; FSOUND_CAPS_HARDWARE)
        printf(&quot;- Driver supports hardware 3D sound!\n&quot;);
    if (caps &amp; FSOUND_CAPS_EAX2)
        printf(&quot;- Driver supports EAX 2 reverb!\n&quot;);
    if (caps &amp; FSOUND_CAPS_EAX3)
        printf(&quot;- Driver supports EAX 3 reverb!\n&quot;);
    printf(&quot;---------------------------------------------------------\n&quot;);    
}

FSOUND_SetMixer(FSOUND_MIXER_AUTODETECT);

// ==========================================================================================
// INITIALIZE
// ==========================================================================================

/////////////////////////
// ATLI ADDED
FSOUND_SetMaxHardwareChannels(10);
////////////////////////
if (!FSOUND_Init(44100, 32, 0))
{
printf("Init: %s\n", FMOD_ErrorString(FSOUND_GetError()));
return 1;
}

// ==========================================================================================
// LOAD SAMPLES
// ==========================================================================================

// ==========================================================================================
// 3D MONO 
// ==========================================================================================

/////////////////////////
// ATLI CHANGED, 3D TO 2D
samp1 = FSOUND_Sample_Load(FSOUND_FREE, "../../media/drumloop.wav", FSOUND_HW2D, 0);
if (!samp1)
{
printf("samp1: %s\n", FMOD_ErrorString(FSOUND_GetError()));
Close(samp1, samp2, samp3);
return 1;
}

// increasing mindistnace makes it louder in 3d space

/////////////////////////
// ATLI CHANGED, NO MINMAX ON 2D
//FSOUND_Sample_SetMinMaxDistance(samp1, 4.0f, 10000.0f);
FSOUND_Sample_SetMode(samp1, FSOUND_LOOP_NORMAL);

// ==========================================================================================
// 3D MONO 
// ==========================================================================================
samp2 = FSOUND_Sample_Load(FSOUND_UNMANAGED, &quot;../../media/jungle.wav&quot;, FSOUND_HW3D, 0);
if (!samp2)
{
    printf(&quot;samp2: %s\n&quot;, FMOD_ErrorString(FSOUND_GetError()));
    Close(samp1, samp2, samp3);
    return 1;
}
// increasing mindistance makes it louder in 3d space
FSOUND_Sample_SetMinMaxDistance(samp2, 4.0f, 10000.0f);
FSOUND_Sample_SetMode(samp2, FSOUND_LOOP_NORMAL);

// ==========================================================================================
// 2D STEREO
// ==========================================================================================
samp3 = FSOUND_Sample_Load(FSOUND_UNMANAGED, &quot;../../media/chimes.wav&quot;, FSOUND_HW2D, 0);
if (!samp3)
{
    printf(&quot;samp3: %s\n&quot;, FMOD_ErrorString(FSOUND_GetError()));
    Close(samp1, samp2, samp3);
    return 1;
}

// ==========================================================================================
// DISPLAY HELP
// ==========================================================================================

printf(&quot;FSOUND Output Method : &quot;);
switch (FSOUND_GetOutput())
{
    case FSOUND_OUTPUT_NOSOUND: printf(&quot;FSOUND_OUTPUT_NOSOUND\n&quot;); break;
    case FSOUND_OUTPUT_WINMM:   printf(&quot;FSOUND_OUTPUT_WINMM\n&quot;); break;
    case FSOUND_OUTPUT_DSOUND:  printf(&quot;FSOUND_OUTPUT_DSOUND\n&quot;); break;
    case FSOUND_OUTPUT_ASIO:    printf(&quot;FSOUND_OUTPUT_ASIO\n&quot;); break;
    case FSOUND_OUTPUT_OSS:     printf(&quot;FSOUND_OUTPUT_OSS\n&quot;); break;
    case FSOUND_OUTPUT_ESD:     printf(&quot;FSOUND_OUTPUT_ESD\n&quot;); break;
    case FSOUND_OUTPUT_ALSA:    printf(&quot;FSOUND_OUTPUT_ALSA\n&quot;); break;       
};

printf(&quot;FSOUND Mixer         : &quot;);
switch (FSOUND_GetMixer())
{
    case FSOUND_MIXER_BLENDMODE:     printf(&quot;FSOUND_MIXER_BLENDMODE\n&quot;); break;
    case FSOUND_MIXER_MMXP5:         printf(&quot;FSOUND_MIXER_MMXP5\n&quot;); break;
    case FSOUND_MIXER_MMXP6:         printf(&quot;FSOUND_MIXER_MMXP6\n&quot;); break;
    case FSOUND_MIXER_QUALITY_FPU:   printf(&quot;FSOUND_MIXER_QUALITY_FPU\n&quot;); break;
    case FSOUND_MIXER_QUALITY_MMXP5: printf(&quot;FSOUND_MIXER_QUALITY_MMXP5\n&quot;); break;
    case FSOUND_MIXER_QUALITY_MMXP6: printf(&quot;FSOUND_MIXER_QUALITY_MMXP6\n&quot;); break;
};
printf(&quot;FSOUND Driver        : &quot;);
printf(&quot;%s\n&quot;, FSOUND_GetDriverName(FSOUND_GetDriver()));
printf(&quot;Hardware 3D channels : %d\n&quot;, FSOUND_GetNumHardwareChannels());

printf(&quot;=========================================================================\n&quot;);
printf(&quot;Press 1        Pause/Unpause 16bit 3D sound at any time\n&quot;);
printf(&quot;      2        Pause/Unpause 8bit 3D sound at any time\n&quot;);
printf(&quot;      3        Play 16bit STEREO 2D sound at any time\n&quot;);
printf(&quot;      4        Change to EAX Reverb mode CONCERTHALL (DirectSound/SBLive only)\n&quot;);
printf(&quot;      5        Change to EAX Reverb mode SEWERPIPE (DirectSound/SBLive only)\n&quot;);
printf(&quot;      6        Change to EAX Reverb mode PSYCHOTIC (DirectSound/SBLive only)\n&quot;);
printf(&quot;      &lt;        Move listener left (in still mode)\n&quot;);
printf(&quot;      &gt;        Move listener right (in still mode)\n&quot;);
printf(&quot;      SPACE Stop/Start listener automatic movement\n&quot;);
printf(&quot;      ESC    Quit\n&quot;);
printf(&quot;=========================================================================\n&quot;);

// ==========================================================================================
// PLAY 2 LOOPING SOUNDS
// ==========================================================================================

{
    float pos[3] = { -10.0f, -0.0f, 0.0f };
    float vel[3] = { 0,0,0 };

    channel1 = FSOUND_PlaySoundEx(FSOUND_FREE, samp1, NULL, TRUE);

/////////////////////////
// ATLI CHANGED, NO 3DATTRIBUTES ON 2D
//FSOUND_3D_SetAttributes(channel1, pos, vel);
if (!FSOUND_SetPaused(channel1, FALSE))
{
printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
}
}
{
float pos[3] = { 15.0f, -0.0f, -0.0f };
float vel[3] = { 0,0,0 };

    channel2 = FSOUND_PlaySoundEx(FSOUND_FREE, samp2, NULL, TRUE);
    FSOUND_3D_SetAttributes(channel2, pos, vel);
    FSOUND_SetVolume(channel2, 128);
    if (!FSOUND_SetPaused(channel2, FALSE))
    {
        printf(&quot;%s\n&quot;, FMOD_ErrorString(FSOUND_GetError()));
    }
}

// ==========================================================================================
// MAIN LOOP
// ==========================================================================================

do
{
    if (kbhit())
    {
        key = getch();

        if (key == '1') 
        {
            FSOUND_SetPaused(channel1, !FSOUND_GetPaused(channel1));
        }
        if (key == '2') 
        {
            FSOUND_SetPaused(channel2, !FSOUND_GetPaused(channel2));
        }
        if (key == '3') 
        {
            FSOUND_PlaySound(FSOUND_FREE, samp3);
        }
        if (key == '4') 
        {
            FSOUND_REVERB_PROPERTIES props = FSOUND_PRESET_CONCERTHALL;
            FSOUND_Reverb_SetProperties(&amp;props);
        }
        if (key == '5') 
        {
            FSOUND_REVERB_PROPERTIES props = FSOUND_PRESET_SEWERPIPE;
            FSOUND_Reverb_SetProperties(&amp;props);
        }
        if (key == '6')
        {
            FSOUND_REVERB_PROPERTIES props = FSOUND_PRESET_PSYCHOTIC;
            FSOUND_Reverb_SetProperties(&amp;props);
        }

        if (key == ' ')
        {
            listenerflag = !listenerflag;
        }

        if (!listenerflag)
        {
            if (key == '&lt;') 
            {
                listenerpos[0] -= 1.0f;
                if (listenerpos[0] &lt; -35)
                {
                    listenerpos[0] = -35;
                }
            }
            if (key == '&gt;') 
            {
                listenerpos[0] += 1.0f;
                if (listenerpos[0] &gt; 30)
                {
                    listenerpos[0] = 30;
                }
            }
        }
    }

/////////////////////////
// ATLI ADDED CHECK FOR STOPPED PLAYING
if(!FSOUND_IsPlaying(channel1))
{
//CRASHES HERE
FSOUND_Sample_Free(samp1);
}
// ==========================================================================================
// UPDATE THE LISTENER
// ==========================================================================================
{
static float t = 0;
static float lastpos[3] = { 0,0,0 };
float vel[3];

        if (listenerflag)
        {
            listenerpos[0] = ((float)sin(t*0.05f) * 33.0f); // left right pingpong
        }

        // ********* NOTE ******* READ NEXT COMMENT!!!!!
        // vel = how far we moved last FRAME (m/f), then time compensate it to SECONDS (m/s).
        vel[0] = (listenerpos[0]-lastpos[0]) * (1000 / INTERFACE_UPDATETIME);
        vel[1] = (listenerpos[1]-lastpos[1]) * (1000 / INTERFACE_UPDATETIME);
        vel[2] = (listenerpos[2]-lastpos[2]) * (1000 / INTERFACE_UPDATETIME);

        // store pos for next time
        lastpos[0] = listenerpos[0];
        lastpos[1] = listenerpos[1];
        lastpos[2] = listenerpos[2];

        FSOUND_3D_Listener_SetAttributes(&amp;listenerpos[0], &amp;vel[0], 0, 0, 1.0f, 0, 1.0f, 0);

        t += (30 * (1.0f / (float)INTERFACE_UPDATETIME));    // t is just a time value .. it increments in 30m/s steps in this example

        // print out a small visual display
        {
            char s[80];

            sprintf(s, &quot;%d|.......................&lt;1&gt;......................&lt;2&gt;....................|&quot;,FSOUND_GetChannelsPlaying());

            s[(int)(listenerpos[0])+35] = 'L';                
            printf(&quot;%s\r&quot;, s);
        }            
    }

    FSOUND_Update();

    Sleep(INTERFACE_UPDATETIME-1);    // -1 for time taken for printf etc

} while (key != 27);

printf(&quot;\n&quot;);

// ==========================================================================================
// CLEANUP AND SHUTDOWN
// ==========================================================================================

Close(samp1, samp2, samp3);

return 0;

}
[/code:32jtdoh8]

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.