/* * $Id: Sound.cpp 1697 2006-07-21 15:01:05Z karijes $ * * Edewm, window manager * Part of Equinox Desktop Environment (EDE). * Copyright (c) 2000-2006 EDE Authors. * * This program is licenced under terms of the * GNU General Public Licence version 2 or newer. * See COPYING for details. */ #include "Sound.h" #include "debug.h" #ifdef SOUND #include #include #endif #include #include #include // free #include // strdup SoundSystem::SoundSystem() { #ifdef SOUND device = NULL; inited = false; down = false; #endif } SoundSystem::~SoundSystem() { #ifdef SOUND if(!down) shutdown(); // just in case #endif } void SoundSystem::init(void) { #ifdef SOUND EPRINTF("Loading sound system\n"); ao_initialize(); default_driver = ao_default_driver_id(); for(int i = 0; i < KNOWN_SOUNDS; i++) { event_sound[i].allocated = false; event_sound[i].loaded = false; event_sound[i].file_to_play = NULL; } inited = true; #endif } void SoundSystem::shutdown(void) { #ifdef SOUND EPRINTF("Shutting down sound system\n"); ao_shutdown(); for(int i = 0; i < KNOWN_SOUNDS; i++) { if(event_sound[i].allocated) free(event_sound[i].file_to_play); } down = true; #endif } void SoundSystem::add(short event, const char* file) { #ifdef SOUND assert(event < KNOWN_SOUNDS); if(event_sound[event].allocated) free(event_sound[event].file_to_play); event_sound[event].file_to_play = strdup(file); event_sound[event].allocated = true; event_sound[event].loaded = true; #endif } int SoundSystem::play(short event) { #ifdef SOUND assert(event < KNOWN_SOUNDS); if(event_sound[event].loaded) play(event_sound[event].file_to_play); else ELOG("Skipping this sound, no file for it"); #endif return 1; } int SoundSystem::play(const char* fname) { #ifdef SOUND assert(inited != false); assert(fname != NULL); FILE* f = fopen(fname, "rb"); if(f == NULL) { ELOG("Can't open %s\n", fname); return 0; } OggVorbis_File vf; vorbis_info* vi; if(ov_open(f, &vf, NULL, 0) < 0) { ELOG("%s does not appear to be ogg file\n"); fclose(f); return 0; } // read and print comments char** comm = ov_comment(&vf, -1)->user_comments; vi = ov_info(&vf, -1); while(*comm) { ELOG("%s", *comm); comm++; } assert(vi != NULL); format.bits = 4 * 8; // TODO: should be word_size * 8 format.channels = vi->channels; format.rate = vi->rate; format.byte_format = AO_FMT_NATIVE; // now open device device = ao_open_live(default_driver, &format, NULL); if(device == NULL) { ELOG("Can't open device"); ov_clear(&vf); return 0; } int current_section; while(1) { long ret = ov_read(&vf, pcm_out, sizeof(pcm_out), 0, 2, 1, ¤t_section); if(ret == 0) break; else if(ret < 0) ELOG("Error in the stream, continuing..."); else ao_play(device, pcm_out, ret); } ao_close(device); device = NULL; // NOTE: fclose(f) is not needed, since ov_clear() will close file ov_clear(&vf); #endif // SOUND return 1; }