/* 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; int sfx_channel1 = -1; int sfx_channel2 = -1; int finished = 0; SoundControl* SoundControl::sound = SoundControl::getInstance(); SoundControl* SoundControl::instance = 0; int volume = SDL_MIX_MAXVOLUME; int track_number = 1; Mix_Music* music = NULL; int audio_rate = 44100, audio_channels = MIX_DEFAULT_CHANNELS, audio_buffers = 16384, bits = 0; Uint16 audio_format = MIX_DEFAULT_FORMAT; SDL_Event event; /** \brief standard constructor This constructor builds a SoundControl Object and initialises it . All sound output is handled by this singleton object. */ SoundControl::SoundControl() { 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 SoundControl singleton */ SoundControl* SoundControl::getInstance() { if (instance == 0) { instance = new SoundControl; } return instance; } void SoundControl::deleteInstance() { } /** \brief Is called by SoundControl object to initiate all values and to output some text */ void SoundControl::initialise() { 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 */ void SoundControl::setNumberOfChannels(int number_of_channels) { Mix_AllocateChannels(number_of_channels); } /** \brief Static function to play a .xm file \param filename: self-explanatory */ void 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 Static function to play a .wav file \param filename: self-explanatory */ void 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 Static function to play an .ogg file \param filename: self-explanatory */ void 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 Pauses music output */ void SoundControl::resumeMusic() { Mix_ResumeMusic(); } /** \brief Fades in music */ void fadeInMusic(int time) { } /** \brief Fades out music */ void SoundControl::fadeOutMusic(int time) { } /** \brief Hooked by playOgg at end of .ogg playback */ void SoundControl::musicDone() { Mix_HaltMusic(); Mix_FreeMusic(music); music = NULL; } /** \brief Handles input events */ void SoundControl::handleKey(SDL_KeyboardEvent key) { switch(key.keysym.sym) { case SDLK_a: if(key.type == SDL_KEYDOWN) { if(sfx_channel1 < 0) { sfx_channel1 = 1; sound->playWav("sound1.wav"); } } else { Mix_HaltChannel(sfx_channel1); sfx_channel1 = -1; } break; case SDLK_s: if(key.type == SDL_KEYDOWN) { if(sfx_channel2 < 0) { sfx_channel2 = 1; sound->playWav("sound2.wav"); } } else { Mix_HaltChannel(sfx_channel2); sfx_channel2 = -1; } break; case SDLK_m: if(key.state == SDL_PRESSED) { sound->playOgg("music.ogg"); } break; case SDLK_q: finished = 1; break; default: break; } } int SoundControl::main(int argc, char* argv[]) { SDL_Surface* screen; SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO); screen = SDL_SetVideoMode(320, 240, 0, 0); while(!finished) { while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: finished = 1; break; case SDL_KEYDOWN: case SDL_KEYUP: SoundControl::handleKey(event.key); break; default: break; } } SDL_Delay(50); } deleteInstance(); SDL_Quit(); return 0; }