/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Simon Hofmann co-programmer: */ #include "sound_control.h" using namespace std; // global variables SoundControl* SoundControl::instance = NULL; // singleton reference int volume = SDL_MIX_MAXVOLUME; int done = 0; int track_number = 1; static Mix_Music* music = NULL; int audio_rate = MIX_DEFAULT_FREQUENCY, audio_channels = MIX_DEFAULT_CHANNELS, audio_buffers = 16384, bits = 0; Uint16 audio_format = MIX_DEFAULT_FORMAT; /** \brief standard constructor This constructor builds a SoundControl Object, which waits for callers. All sound output is handled by this singleton object. */ SoundControl::SoundControl () { /* initializing sound and calling Mix_OpenAudio if(SDL_Init(SDL_INIT_AUDIO)<0){ printf("SDL_Init: INIT_AUDIO error.\n"); } */ if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)){ printf("Mix_OpenAudio: Failed to open audio!\n"); } initialise(); } /** \brief Default destructor */ SoundControl::~SoundControl () { } /** \brief Returns a reference to the singleton */ SoundControl* SoundControl::getInstance() { if (instance == NULL) { instance = new SoundControl; } return instance; } void SoundControl::deleteInstance() { delete instance; instance = NULL; } /** \brief Is called by SoundControl object to initiate all values */ void SoundControl::initialise() { // Print some info Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels); bits=audio_format&0xFF; printf("Opened audio at %d Hz %d bit %s, %d bytes audio buffer\n", audio_rate, bits, audio_channels > 1 ? "stereo" : "mono", audio_buffers ); Mix_VolumeMusic(volume); } /** \brief Sets the number of output Channels (should not be used) */ void SoundControl::setNumberOfChannels (int number_of_channels) { Mix_AllocateChannels(number_of_channels); } /** \brief May be called from any WorldEntity to play a .xm file \param filename: self-explanatory */ int SoundControl::playMod (char* fileName) { Mix_Chunk* chunk = NULL; chunk = Mix_LoadWAV(fileName); if(Mix_PlayChannel(-1, chunk, 0) == -1) { printf("Mix_PlayChannel: %s\n", Mix_GetError()); } } /** \brief May be called from any WorldEntity to play a .wav file \param filename: self-explanatory */ int SoundControl::playWav (char* fileName) { Mix_Chunk* chunk = NULL; chunk = Mix_LoadWAV(fileName); if(Mix_PlayChannel(-1, chunk, 0) == -1) { printf("Mix_PlayChannel: %s\n", Mix_GetError()); } } /** \brief May be called from any WorldEntity to play a .ogg file \param filename: self-explanatory */ int SoundControl::playOgg (char* fileName) { Mix_Music* music = NULL; music = Mix_LoadMUS(fileName); if(Mix_PlayMusic(music, 1) == -1){ printf("Mix_PlayMusic: %s\n",Mix_GetError()); } Mix_HookMusicFinished(musicDone); } /** \brief Heightens the overall volume of output */ void SoundControl::volumeUp () { volume = (volume + 1) << 1; if(volume > SDL_MIX_MAXVOLUME) volume = SDL_MIX_MAXVOLUME; Mix_VolumeMusic(volume); } /** \brief Lowers the overall volume of output */ void SoundControl::volumeDown () { volume >>= 1; Mix_VolumeMusic(volume); } /** \brief Rewinds music to the beginning */ void SoundControl::trackRewind () { Mix_RewindMusic(); } /** \brief Rewinds the music 5 seconds */ void SoundControl::forwardMusic () { Mix_SetMusicPosition(+5); } /** \brief Forwards the music 5 seconds */ void SoundControl::rewindMusic () { Mix_SetMusicPosition(-5); } /** \brief Pauses music output */ void SoundControl::pauseMusic () { Mix_PauseMusic(); } /** \brief this function pauses music output */ void SoundControl::resumeMusic () { Mix_ResumeMusic(); } /** \brief Selects the track of all orxonox tracks */ void SoundControl::trackSelect() { switch (track_number) { case 1: music = Mix_LoadMUS("luke_grey_orxonox1.ogg"); if(Mix_PlayMusic(music, 1) == -1){ printf("Mix_PlayMusic: %s\n",Mix_GetError()); } Mix_HookMusicFinished(musicDone); break; case 2: music = Mix_LoadMUS("luke_grey_orxonox2.ogg"); if(Mix_PlayMusic(music, 1) == -1){ printf("Mix_PlayMusic: %s\n",Mix_GetError()); } Mix_HookMusicFinished(musicDone); break; case 3: music = Mix_LoadMUS("luke_grey_orxonox3.ogg"); if(Mix_PlayMusic(music, 1) == -1){ printf("Mix_PlayMusic: %s\n",Mix_GetError()); } Mix_HookMusicFinished(musicDone); break; case 4: music = Mix_LoadMUS("luke_grey_and_aquarius_orxonox.ogg"); if(Mix_PlayMusic(music, 1) == -1){ printf("Mix_PlayMusic: %s\n",Mix_GetError()); } Mix_HookMusicFinished(musicDone); break; case 5: music = Mix_LoadMUS("nomenes_orxonox.ogg"); if(Mix_PlayMusic(music, 1) == -1){ printf("Mix_PlayMusic: %s\n",Mix_GetError()); } Mix_HookMusicFinished(musicDone); break; case 6: music = Mix_LoadMUS("nomenes_funkadudu.ogg"); if(Mix_PlayMusic(music, 1) == -1){ printf("Mix_PlayMusic: %s\n",Mix_GetError()); } Mix_HookMusicFinished(musicDone); break; } } /** \brief Hooked by playOgg at end of .ogg playback */ void SoundControl::musicDone() { Mix_HaltMusic(); Mix_FreeMusic(music); music = NULL; }