Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

mixer.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2002 Xavier Trochu
00003 
00004 This software is provided 'as-is', without any express or implied warranty. In no event
00005 will the authors be held liable for any damages arising from the use of this software.
00006 
00007 Permission is granted to anyone to use this software for any purpose, including commercial
00008 applications, and to alter it and redistribute it freely, subject to the following
00009 restrictions:
00010 
00011 1. The origin of this software must not be misrepresented; you must not claim that you
00012    wrote the original software. If you use this software in a product, an acknowledgment
00013    in the product documentation would be appreciated but is not required.
00014 
00015 2. Altered source versions must be plainly marked as such, and must not be misrepresented 
00016    as being the original software.
00017 
00018 3. This notice may not be removed or altered from any source distribution.
00019 */
00020 #include <sstream>
00021 #include <stdexcept>
00022 #include <map>
00023 #include "mixer.h"
00024 #include "channel.h"
00025 #include "renderer.h"
00026 
00027 #ifdef DEBUG_MIXER
00028 #include <iostream>
00029 #endif
00030 
00031 using namespace std;
00032 
00033 mixer::mixer() throw() : _frequency(0), _sound(0), _out(0) {
00034 }
00035 
00036 bool mixer::init(sound_renderer * sr, int freq, int fps) throw() {
00037     _frequency = freq;
00038     _sound = new short[_frequency*2]; // This is too much, but who cares.
00039     if(_sound == 0) return false;
00040     _out = sr;
00041     _out->init(_frequency, true);
00042     return true;
00043 }
00044 
00045 bool mixer::stop() throw(exception) {
00046     while(handle_frame());
00047     _out->stop();
00048     return true;
00049 }
00050 
00051 mixer::~mixer() throw() {
00052     while(_channels.size()) {
00053         map<int, channel *>::iterator i = _channels.begin();
00054         delete i->second;
00055         _channels.erase(i);
00056     }
00057     if(_sound) delete []_sound;
00058 }
00059 
00060 channel * mixer::find_channel(int track) throw() {
00061     assert(_frequency != 0);
00062     map<int, channel *>::iterator i = _channels.find(track);
00063     return i == _channels.end() ? 0 : i->second;
00064 }
00065 
00066 bool mixer::add_channel(int track, channel * c) throw(exception) {
00067     assert(_frequency != 0);
00068 #ifdef DEBUG_MIXER
00069     map<int, channel *>::iterator i = _channels.find(track);
00070     if(i != _channels.end()) throw runtime_error("channel already exist !");
00071 #endif
00072     _channels.insert(make_pair(track, c));
00073     return true;
00074 }
00075 
00076 bool mixer::handle_frame() throw(std::exception) {
00077     int dumped_size = 2205;
00078     while(dumped_size > 0) {
00079         //~ cout << "mixer::handle_frame() dumped_size == " << dumped_size << endl;
00080         if(_channels.size() == 0) {
00081 #ifdef DEBUG_MIXER
00082             cout << "mixer::handle_frame() : no more track available and still " << dumped_size << " bytes to fill" << endl;
00083 #endif
00084             memset(_sound, 0, 2205 * 4);    
00085             _out->write(reinterpret_cast<unsigned short *>(_sound), 2205 * 4);
00086             return false;
00087         }
00088         for(map<int, channel *>::iterator i = _channels.begin(); i != _channels.end(); i++) {
00089             if(i->second->is_terminated()) {
00090                 delete i->second;
00091                 _channels.erase(i);
00092             }
00093         }
00094         int minsize = dumped_size;
00095         for(map<int, channel *>::iterator i = _channels.begin(); i != _channels.end(); i++) {
00096             int s = i->second->available_sound_data();
00097             if(s < minsize) minsize = s;
00098         }
00099         //~ minsize &= ~1;
00100         if(minsize == 0) {
00101 #ifdef DEBUG_MIXER
00102             cout << "mixer::handle_frame() : no more data in track available and still " << dumped_size << " samples to fill" << endl;
00103 #endif
00104             return true;
00105         //~ } else {
00106             //~ cout << "mixer::handle_frame() minsize == " << minsize << endl;
00107         }
00108         memset(_sound, 0, minsize * 4); 
00109         for(map<int, channel *>::iterator i = _channels.begin(); i != _channels.end(); i++) {
00110             i->second->read_sound_data(_sound, minsize);
00111         }
00112         dumped_size -= minsize;
00113 #ifdef DEBUG_MIXER
00114         cout << "mixer::handle_frame() dumped_size == " << dumped_size << ", minsize == " << minsize << endl;
00115 #endif
00116         _out->write(reinterpret_cast<unsigned short *>(_sound), minsize * 4);
00117     }
00118 #ifdef DEBUG_MIXER
00119     cout << "mixer::handle_frame() : buffer completely field for this frame" << endl;
00120 #endif
00121     return true;
00122 }

Generated on Fri Aug 9 22:54:29 2002 for san_player by doxygen1.2.16