00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "pent_include.h"
00019 #include "AudioMixer.h"
00020 #include "SettingManager.h"
00021 #include "Kernel.h"
00022
00023 #include "AudioProcess.h"
00024 #include "MusicProcess.h"
00025 #include "AudioChannel.h"
00026
00027 #include "MidiDriver.h"
00028
00029 #include <SDL.h>
00030
00031 namespace Pentagram {
00032
00033 AudioMixer *AudioMixer::the_audio_mixer = 0;
00034
00035 AudioMixer::AudioMixer(int sample_rate_, bool stereo_, int num_channels_) :
00036 audio_ok(false),
00037 sample_rate(sample_rate_), stereo(stereo_),
00038 midi_driver(0), midi_volume(255),
00039 num_channels(num_channels_), channels(0)
00040 {
00041 the_audio_mixer = this;
00042
00043 con.Print(MM_INFO, "Creating AudioMixer...\n");
00044
00045 SDL_AudioSpec desired, obtained;
00046
00047 desired.format = AUDIO_S16SYS;
00048 desired.freq = sample_rate_;
00049 desired.channels = stereo_?2:1;
00050 desired.samples = 1024;
00051 desired.callback = sdlAudioCallback;
00052 desired.userdata = reinterpret_cast<void*>(this);
00053
00054 #ifdef UNDER_CE
00055 desired.freq = 11025;
00056 desired.channels = 1;
00057 #endif
00058
00059
00060 SDL_InitSubSystem(SDL_INIT_AUDIO);
00061 int ret = SDL_OpenAudio(&desired, &obtained);
00062 audio_ok = (ret == 0);
00063
00064 if (audio_ok) {
00065 pout << "Audio opened using format: " << obtained.freq << " Hz " << (int) obtained.channels << " Channels" << std::endl;
00066
00067 Lock();
00068
00069 sample_rate = obtained.freq;
00070 stereo = obtained.channels == 2;
00071
00072 channels = new AudioChannel*[num_channels];
00073 for (int i=0;i<num_channels;i++)
00074 channels[i] = new AudioChannel(sample_rate,stereo);
00075
00076
00077 Unlock();
00078
00079
00080 SDL_PauseAudio(0);
00081 }
00082 }
00083
00084 void AudioMixer::createProcesses()
00085 {
00086 Kernel *kernel = Kernel::get_instance();
00087
00088
00089 kernel->addProcess(new AudioProcess());
00090
00091
00092 kernel->addProcess(new MusicProcess(midi_driver));
00093 }
00094
00095 AudioMixer::~AudioMixer(void)
00096 {
00097 con.Print(MM_INFO, "Destroying AudioMixer...\n");
00098
00099 closeMidiOutput();
00100
00101 SDL_CloseAudio();
00102
00103 the_audio_mixer = 0;
00104
00105 if (channels) for (int i=0;i<num_channels;i++) delete channels[i];
00106 delete [] channels;
00107 }
00108
00109 void AudioMixer::Lock()
00110 {
00111 SDL_LockAudio();
00112 }
00113
00114 void AudioMixer::Unlock()
00115 {
00116 SDL_UnlockAudio();
00117 }
00118
00119 void AudioMixer::reset()
00120 {
00121 if (!audio_ok) return;
00122
00123 con.Print(MM_INFO, "Resetting AudioMixer...\n");
00124
00125 Lock();
00126
00127 if (midi_driver) {
00128 for (int i = 0; i < midi_driver->maxSequences(); i++) {
00129 midi_driver->finishSequence(i);
00130 }
00131 }
00132
00133 if (channels) for (int i=0;i<num_channels;i++) channels[i]->stop();
00134
00135 Unlock();
00136 }
00137
00138 int AudioMixer::playSample(AudioSample *sample, int loop, int priority, bool paused, uint32 pitch_shift_, int lvol, int rvol)
00139 {
00140 if (!audio_ok || !channels) return -1;
00141
00142 int lowest = -1;
00143 int lowprior = 65536;
00144
00145
00146 Lock();
00147
00148 int i;
00149 for (i=0;i<num_channels;i++)
00150 {
00151 if (!channels[i]->isPlaying()) {
00152 lowest = i;
00153 break;
00154 }
00155 else if (channels[i]->getPriority() < priority) {
00156 lowprior = channels[i]->getPriority();
00157 lowest = i;
00158 }
00159 }
00160
00161 if (i != num_channels || lowprior < priority)
00162 channels[lowest]->playSample(sample,loop,priority,paused,pitch_shift_,lvol,rvol);
00163 else
00164 lowest = -1;
00165
00166
00167 Unlock();
00168
00169 return lowest;
00170 }
00171
00172 bool AudioMixer::isPlaying(int chan)
00173 {
00174 if (chan > num_channels || chan < 0 || !channels || !audio_ok) return 0;
00175
00176 Lock();
00177
00178 bool playing = channels[chan]->isPlaying();
00179
00180 Unlock();
00181
00182 return playing;
00183 }
00184
00185 void AudioMixer::stopSample(int chan)
00186 {
00187 if (chan > num_channels || chan < 0 || !channels || !audio_ok) return;
00188
00189 Lock();
00190
00191 channels[chan]->stop();
00192
00193 Unlock();
00194 }
00195
00196 void AudioMixer::setPaused(int chan, bool paused)
00197 {
00198 if (chan > num_channels || chan < 0 || !channels || !audio_ok) return;
00199
00200 Lock();
00201
00202 channels[chan]->setPaused(paused);
00203
00204 Unlock();
00205 }
00206
00207 bool AudioMixer::isPaused(int chan)
00208 {
00209 if (chan > num_channels || chan < 0 || !channels || !audio_ok) return false;
00210
00211 Lock();
00212
00213 bool ret = channels[chan]->isPaused();
00214
00215 Unlock();
00216
00217 return ret;
00218 }
00219
00220 void AudioMixer::setVolume(int chan, int lvol, int rvol)
00221 {
00222 if (chan > num_channels || chan < 0 || !channels || !audio_ok) return;
00223
00224 Lock();
00225
00226 channels[chan]->setVolume(lvol,rvol);
00227
00228 Unlock();
00229 }
00230
00231 void AudioMixer::getVolume(int chan, int &lvol, int &rvol)
00232 {
00233 if (chan > num_channels || chan < 0 || !channels || !audio_ok) return;
00234
00235 Lock();
00236
00237 channels[chan]->getVolume(lvol,rvol);
00238
00239 Unlock();
00240 }
00241
00242
00243 void AudioMixer::sdlAudioCallback(void *userdata, Uint8 *stream, int len)
00244 {
00245 AudioMixer *mixer = reinterpret_cast<AudioMixer *>(userdata);
00246
00247 mixer->MixAudio(reinterpret_cast<sint16*>(stream), len);
00248 }
00249
00250 void AudioMixer::MixAudio(sint16 *stream, uint32 bytes)
00251 {
00252 if (!audio_ok) return;
00253
00254 if (midi_driver && midi_driver->isSampleProducer())
00255 midi_driver->produceSamples(stream, bytes);
00256
00257 if (channels) for (int i=0;i<num_channels;i++)
00258 if (channels[i]->isPlaying()) channels[i]->resampleAndMix(stream,bytes);
00259 }
00260
00261 void AudioMixer::openMidiOutput()
00262 {
00263 if (midi_driver) return;
00264 if (!audio_ok) return;
00265
00266 MidiDriver * new_driver = 0;
00267 con.Print(MM_INFO, "Initializing MidiDriver...\n");
00268
00269 SettingManager *settingman = SettingManager::get_instance();
00270
00271
00272 std::string desired_driver;
00273 settingman->setDefault("midi_driver", "default");
00274 settingman->get("midi_driver", desired_driver);
00275
00276
00277 if (audio_ok) new_driver = MidiDriver::createInstance(desired_driver,sample_rate,stereo);
00278
00279
00280 if (new_driver)
00281 {
00282 Lock();
00283 midi_driver = new_driver;
00284 Unlock();
00285 midi_driver->setGlobalVolume(midi_volume);
00286 }
00287 }
00288
00289 void AudioMixer::closeMidiOutput()
00290 {
00291 if (!midi_driver) return;
00292 con.Print(MM_INFO, "Destroying MidiDriver...\n");
00293
00294 midi_driver->destroyMidiDriver();
00295
00296 Lock();
00297 delete midi_driver;
00298 midi_driver = 0;
00299 Unlock();
00300 }
00301
00302 };