/* * THE H FILE */ #ifndef _LLAMABOX_AUDIOSYSTEM_H_ #define _LLAMABOX_AUDIOSYSTEM_H_ #include #include #include typedef struct _SWAUDIOINFO { unsigned int uiPos; // Seconds.msecs float fSpec_Left[64]; // Spectrum data array for left channel float fSpec_Right[64]; // Spectrum data array for right channel bool bIsPlaying; // TRUE = song is playing } SWAUDIOINFO; class AudioSystem : public sigc::trackable { public: AudioSystem(); ~AudioSystem(); static AudioSystem* system(); void destroy(); int init(); void release(); int play_file( const std::string& strPath ); int cache_file( const std::string& strPath ); void play(); void pause(); void stop(); void jump_position( int iJump ); void set_position( int iPos ); int position() const; int track_length() const; //bool is_playing() const; //void song_info() const; void spectrum_data(float* left, float* right, int length) const; void waveform_data(float* left, float* right, int length) const; private: static AudioSystem* m_instance; Xmms::Client m_client; // signals public: void signal_track_over(); // Called when the track is over (handled by playlist to start a new song) void signal_new_info( SWAUDIOINFO *newinfo ); // Called when new song starts void signal_status_changed(); // Called when play status changes (playing, paused, stopped, seeking?) void signal_position_changed(int ms); // Called when position changes due to set_position or other events but NOT while playing. // Event handlers private: bool current_id_changed( const unsigned int& id ); bool error_handler( const std::string& error ); }; // Convenience function for grabbing the instance AudioSystem* audio_system(); #endif /* * The C File */ #include "audiosystem.h" #include using namespace std; AudioSystem* AudioSystem::m_instance = 0; AudioSystem::AudioSystem() : m_client("LlamaAudio") { cout << "Creating AudioSystem.\n"; init(); } AudioSystem::~AudioSystem() { release(); } /** * Fetches and optionally creates the singleton AudioSystem instance */ AudioSystem* AudioSystem::system() { if( !m_instance ) { cout << "Does not exist, creating.\n"; m_instance = new AudioSystem(); } return m_instance; } /** * Initializes FMOD */ int AudioSystem::init() { try { m_client.connect( std::getenv("XMMS_PATH") ); } catch( Xmms::connection_error& err ) { std::cout << "Connection failed: " << err.what() << std::endl; return EXIT_FAILURE; // TODO: Something more graceful } m_client.playback.currentID()( Xmms::bind(&AudioSystem::current_id_changed, this), Xmms::bind(&AudioSystem::error_handler, this)); return EXIT_SUCCESS; } bool AudioSystem::current_id_changed( const unsigned int& id) { cout << "ID Changed to: " << id << "\n"; } bool AudioSystem::error_handler( const std::string& error ) { /* * This is the error callback function which will get called * if there was an error in the process. */ std::cout << "Error: " << error << std::endl; return false; } /** * Destroys the only AudioSystem object, if it exists. */ void AudioSystem::destroy() { if( m_instance ) { delete m_instance; m_instance = 0; } } /** * Releases FMOD (but the AudioSystem still exists) */ void AudioSystem::release() { { /* m_fmodSystem->release(); m_fmodSystem = 0; */ } } /** * Loads and begins playing a track. Interrupts any currently playing track. * @param strPath The path to the requested file. * @return 1 on success */ int AudioSystem::play_file( const string& strPath ) { cout << "Playing File.."; return 1; } int AudioSystem::cache_file( const std::string& strPath ) { return 0; } void AudioSystem::spectrum_data(float* left, float* right, int length) const { } void AudioSystem::waveform_data(float* left, float* right, int length) const { } void AudioSystem::pause() { m_client.playback.pause(); } void AudioSystem::play() { m_client.playback.start(); try { unsigned int id = m_client.playback.currentID(); std::cout << "Currently playing ID is " << id << std::endl; } catch( Xmms::result_error& err ) { std::cout << "playback start returned error, " << err.what() << std::endl; //return EXIT_FAILURE; } } void AudioSystem::stop() { m_client.playback.stop(); } void AudioSystem::set_position( int ms ) { } // Returns ms int AudioSystem::position() const { return 69; } void AudioSystem::jump_position( int iJump ) { // It is pointless to jump 0 ms AudioSystem* audio_system() { return AudioSystem::system(); } int AudioSystem::track_length() const { return 0; //m_trackLength; }