From ad1833a4d534e67f6801f3670ce88fca7357778d Mon Sep 17 00:00:00 2001 From: Erik Hofman Date: Thu, 26 Mar 2020 09:54:28 +0100 Subject: [PATCH] Move more modern C++ idioms and use std::unique_ptr for moving daat ownership around --- simgear/sound/openal_test1.cxx | 24 ++++---- simgear/sound/readwav.cxx | 10 ++-- simgear/sound/sample.cxx | 36 +----------- simgear/sound/sample.hxx | 29 ++++------ simgear/sound/sample_group.cxx | 12 ++-- simgear/sound/sample_group.hxx | 4 +- simgear/sound/soundmgr.hxx | 2 +- simgear/sound/soundmgr_aeonwave.cxx | 67 +++++++++-------------- simgear/sound/soundmgr_openal.cxx | 44 +++++++-------- simgear/sound/soundmgr_openal_private.hxx | 4 +- simgear/sound/xmlsound.cxx | 8 +-- simgear/sound/xmlsound.hxx | 8 +-- 12 files changed, 96 insertions(+), 152 deletions(-) diff --git a/simgear/sound/openal_test1.cxx b/simgear/sound/openal_test1.cxx index c614e564..952c522e 100644 --- a/simgear/sound/openal_test1.cxx +++ b/simgear/sound/openal_test1.cxx @@ -75,23 +75,23 @@ ALuint createBufferFromFile(const SGPath& path) } -int main( int argc, char *argv[] ) +int main( int argc, char *argv[] ) { sglog().setLogLevels( SG_ALL, SG_ALERT ); - + // initialize OpenAL - ALCdevice *dev = alcOpenDevice(NULL); + ALCdevice *dev = alcOpenDevice(nullptr); if (!dev) { SG_LOG( SG_GENERAL, SG_ALERT, "Audio device initialization failed!" ); return EXIT_FAILURE; } - - ALCcontext *context = alcCreateContext(dev, NULL); + + ALCcontext *context = alcCreateContext(dev, nullptr); if (!context) { SG_LOG( SG_GENERAL, SG_ALERT, "Audio context initialization failed!" ); return EXIT_FAILURE; } - + alcMakeContextCurrent( context ); // Position of the listener. @@ -111,7 +111,7 @@ int main( int argc, char *argv[] ) listener_vel[0] = 0.0; listener_vel[1] = 0.0; listener_vel[2] = 0.0; - + listener_ori[0] = 0.0; listener_ori[1] = 0.0; listener_ori[2] = -1.0; @@ -163,10 +163,10 @@ int main( int argc, char *argv[] ) alSourcePlay( source ); sleep(10); - - alcMakeContextCurrent(NULL); - alcDestroyContext(context); - alcCloseDevice(dev); - + + alcMakeContextCurrent(nullptr); + alcDestroyContext(context); + alcCloseDevice(dev); + return 0; } diff --git a/simgear/sound/readwav.cxx b/simgear/sound/readwav.cxx index d5c16cd2..ffb0da0d 100644 --- a/simgear/sound/readwav.cxx +++ b/simgear/sound/readwav.cxx @@ -46,7 +46,7 @@ namespace ALfloat frequency; SGPath path; - Buffer() : data(NULL), format(AL_NONE), length(0), frequency(0.0f) {} + Buffer() : data(nullptr), format(AL_NONE), length(0), frequency(0.0f) {} ~Buffer() { @@ -119,7 +119,7 @@ namespace uint8_t *d = (uint8_t *) b->data; size_t newLength = b->length * 2; int16_t *buf = (int16_t *) malloc(newLength); - if (buf == NULL) + if (buf == nullptr) throw sg_exception("malloc failed decoing ULaw WAV file"); for (ALsizei i = 0; i < b->length; i++) { @@ -193,7 +193,7 @@ namespace size_t blocks = b->length/block_align; size_t newLength = block_align * blocks * 4; int16_t *buf = (int16_t *) malloc ( newLength ); - if (buf == NULL) + if (buf == nullptr) throw sg_exception("malloc failed decoing IMA4 WAV file"); int16_t *ptr = buf; @@ -260,7 +260,7 @@ namespace void loadWavFile(gzFile fd, Buffer* b) { - assert(b->data == NULL); + assert(b->data == nullptr); bool found_header = false; bool compressed = false; @@ -405,7 +405,7 @@ ALvoid* loadWAVFromFile(const SGPath& path, unsigned int& format, ALsizei& size, } ALvoid* data = b.data; - b.data = NULL; // don't free when Buffer does out of scope + b.data = nullptr; // don't free when Buffer does out of scope format = b.format; block_align = b.block_align; size = b.length; diff --git a/simgear/sound/sample.cxx b/simgear/sound/sample.cxx index e3db3445..2ff503a6 100644 --- a/simgear/sound/sample.cxx +++ b/simgear/sound/sample.cxx @@ -88,40 +88,18 @@ SGSoundSample::SGSoundSample(const char *file, const SGPath& currentDir) : } // constructor -SGSoundSample::SGSoundSample( const unsigned char** data, +SGSoundSample::SGSoundSample( std::unique_ptr& data, int len, int freq, int format ) { SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" ); - _data = (unsigned char*)*data; *data = NULL; + + _data = std::move(data); set_frequency(freq); set_format(format); set_size(len); } -// constructor -SGSoundSample::SGSoundSample( void** data, int len, int freq, int format ) : - _is_file(false), - _changed(true), - _valid_source(false), - _source(SGSoundMgr::NO_SOURCE), - _valid_buffer(false), - _buffer(SGSoundMgr::NO_BUFFER) -{ - SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" ); - _data = (unsigned char*)*data; *data = NULL; - - set_frequency(freq); - set_format(format); - set_size(len); -} - - -// destructor -SGSoundSample::~SGSoundSample() { - if ( _data != NULL ) free(_data); -} - void SGSoundSample::update_pos_and_orientation() { if (_use_pos_props) { @@ -148,11 +126,3 @@ SGPath SGSoundSample::file_path() const return SGPath(_refname); } - -void SGSoundSample::free_data() -{ - if ( _data != NULL ) { - free( _data ); - } - _data = NULL; -} diff --git a/simgear/sound/sample.hxx b/simgear/sound/sample.hxx index a67524d7..bc12b050 100644 --- a/simgear/sound/sample.hxx +++ b/simgear/sound/sample.hxx @@ -255,7 +255,8 @@ public: * Empty constructor, can be used to read data to the systems * memory and not to the driver. */ - SGSoundSample() {}; + SGSoundSample() = default; + virtual ~SGSoundSample () = default; /** * Constructor @@ -269,20 +270,15 @@ public: * @param data Pointer to a memory buffer containing this audio sample data The application may free the data by calling free_data(), otherwise it will be resident until the class is destroyed. This pointer will be - set to NULL after calling this function. + set to nullptr after calling this function. * @param len Byte length of array * @param freq Frequency of the provided data (bytes per second) * @param format SimGear format id of the data */ - SGSoundSample( void** data, int len, int freq, int format=SG_SAMPLE_MONO8 ); - SGSoundSample( const unsigned char** data, int len, int freq, + SGSoundSample( std::unique_ptr& data, + int len, int freq, int format = SG_SAMPLE_MONO8 ); - /** - * Destructor - */ - virtual ~SGSoundSample (); - /** * Test if this audio sample configuration has changed since the last call. * Calling this function will reset the flag so calling it a second @@ -360,25 +356,22 @@ public: /** * Set the data associated with this audio sample * @param data Pointer to a memory block containg this audio sample data. - This pointer will be set to NULL after calling this function. + This pointer will be set to nullptr after calling this function. */ - inline void set_data( const unsigned char **data ) { - _data = (unsigned char*)*data; *data = NULL; - } - inline void set_data( const void **data ) { - _data = (unsigned char*)*data; *data = NULL; + inline void set_data( std::unique_ptr& data ) { + _data = std::move(data); } /** * Return the data associated with this audio sample. * @return A pointer to this sound data of this audio sample. */ - inline void* get_data() const { return _data; } + inline unsigned char* get_data() const { return _data.get(); } /** * Free the data associated with this audio sample */ - void free_data(); + inline void free_data() { _data = nullptr; } /** * Set the source id of this source @@ -607,7 +600,7 @@ protected: unsigned int _source = SGSoundMgr::NO_SOURCE; private: - unsigned char* _data = NULL; + std::unique_ptr _data = { nullptr, free }; // Buffers hold sound data. bool _valid_buffer = false; diff --git a/simgear/sound/sample_group.cxx b/simgear/sound/sample_group.cxx index d303dee5..0681e40e 100644 --- a/simgear/sound/sample_group.cxx +++ b/simgear/sound/sample_group.cxx @@ -180,12 +180,12 @@ bool SGSampleGroup::exists( const std::string &refname ) { // return a pointer to the SGSoundSample if the specified sound exists -// in the sound manager system, otherwise return NULL +// in the sound manager system, otherwise return nullptr SGSoundSample *SGSampleGroup::find( const std::string &refname ) { auto sample_it = _samples.find( refname ); if ( sample_it == _samples.end() ) { // sample was not found - return NULL; + return nullptr; } return sample_it->second; @@ -241,7 +241,7 @@ bool SGSampleGroup::play( const std::string &refname, { SGSoundSample *sample = find( refname ); - if ( sample == NULL ) { + if ( sample == nullptr ) { return false; } @@ -254,7 +254,7 @@ bool SGSampleGroup::play( const std::string &refname, bool SGSampleGroup::is_playing( const std::string& refname ) { SGSoundSample *sample = find( refname ); - if ( sample == NULL ) { + if ( sample == nullptr ) { return false; } @@ -265,7 +265,7 @@ bool SGSampleGroup::is_playing( const std::string& refname ) { bool SGSampleGroup::stop( const std::string& refname ) { SGSoundSample *sample = find( refname ); - if ( sample == NULL ) { + if ( sample == nullptr ) { return false; } @@ -357,7 +357,7 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample ) bool SGSampleGroup::testForError(void *p, std::string s) { - if (p == NULL) { + if (p == nullptr) { SG_LOG( SG_SOUND, SG_ALERT, "Error (sample group): " << s); return true; } diff --git a/simgear/sound/sample_group.hxx b/simgear/sound/sample_group.hxx index be63224d..d592d857 100644 --- a/simgear/sound/sample_group.hxx +++ b/simgear/sound/sample_group.hxx @@ -39,7 +39,7 @@ #include "sample.hxx" -typedef std::map < std::string, SGSharedPtr > sample_map; +using sample_map = std::map< std::string, SGSharedPtr >; class SGSoundMgr; @@ -212,7 +212,7 @@ public: void tie_to_listener() { _tied_to_listener = true; } protected: - SGSoundMgr *_smgr = NULL; + SGSoundMgr *_smgr = nullptr; std::string _refname = ""; bool _active = false; diff --git a/simgear/sound/soundmgr.hxx b/simgear/sound/soundmgr.hxx index a3360dfa..983c3f75 100644 --- a/simgear/sound/soundmgr.hxx +++ b/simgear/sound/soundmgr.hxx @@ -307,7 +307,7 @@ public: * @return true if succesful, false on error */ virtual bool load( const std::string &samplepath, - void **data, + void** data, int *format, size_t *size, int *freq, diff --git a/simgear/sound/soundmgr_aeonwave.cxx b/simgear/sound/soundmgr_aeonwave.cxx index 7a0fa32f..d282355c 100644 --- a/simgear/sound/soundmgr_aeonwave.cxx +++ b/simgear/sound/soundmgr_aeonwave.cxx @@ -48,11 +48,11 @@ // We keep track of the emitters ourselves. -typedef std::map < unsigned int, aax::Emitter > source_map; +using source_map = std::map< unsigned int, aax::Emitter >; // The AeonWave class keeps track of the buffers, so use a reference instead. -typedef std::map < unsigned int, aax::Buffer& > buffer_map; -typedef std::map < std::string, SGSharedPtr > sample_group_map; +using buffer_map = std::map< unsigned int, aax::Buffer& >; +using sample_group_map = std::map< std::string, SGSharedPtr >; #ifndef NDEBUG # define TRY(a) if ((a) == 0) printf("%i: %s\n", __LINE__, d->_aax.strerror()) @@ -64,14 +64,7 @@ typedef std::map < std::string, SGSharedPtr > sample_group_map; class SGSoundMgr::SoundManagerPrivate { public: - SoundManagerPrivate() : - _absolute_pos(SGVec3d::zeros()), - _base_pos(SGVec3d::zeros()), - _orientation(SGQuatd::zeros()), - _buffer_id(0), - _source_id(0) - { - } + SoundManagerPrivate() = default; ~SoundManagerPrivate() { @@ -96,11 +89,11 @@ public: aax::AeonWave _aax; aax::Matrix64 _mtx; - SGVec3d _absolute_pos; - SGVec3d _base_pos; - SGQuatd _orientation; + SGVec3d _absolute_pos = SGVec3d::zeros(); + SGVec3d _base_pos = SGVec3d::zeros(); + SGQuatd _orientation = SGQuatd::zeros(); - unsigned int _buffer_id; + unsigned int _buffer_id = 0; buffer_map _buffers; aax::Buffer nullBuffer; aax::Buffer& get_buffer(unsigned int id) { @@ -110,7 +103,7 @@ public: return nullBuffer; } - unsigned int _source_id; + unsigned int _source_id = 0; source_map _sources; aax::Emitter nullEmitter; aax::Emitter& get_emitter(unsigned int id) { @@ -229,10 +222,8 @@ void SGSoundMgr::activate() if ( is_working() ) { _active = true; - for ( auto current = d->_sample_groups.begin(); - current != d->_sample_groups.end(); ++current ) { - SGSampleGroup *sgrp = current->second; - sgrp->activate(); + for ( auto current : d->_sample_groups ) { + current.second->activate(); } } #endif @@ -243,10 +234,8 @@ void SGSoundMgr::stop() { #ifdef ENABLE_SOUND // first stop all sample groups - for ( auto current = d->_sample_groups.begin(); - current != d->_sample_groups.end(); ++ current ) { - SGSampleGroup *sgrp = current->second; - sgrp->stop(); + for ( auto current : d->_sample_groups ) { + current.second->stop(); } d->_buffer_id = 0; @@ -269,10 +258,8 @@ void SGSoundMgr::suspend() { #ifdef ENABLE_SOUND if (is_working()) { - for (auto current = d->_sample_groups.begin(); - current != d->_sample_groups.end(); ++current ) { - SGSampleGroup *sgrp = current->second; - sgrp->stop(); + for (auto current : d->_sample_groups ) { + current.second->stop(); } _active = false; } @@ -283,10 +270,8 @@ void SGSoundMgr::resume() { #ifdef ENABLE_SOUND if (is_working()) { - for ( auto current = d->_sample_groups.begin(); - current != d->_sample_groups.end(); ++current ) { - SGSampleGroup *sgrp = current->second; - sgrp->resume(); + for ( auto current : d->_sample_groups ) { + current.second->resume(); } _active = true; } @@ -302,10 +287,8 @@ void SGSoundMgr::update( double dt ) d->update_pos_and_orientation(); } - for ( auto current = d->_sample_groups.begin(); - current != d->_sample_groups.end(); ++current ) { - SGSampleGroup *sgrp = current->second; - sgrp->update(dt); + for ( auto current : d->_sample_groups ) { + current.second->update(dt); } if (_changed) { @@ -371,21 +354,21 @@ bool SGSoundMgr::exists( const std::string &refname ) { // return a pointer to the SGSampleGroup if the specified sound exists -// in the sound manager system, otherwise return NULL +// in the sound manager system, otherwise return nullptr SGSampleGroup *SGSoundMgr::find( const std::string &refname, bool create ) { auto sample_grp_it = d->_sample_groups.find( refname ); if ( sample_grp_it == d->_sample_groups.end() ) { // sample group was not found. if (create) { - SGSampleGroup* sgrp = new SGSampleGroup(this, refname); + SGSampleGroup *sgrp = new SGSampleGroup(this, refname); add( sgrp, refname ); return sgrp; } else - return NULL; + return nullptr; } - return sample_grp_it->second; + return sample_grp_it->second.get(); } @@ -695,7 +678,7 @@ vector SGSoundMgr::get_available_devices() bool SGSoundMgr::testForError(void *p, std::string s) { - if (p == NULL) { + if (p == nullptr) { SG_LOG( SG_SOUND, SG_ALERT, "Error: " << s); return true; } @@ -718,7 +701,7 @@ bool SGSoundMgr::testForError(std::string s, std::string name) bool SGSoundMgr::is_working() const { - return ((const void*)d->_aax != NULL ? true : false); + return ((const void*)d->_aax != nullptr ? true : false); } const SGQuatd& SGSoundMgr::get_orientation() const diff --git a/simgear/sound/soundmgr_openal.cxx b/simgear/sound/soundmgr_openal.cxx index 8b91652d..f00cfaab 100644 --- a/simgear/sound/soundmgr_openal.cxx +++ b/simgear/sound/soundmgr_openal.cxx @@ -68,8 +68,8 @@ class SGSoundMgr::SoundManagerPrivate { public: SoundManagerPrivate() : - _device(NULL), - _context(NULL), + _device(nullptr), + _context(nullptr), _absolute_pos(SGVec3d::zeros()), _base_pos(SGVec3d::zeros()), _orientation(SGQuatd::zeros()) @@ -173,10 +173,10 @@ void SGSoundMgr::init() d->_sources_in_use.clear(); d->_sources_in_use.reserve( MAX_SOURCES ); - ALCdevice *device = NULL; + ALCdevice *device = nullptr; const char* devname = _device_name.c_str(); if (_device_name == "") - devname = NULL; // use default device + devname = nullptr; // use default device else { // try non-default device @@ -184,13 +184,13 @@ void SGSoundMgr::init() } if ((!devname)||(testForError(device, "Audio device not available, trying default.")) ) { - device = alcOpenDevice(NULL); + device = alcOpenDevice(nullptr); if (testForError(device, "Default audio device not available.") ) { return; } } - ALCcontext *context = alcCreateContext(device, NULL); + ALCcontext *context = alcCreateContext(device, nullptr); testForALCError("context creation."); if ( testForError(context, "Unable to create a valid context.") ) { alcCloseDevice (device); @@ -204,7 +204,7 @@ void SGSoundMgr::init() return; } - if (d->_context != NULL) + if (d->_context != nullptr) { SG_LOG(SG_SOUND, SG_ALERT, "context is already assigned"); } @@ -324,8 +324,8 @@ void SGSoundMgr::stop() _active = false; alcDestroyContext(d->_context); alcCloseDevice(d->_device); - d->_context = NULL; - d->_device = NULL; + d->_context = nullptr; + d->_device = nullptr; _renderer = "unknown"; _vendor = "unknown"; @@ -448,7 +448,7 @@ bool SGSoundMgr::exists( const std::string &refname ) { // return a pointer to the SGSampleGroup if the specified sound exists -// in the sound manager system, otherwise return NULL +// in the sound manager system, otherwise return nullptr SGSampleGroup *SGSoundMgr::find( const std::string &refname, bool create ) { auto sample_grp_it = d->_sample_groups.find( refname ); if ( sample_grp_it == d->_sample_groups.end() ) { @@ -459,7 +459,7 @@ SGSampleGroup *SGSoundMgr::find( const std::string &refname, bool create ) { return sgrp; } else - return NULL; + return nullptr; } return sample_grp_it->second; @@ -525,7 +525,7 @@ unsigned int SGSoundMgr::request_buffer(SGSoundSample *sample) if ( !sample->is_valid_buffer() ) { // sample was not yet loaded or removed again std::string sample_name = sample->get_sample_name(); - void *sample_data = NULL; + void* sample_data = nullptr; // see if the sample name is already cached auto buffer_it = d->_buffers.find( sample_name ); @@ -784,7 +784,7 @@ void SGSoundMgr::update_sample_config( SGSoundSample *sample, SGVec3d& position, bool SGSoundMgr::load( const std::string &samplepath, - void **dbuf, + void** dbuf, int *fmt, size_t *sz, int *frq, @@ -797,18 +797,16 @@ bool SGSoundMgr::load( const std::string &samplepath, unsigned int blocksz; ALsizei size; ALsizei freq; - ALvoid *data; - ALfloat freqf; - data = simgear::loadWAVFromFile(samplepath, format, size, freqf, blocksz); + auto data = simgear::loadWAVFromFile(samplepath, format, size, freqf, blocksz); freq = (ALsizei)freqf; - if (data == NULL) { + if (data == nullptr) { throw sg_io_exception("Failed to load wav file", sg_location(samplepath)); } if (format == AL_FORMAT_STEREO8 || format == AL_FORMAT_STEREO16) { - free(data); + free(data); throw sg_io_exception("Warning: STEREO files are not supported for 3D audio effects: " + samplepath); } @@ -827,10 +825,10 @@ vector SGSoundMgr::get_available_devices() #ifdef ENABLE_SOUND const ALCchar *s; - if (alcIsExtensionPresent(NULL, "ALC_enumerate_all_EXT") == AL_TRUE) { - s = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); + if (alcIsExtensionPresent(nullptr, "ALC_enumerate_all_EXT") == AL_TRUE) { + s = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER); } else { - s = alcGetString(NULL, ALC_DEVICE_SPECIFIER); + s = alcGetString(nullptr, ALC_DEVICE_SPECIFIER); } if (s) { @@ -851,7 +849,7 @@ vector SGSoundMgr::get_available_devices() bool SGSoundMgr::testForError(void *p, std::string s) { - if (p == NULL) { + if (p == nullptr) { SG_LOG( SG_SOUND, SG_ALERT, "Error: " << s); return true; } @@ -889,7 +887,7 @@ bool SGSoundMgr::testForALCError(std::string s) bool SGSoundMgr::is_working() const { - return (d->_device != NULL); + return (d->_device != nullptr); } const SGQuatd& SGSoundMgr::get_orientation() const diff --git a/simgear/sound/soundmgr_openal_private.hxx b/simgear/sound/soundmgr_openal_private.hxx index e6407378..81f4cef1 100644 --- a/simgear/sound/soundmgr_openal_private.hxx +++ b/simgear/sound/soundmgr_openal_private.hxx @@ -63,8 +63,8 @@ struct refUint { ~refUint() {}; }; -typedef std::map < std::string, refUint > buffer_map; -typedef std::map < std::string, SGSharedPtr > sample_group_map; +using buffer_map = std::map < std::string, refUint >; +using sample_group_map = std::map < std::string, SGSharedPtr >; inline bool isNaN(float *v) { return (SGMisc::isNaN(v[0]) || SGMisc::isNaN(v[1]) || SGMisc::isNaN(v[2])); diff --git a/simgear/sound/xmlsound.cxx b/simgear/sound/xmlsound.cxx index ccb52a66..9646a9c0 100644 --- a/simgear/sound/xmlsound.cxx +++ b/simgear/sound/xmlsound.cxx @@ -150,9 +150,9 @@ SGXmlSound::init( SGPropertyNode *root, string intern_str = kids[i]->getStringValue("internal", ""); if (intern_str == "dt_play") - volume.intern = &_dt_play; + volume.intern = std::make_shared(_dt_play); else if (intern_str == "dt_stop") - volume.intern = &_dt_stop; + volume.intern = std::make_shared(_dt_stop); if ((volume.factor = kids[i]->getDoubleValue("factor", 1.0)) != 0.0) if (volume.factor < 0.0) { @@ -217,9 +217,9 @@ SGXmlSound::init( SGPropertyNode *root, string intern_str = kids[i]->getStringValue("internal", ""); if (intern_str == "dt_play") - pitch.intern = &_dt_play; + pitch.intern = std::make_shared(_dt_play); else if (intern_str == "dt_stop") - pitch.intern = &_dt_stop; + pitch.intern = std::make_shared(_dt_stop); if ((pitch.factor = kids[i]->getDoubleValue("factor", 1.0)) != 0.0) if (pitch.factor < 0.0) { diff --git a/simgear/sound/xmlsound.hxx b/simgear/sound/xmlsound.hxx index 647d83f7..8b24acc6 100644 --- a/simgear/sound/xmlsound.hxx +++ b/simgear/sound/xmlsound.hxx @@ -138,24 +138,24 @@ protected: enum { LEVEL=0, INVERTED, FLIPFLOP }; using _fn_t = std::function; - typedef struct { + using _snd_prop = struct { SGSharedPtr expr; // sound system version 2.0 + std::shared_ptr intern; SGPropertyNode_ptr prop; _fn_t fn; - double *intern; double factor; double offset; double min; double max; bool subtract; - } _snd_prop; + }; using _sound_fn_t = std::map ; _sound_fn_t _sound_fn; private: - SGSampleGroup * _sgrp; + SGSharedPtr _sgrp; SGSharedPtr _sample; SGSharedPtr _condition;