# FMOD::Sound::getLength returns FMOD\_ERR\_NOTREADY on very short programmer sound

**URL:** <https://qa.fmod.com/t/fmod-getlength-returns-fmod-err-notready-on-very-short-programmer-sound/18716>\
**Category:** FMOD Engine\
**Tags:** cpp\
**Created:** [May 2, 2022, 9:08am UTC](https://qa.fmod.com/t/fmod-getlength-returns-fmod-err-notready-on-very-short-programmer-sound/18716 "2022-05-02T09:08:56Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![kylotonn](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@kylotonn](https://qa.fmod.com/u/kylotonn)\
**Post date:** [May 2, 2022, 9:08am UTC](https://qa.fmod.com/t/fmod-getlength-returns-fmod-err-notready-on-very-short-programmer-sound/18716/1 "2022-05-02T09:08:56Z")

</div>

We are using the FMOD\_STUDIO\_EVENT\_CALLBACK\_SOUND\_PLAYED when playing programmer sound ( audiotable) to retrieve subsound length.

```auto
case FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED:
	{
		FMOD::Sound* pSound = (FMOD::Sound*)pAudioTableInstance->pSound;
		FMOD::Sound* pSubSound = NULL;
		iResult = pSound->getSubSound( pAudioTableInstance->iSubSoundIndex, &pSubSound );
		PA_FMOD_LOG_AND_ASSERT_ON_ERROR( ERROR, iResult );

		if( pSubSound != NULL ) 
		{
			iResult = pSubSound->getLength( &pAudioTableInstance->iSoundLenghtMs, FMOD_TIMEUNIT_MS );
			PA_FMOD_LOG_AND_ASSERT_ON_ERROR( ERROR, iResult );
			pAudioTableInstance->bIsSoundLengthReady = true;
		}

		if( pAudioTableInstance->pAudioTableInstanceCallback != NULL && pAudioTableInstance->bNeedToDestroy == false )
		{
			pAudioTableInstance->pAudioTableInstanceCallback( pAudioTableInstance, true );
		}
		return FMOD_OK;
	
	}

```

Sometimes, on very short sound , getLength returns a FMOD\_ERR\_NOTREADY ( " Operation could not be performed because specified sound/DSP connection is not ready" )  
Is our code correct ?  
What we want is to get the subsound length as soon as possible  
Thanks

---

<div class="post-metadata">

**Author:** ![jeff\_fmod](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/jeff_fmod/32/1766_2.png) [@jeff\_fmod](https://qa.fmod.com/u/jeff_fmod)\
**Post date:** [May 5, 2022, 1:23am UTC](https://qa.fmod.com/t/fmod-getlength-returns-fmod-err-notready-on-very-short-programmer-sound/18716/2 "2022-05-05T01:23:32Z")

</div>

> [@kylotonn](#):
>
> Sometimes, on very short sound , getLength returns a FMOD\_ERR\_NOTREADY

I think I will need a little more context to determine what the issue here is. Can you please share your full callback so I can see how the different callback cases are working together?

> [@kylotonn](#):
>
> Is our code correct ?

The intended way to use the `FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED` callback is to cast `void* parameters` to a `FMOD::Sound` and use that sound- it looks you are using a sound stored somewhere else and that sound for whatever reason is not ready. Here is an example of the expected usage of `FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED`:

```auto
case FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED:
	{
		FMOD::Sound* pSound = (FMOD::Sound*)parameters;

		if( pSound != NULL ) 
		{
			iResult = pSound->getLength( &pAudioTableInstance->iSoundLenghtMs, FMOD_TIMEUNIT_MS );
			PA_FMOD_LOG_AND_ASSERT_ON_ERROR( ERROR, iResult );
			pAudioTableInstance->bIsSoundLengthReady = true;
		}

		if( pAudioTableInstance->pAudioTableInstanceCallback != NULL && pAudioTableInstance->bNeedToDestroy == false )
		{
			pAudioTableInstance->pAudioTableInstanceCallback( pAudioTableInstance, true );
		}
		return FMOD_OK;
	
	}

```

That would depend on whether you filled in the `Sound *sound` inside [`FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES`](https://fmod.com/resources/documentation-api?version=2.02&page=studio-api-eventinstance.html#fmod_studio_programmer_sound_properties) in the [`FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND`](https://fmod.com/resources/documentation-api?version=2.02&page=studio-api-eventinstance.html#fmod_studio_event_callback) callback though, so seeing the full callback should help me reproduce the issue and figure out what might be going wrong.

---

<div class="post-metadata">

**Author:** ![kylotonn](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@kylotonn](https://qa.fmod.com/u/kylotonn)\
**Post date:** [May 12, 2022, 1:19pm UTC](https://qa.fmod.com/t/fmod-getlength-returns-fmod-err-notready-on-very-short-programmer-sound/18716/3 "2022-05-12T13:19:19Z")

</div>

Hi !  
Here is a more complete code source:  
We are storing inside the EventInstance’s user data a structure called AudioTableInstance that contains FMOD::Sound\*

```auto
struct AudioTableInstance
{
    String sEventDescName;
    EventDesc oEventDesc = I_AUDIO_INVALID_EVENT_DESC;
    EventInstance oEventInstance = I_AUDIO_INVALID_EVENT_INSTANCE;
    String sAudioFile;
    
    void* pSound = NULL;	// FMOD::Sound*
    int iSubSoundIndex;
    bool bIsSoundLengthReady = false;
    uint32 iSoundLenghtMs;
};

```

Programmer Sound EventInstance creation and play command:

```auto
AudioTableInstance* AudioDriverFModStudio::CreateAudioTableInstance( const char* pEventName, AudioTableInstanceCallback pCallback, void* pCallbackUserData )
{
    // Get event desc
    EventDesc oEventDesc = GetEventDesc( pEventName );
    if( oEventDesc == I_AUDIO_INVALID_EVENT_DESC )
    {
        return NULL;

    }
    FMOD::Studio::EventDescription* pFMODEventDesc = PA_EVENTDESC_TO_FMOD( oEventDesc );
    PA_ASSERT( pFMODEventDesc!= NULL );

    // Create an event instance
    FMOD::Studio::EventInstance* pFMODEventInstance = NULL;
    FMOD_RESULT iResult = pFMODEventDesc->createInstance( &pFMODEventInstance );
    if( iResult != FMOD_OK )
    {
        PA_FMOD_LOG_AND_ASSERT_ON_ERROR( ERROR, iResult );
        return NULL;
    }

    AudioTableInstance* pResult = new AudioTableInstance();
    pResult->sEventDescName = pEventName;
    pResult->oEventDesc = oEventDesc;
    pResult->oEventInstance = PA_FMOD_TO_EVENTINSTANCE( pFMODEventInstance );
    pResult->pAudioTableInstanceCallback = pCallback;
    pResult->pCallbackUserData = pCallbackUserData;

    iResult = pFMODEventInstance->setUserData( pResult );
    PA_FMOD_LOG_AND_ASSERT_ON_ERROR( ERROR, iResult );
    pFMODEventInstance->setCallback( AudioTableSoundCallback, FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND | FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND | FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED | FMOD_STUDIO_EVENT_CALLBACK_SOUND_STOPPED | FMOD_STUDIO_EVENT_CALLBACK_DESTROYED );
    PA_FMOD_LOG_AND_ASSERT_ON_ERROR( ERROR, iResult );

    PA_VERIFY( pResult->oLockVar.Create() == PA_OK );
    
    return pResult;
}

void AudioDriverFModStudio::AudioTablePlaySound( AudioTableInstance* pAudioTableInstance, const String& sAudioFile )
{
    PA_ASSERT( pAudioTableInstance != NULL );
    pAudioTableInstance->sAudioFile = sAudioFile;
    pAudioTableInstance->bIsSoundLengthReady = false;
    pAudioTableInstance->iSoundLenghtMs = (uint32)-1;
    EventInstanceCommand( pAudioTableInstance->oEventInstance, 
    Audio::IAudioDriver::EVENT_PLAY );
}

```

And the main callback function:

```auto
// Audio Table event callback
FMOD_RESULT F_CALLBACK AudioDriverFModStudio::AudioTableSoundCallback( FMOD_STUDIO_EVENT_CALLBACK_TYPE type, FMOD_STUDIO_EVENTINSTANCE* event, void* parameters )
{
    FMOD::Studio::EventInstance* pEventInstance = (FMOD::Studio::EventInstance*)event;
    FMOD_RESULT iResult;

    AudioDriverFModStudio* pAudioDriver = (AudioDriverFModStudio*)s_pAudioDriver;
    PA_ASSERT( pAudioDriver != NULL );
    PA_ASSERT( pAudioDriver->m_pSystem != NULL );
    PA_ASSERT( pAudioDriver->m_pEventSystem != NULL );

    AudioTableInstance* pAudioTableInstance = NULL;
    pEventInstance->getUserData( ( void** )&pAudioTableInstance );
    PA_ASSERT( pAudioTableInstance != NULL );
    switch( type )
    {
        case FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND:
        {
            FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES* props = (FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES*)parameters;

            // get the user - defined context of the programmer sound
            PA_ASSERT( pAudioTableInstance != NULL );

            // Find the audio file in the audio table with the key
            FMOD_STUDIO_SOUND_INFO info;
            iResult = pAudioDriver->m_pEventSystem->getSoundInfo( pAudioTableInstance->sAudioFile.c_str(), &info );
            PA_FMOD_LOG_STRING_AND_ASSERT_ON_ERROR( ERROR, iResult, pAudioTableInstance->sAudioFile.c_str() );

            FMOD::Sound* pSound = NULL;
            iResult = pAudioDriver->m_pSystem->createSound( info.name_or_data, FMOD_LOOP_NORMAL | FMOD_CREATECOMPRESSEDSAMPLE | FMOD_NONBLOCKING | info.mode, &info.exinfo, &pSound );
            PA_FMOD_LOG_AND_ASSERT_ON_ERROR( ERROR, iResult );
            //https://qa.fmod.com/t/how-to-know-the-duration-of-a-programmer-sound-in-advance/14987/2

            pAudioTableInstance->pSound = pSound;
            pAudioTableInstance->iSubSoundIndex = info.subsoundindex;
            props->sound = (FMOD_SOUND*)pSound;
            props->subsoundIndex = info.subsoundindex;

            return FMOD_OK;
        }
        case FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED:
        {
            FMOD::Sound* pSound = (FMOD::Sound*)pAudioTableInstance->pSound;
            FMOD::Sound* pSubSound = NULL;
            iResult = pSound->getSubSound( pAudioTableInstance->iSubSoundIndex, &pSubSound );
            PA_FMOD_LOG_AND_ASSERT_ON_ERROR( ERROR, iResult );

            uint32 iSoundLength = 0;
            uint32 iSubSoundLength = 0;
            iResult = pSound->getLength( &iSoundLength, FMOD_TIMEUNIT_MS );
            iResult = pSubSound->getLength( &iSubSoundLength, FMOD_TIMEUNIT_MS );
            PA_LOG( "Sound length: %d VS %d", iSoundLength, iSubSoundLength );

            return FMOD_OK;

        }
    }
}

```

In my case, I’m just using one ProgrammerSound / AudioTable, that can uses different “subsound”  
My goal is the get the subsound lengh as soon as possible  
On some very short subsound:

```nohighlight

```

returns FMOD\_ERR\_NOTREADY

---

<div class="post-metadata">

**Author:** ![jeff\_fmod](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/jeff_fmod/32/1766_2.png) [@jeff\_fmod](https://qa.fmod.com/u/jeff_fmod)\
**Post date:** [May 16, 2022, 5:40am UTC](https://qa.fmod.com/t/fmod-getlength-returns-fmod-err-notready-on-very-short-programmer-sound/18716/4 "2022-05-16T05:40:57Z")

</div>

Thank you for the additional information. I have not been able to reproduce any issues with getting the length of a subsound. The only thing I can think of is the value of `iSubSoundIndex` changing some time between the CREATE\_PROGRAMMER\_SOUND callback and the SOUND\_PLAYED callback, resulting in the newly indexed sound not being ready. If this is the case, then following the recommended approach of calling `getLength` on the sound passed in via the `parameters` argument instead of retrieving it via `pAudioTableInstance->getSubSound` should fix the issue.

```cpp
...
case FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED:
{
    FMOD::Sound* pSubSound = (FMOD::Sound*)parameters; //This is the ready-to-play subsound

    uint32 iSubSoundLength = 0;
    iResult = pSubSound->getLength( &iSubSoundLength, FMOD_TIMEUNIT_MS );
    PA_LOG( "Sound length: %d", iSubSoundLength );

    return FMOD_OK;

}
...

```

Please try implementing that and let me know if you are still getting errors.
