0

我目前正在为我的项目创建一个音响系统。每次调用 PlayAsync 在 std::thread 回调中创建声音实例。声音数据在此回调中循环进行。当线程继续时,它将声音实例存储在静态向量中。当线程结束(声音完成) - 它删除声音实例并减少实例计数。当应用程序结束时 - 它必须立即停止所有声音,向每个声音周期发送中断。

问题在于保持这些声音。我不确定,但我认为向量不是这个目的的正确选择。这是一个代码。

void gSound::PlayAsync()
{
    std::thread t(gSound::Play,mp_Audio,std::ref(*this));
    t.detach();
}
    HRESULT gSound::Play(IXAudio2* s_XAudio,gSound& sound)
{                
    gSound* pSound = new gSound(sound);   
    pSound->m_Disposed = false;         

    HRESULT hr;      
    // Create the source voice
    IXAudio2SourceVoice* pSourceVoice;
    if( FAILED( hr = s_XAudio->CreateSourceVoice( &pSourceVoice, pSound->pwfx ) ) )
    {
        gDebug::ShowMessage(L"Error creating source voice");      
        return hr;
    }

    // Submit the wave sample data using an XAUDIO2_BUFFER structure
    XAUDIO2_BUFFER buffer = {0};
    buffer.pAudioData = pSound->pbWaveData;
    buffer.Flags = XAUDIO2_END_OF_STREAM;  // tell the source voice not to expect any data after this buffer
    buffer.AudioBytes = pSound->cbWaveSize;

    if( FAILED( hr = pSourceVoice->SubmitSourceBuffer( &buffer ) ) )
    {
        gDebug::ShowMessage(L"Error submitting source buffer");
        pSourceVoice->DestroyVoice();   
        return hr;
    }

    hr = pSourceVoice->Start( 0 );     

    // Let the sound play
    BOOL isRunning = TRUE;
    m_soundInstanceCount++;     
    mp_SoundInstances.push_back(pSound); #MARK2
    while( SUCCEEDED( hr ) && isRunning && pSourceVoice != nullptr && !pSound->m_Interrupted)
    {    
        XAUDIO2_VOICE_STATE state;
        pSourceVoice->GetState( &state );
        isRunning = ( state.BuffersQueued > 0 ) != 0;     
        Sleep(10);
    }   
    pSourceVoice->DestroyVoice();   
    delete pSound;pSound = nullptr; //its correct ??
    m_soundInstanceCount--; 
    return 0;    
}

void gSound::InterrupAllSoundInstances()
{
    for(auto Iter = mp_SoundInstances.begin(); Iter != mp_SoundInstances.end(); Iter++)
    {
        if(*Iter != nullptr)//#MARK1
        {
        (*Iter)->m_Interrupted = true;
        }
    }
}

在主应用程序循环之后,我在处理声音对象之前调用应用程序类。

    gSound::InterrupAllSoundInstances();
while (gSound::m_soundInstanceCount>0)//waiting for deleting all sound instances in threads
{

}

问题:

所以#MARK1 - 如何检查向量中的内存验证?我没有这方面的经验。并在尝试检查无效内存时出错(它不等于 null)

还有#MARK2 - 如何正确使用矢量?或者向量是不好的选择?每次我创建声音实例时,它都会增加大小。这样不好。

4

1 回答 1

1

一个典型的问题:

delete pSound;
pSound = nullptr; // issue

这不符合你的想法。

它将有效地设置pSound为 null,但也有相同指针的其他副本(向量中至少有一个)不会被无效。这就是为什么你没有nullptr在你的vector.

相反,您可以将索引注册到向量中并使其无效:mp_SoundInstances[index] = nullptr;.

但是,恐怕您根本不了解内存处理并且缺乏结构。对于内存处理,如果没有细节就很难说清楚,而且您的系统似乎足够复杂,恐怕它会说得太长而无法解释。对于结构,您应该阅读一些有关Observer模式的信息。

于 2012-06-03T14:43:36.180 回答