_BLOCK_TYPE_IS_VALID assertion with maps


B

Barzo

Hi,

In the following code, I have a _BLOCK_TYPE_IS_VALID assertion when
the CDeviceManager destructor is called.
The 'IAudioCallBackDevice *caller' argument is an object created and
destroyed outside this code.
Could someone give me some suggestion? I cannot find where is the
mistake!



class IAudioCallBackDevice;
class CDeviceManager;

template<class T>
class Singleton : private boost::noncopyable
{

public:
static T& instance()
{
boost::call_once(init, flag);
return *t;
}

static void init() // never throws
{
t.reset(new T());
}

protected:
~Singleton() {}
Singleton() {}

private:
static boost::scoped_ptr<T> t;
static boost::eek:nce_flag flag;

};

template<class T> boost::scoped_ptr<T> Singleton<T>::t(0);
template<class T> boost::eek:nce_flag Singleton<T>::flag =
BOOST_ONCE_INIT;


//----------------------------------------------------------------------------

class CDevicesManager : public Singleton<CDevicesManager>
{
friend class Singleton<CDevicesManager>;

typedef std::map<LONG, CDeviceManager*> TManagersMap;

public:

EAudioLibRetVal InitDevice(LONG device_id,
RtAudio::Api audio_api,
IAudioCallBackDevice *caller);

~CDevicesManager();

private:
TManagersMap Managers_; // A manager for each phisical device

};

//----------------------------------------------------------------------------


class CDeviceManager
{

struct TAudioDevParams
{
RtAudio::StreamParameters OutParams;
RtAudio::StreamParameters InParams;
RtAudioFormat Format;
unsigned int SampleRate;
unsigned int BufferFrames;
RtAudio::StreamOptions Options;
};

struct TCallbackUserData
{
CDeviceManager* ptrThis;
RtAudio::Api CurrentApi;
};


typedef RtAudio* pAudioDev;
typedef IAudioCallBackDevice* pListener;

typedef std::map<INT, pListener> TListeners;
typedef std::map<RtAudio::Api, TListeners> TListenersMap;
typedef std::map<RtAudio::Api, pAudioDev> TAudioDevsMap;
typedef std::map<RtAudio::Api, TAudioDevParams>
TAudioDevParamsMap;
typedef std::map<RtAudio::Api, TCallbackUserData>
TCallbackUserDataMap;


public:

void
NotifyDeviceHandlerDestroy(IAudioCallBackDevice *caller);

EAudioLibRetVal InitDevice(RtAudio::Api audio_api,
IAudioCallBackDevice *caller);


CDeviceManager(CDevicesManager* Manager, LONG DeviceID) :
Manager_(Manager),
DeviceID_(DeviceID) {};

~CDeviceManager();

private:

CDevicesManager* Manager_;
LONG DeviceID_; // The Device ID which
the manager refers to
TAudioDevsMap Devs_; // From
RtAudio::Api::LINUX_ALSA to RtAudio::Api::WINDOWS_DS
TListenersMap ListenersMap_; // From
RtAudio::Api::LINUX_ALSA to RtAudio::Api::WINDOWS_DS

};

//----------------------------------------------------------------------------

class IAudioCallBackDevice
{
public:
IAudioCallBackDevice()
{
srand((unsigned)time(0));
id_ = rand();
};

~IAudioCallBackDevice()
{ // Notify to the Manager when a Device handler is destroyed
if (dev_manager_)
dev_manager_->NotifyDeviceHandlerDestroy(this);
};

inline void SetDeviceManager(CDeviceManager* dev_manager,
RtAudio::Api audio_api)
{ // Sets the Device handler Manager
dev_manager_ = dev_manager;
audio_api_ = audio_api;
};

inline RtAudio::Api GetApi() { return audio_api_; }

virtual INT AudioCallBack(void *AudioBuffer,
UINT nFrames,
double streamTime,
RtAudioStreamStatus status) = 0;

inline CDeviceManager* getDeviceManager() { return
dev_manager_; };

inline INT GetID() { return id_; };

inline bool operator!=(const IAudioCallBackDevice& obj) const {
return (this->id_ != obj.id_);
}

inline bool operator==(const IAudioCallBackDevice& obj) const {
return (this->id_ == obj.id_);
}

private:
CDeviceManager* dev_manager_;
RtAudio::Api audio_api_;
INT id_;
};



The implementation...


//----------------------------------------------------------------------------

EAudioLibRetVal CDevicesManager::InitDevice(LONG
device_id,
RtAudio::Api
audio_api,
IAudioCallBackDevice
*caller)
{

// First of all check if already exist a DeviceManager for device_id
// and if it doesn't, create it
if ( Managers_.find(device_id) == Managers_.end() )
Managers_[device_id] = new CDeviceManager(this, device_id);

// Set the caller's DeviceManager
(caller)->SetDeviceManager( Managers_[device_id], audio_api );

return Managers_[device_id]->InitDevice( audio_api, caller );

};

//----------------------------------------------------------------------------

CDevicesManager::~CDevicesManager()
{
for( TManagersMap::iterator it = Managers_.begin(); it !=
Managers_.end(); it++ )
delete it->second;
}



//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------



CDeviceManager::~CDeviceManager()
{
//for(TAudioDevsMap::iterator it = Devs_.begin(); it != Devs_.end();
it++ )
TAudioDevsMap::iterator dev = Devs_.begin();
while(dev != Devs_.end())
{
if (dev->second->isStreamRunning()) dev->second->stopStream();
delete dev->second;
Devs_.erase( dev );
dev = Devs_.begin();
}

TListenersMap::iterator it = ListenersMap_.begin();

while(it != ListenersMap_.end())
{
// Remove all listeners
TListeners listeners = it->second;
while (listeners.size() > 0)
listeners.erase(listeners.begin());

//Remove the listeners map
ListenersMap_.erase( it );
it = ListenersMap_.begin();
}
}

//----------------------------------------------------------------------------

EAudioLibRetVal CDeviceManager::InitDevice(RtAudio::Api
audio_api,
IAudioCallBackDevice
*caller)
{
try {

// Searching if the RtAudio class exists for the given Api
// If not, crete it
if ( Devs_.find(audio_api) == Devs_.end() )
Devs_[audio_api] = new RtAudio(audio_api);

DeviceInfo_ = Devs_[audio_api]->getDeviceInfo(DeviceID_);

TListeners lst = ListenersMap_[audio_api];

// Add the listeners
if ( lst.find( caller->GetID() ) == lst.end() )
lst[caller->GetID()] = caller;

// Return a pointer to the device
return RV_NO_ERROR;
}
catch (RtError& e) { return
static_cast<EAudioLibRetVal>(e.getType()); }

}

//----------------------------------------------------------------------------

void CDeviceManager::NotifyDeviceHandlerDestroy(IAudioCallBackDevice*
caller)
{
// When a device handler is destroyed, I remove it from the
listeners list
ListenersMap_[ caller->GetApi() ].erase( caller->GetID() );
};
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top