00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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];
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
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
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
00106
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 }