3
* Ekiga -- A VoIP and Video-Conferencing application
4
* Copyright (C) 2000-2009 Damien Sandras <dsandras@seconix.com>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or (at
9
* your option) any later version. This program is distributed in the hope
10
* that it will be useful, but WITHOUT ANY WARRANTY; without even the
11
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
* See the GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License along
15
* with this program; if not, write to the Free Software Foundation, Inc.,
16
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18
* Ekiga is licensed under the GPL license and as a special exception, you
19
* have permission to link or otherwise combine this program with the
20
* programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
21
* applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
22
* programs, as long as you do follow the requirements of the GNU GPL for all
23
* the rest of the software thus combined.
28
* audiooutput-scheduler.h - description
29
* ------------------------------------------
30
* begin : written in 2008 by Matthias Schneider
31
* copyright : (c) 2008 by Matthias Schneider
32
* description : Declaration of a scheduler for sound events that is run in
37
#include "audiooutput-scheduler.h"
38
#include "audiooutput-core.h"
41
#include "platform/winpaths.h"
44
using namespace Ekiga;
46
AudioEventScheduler::AudioEventScheduler (AudioOutputCore& _audio_output_core)
47
: PThread (1000, NoAutoDeleteThread, HighestPriority, "AudioEventScheduler"),
48
audio_output_core (_audio_output_core)
51
// Since windows does not like to restart a thread that
52
// was never started, we do so here
54
thread_created.Wait ();
57
AudioEventScheduler::~AudioEventScheduler ()
62
/* Wait for the Main () method to be terminated */
63
PWaitAndSignal m(thread_ended);
67
void AudioEventScheduler::Main ()
69
PWaitAndSignal m(thread_ended);
71
std::vector <AudioEvent> pending_event_list;
72
unsigned idle_time = 65535;
75
unsigned long buffer_len = 0;
76
unsigned channels, sample_rate, bps;
79
thread_created.Signal ();
83
if (idle_time == 65535)
86
run_thread.Wait (idle_time);
91
get_pending_event_list(pending_event_list);
92
PTRACE(4, "AEScheduler\tChecking pending list with " << pending_event_list.size() << " elements");
94
while (pending_event_list.size() > 0) {
95
event = *(pending_event_list.begin()); pending_event_list.erase(pending_event_list.begin());
96
load_wav(event.name, event.is_file_name, buffer, buffer_len, channels, sample_rate, bps, ps);
98
audio_output_core.play_buffer (ps, buffer, buffer_len, channels, sample_rate, bps);
102
Current()->Sleep (10);
104
idle_time = get_time_to_next_event();
108
void AudioEventScheduler::get_pending_event_list (std::vector<AudioEvent> & pending_event_list)
110
PWaitAndSignal m(event_list_mutex);
113
std::vector <AudioEvent> new_event_list;
114
unsigned long time = get_time_ms();
116
pending_event_list.clear();
118
while (event_list.size() > 0) {
120
event = *(event_list.begin()); event_list.erase(event_list.begin());
122
if (event.interval == 0) {
123
pending_event_list.push_back(event);
126
if (event.time <= time) {
127
pending_event_list.push_back(event);
129
if (event.repetitions > 0) {
130
event.time = time + event.interval;
131
new_event_list.push_back(event);
135
new_event_list.push_back(event);
140
event_list = new_event_list;
143
unsigned long AudioEventScheduler::get_time_ms()
146
g_get_current_time(&time_val);
147
return (time_val.tv_sec * 1000 + (unsigned long) (time_val.tv_usec / 1000) );
150
unsigned AudioEventScheduler::get_time_to_next_event()
152
PWaitAndSignal m(event_list_mutex);
153
unsigned long time = get_time_ms();
154
unsigned min_time = 65535;
156
for (std::vector<AudioEvent>::iterator iter = event_list.begin ();
157
iter !=event_list.end ();
160
if ( (iter->interval > 0) && ((iter->time - time) < min_time) )
161
min_time = iter->time - time;
166
void AudioEventScheduler::add_event_to_queue(const std::string & name, bool is_file_name, unsigned interval, unsigned repetitions)
168
PTRACE(4, "AEScheduler\tAdding Event " << name << " " << interval << "/" << repetitions << " to queue");
169
PWaitAndSignal m(event_list_mutex);
172
event.is_file_name = is_file_name;
173
event.interval = interval;
174
event.repetitions = repetitions;
175
event.time = get_time_ms();
176
event_list.push_back(event);
180
void AudioEventScheduler::remove_event_from_queue(const std::string & name)
182
PTRACE(4, "AEScheduler\tRemoving Event " << name << " from queue");
183
PWaitAndSignal m(event_list_mutex);
186
std::vector<AudioEvent>::iterator iter;
188
for (iter = event_list.begin ();
189
iter != event_list.end () ;
192
if ( (iter->name == name) ) {
199
event_list.erase(iter);
203
void AudioEventScheduler::load_wav(const std::string & event_name, bool is_file_name, char* & buffer, unsigned long & len, unsigned & channels, unsigned & sample_rate, unsigned & bps, AudioOutputPS & ps)
205
PWAVFile* wav = NULL;
206
std::string file_name;
211
// Shall we also try event name as file name?
213
file_name = event_name;
217
if (!get_file_name(event_name, file_name, ps)) // if this event is disabled
220
PTRACE(4, "AEScheduler\tTrying to load " << file_name << " for event " << event_name);
221
wav = new PWAVFile (file_name.c_str(), PFile::ReadOnly);
223
if (!wav->IsValid ()) {
224
/* it isn't a full path to a file : add our default path */
229
gchar* filename = g_build_filename (DATA_DIR, "sounds", PACKAGE_NAME, file_name.c_str(), NULL);
230
PTRACE(4, "AEScheduler\tTrying to load " << filename << " for event " << event_name);
232
wav = new PWAVFile (filename, PFile::ReadOnly);
236
if (wav->IsValid ()) {
237
len = wav->GetDataLength();
238
channels = wav->GetChannels ();
239
sample_rate = wav->GetSampleRate ();
240
bps = wav->GetSampleSize ();
242
buffer = (char*) malloc (len);
243
memset(buffer, 127, len);
244
wav->Read(buffer, len);
251
bool AudioEventScheduler::get_file_name(const std::string & event_name, std::string & file_name, AudioOutputPS & ps)
253
PWaitAndSignal m(event_file_list_mutex);
257
for (std::vector<EventFileName>::iterator iter = event_file_list.begin ();
258
iter != event_file_list.end ();
261
if (iter->event_name == event_name) {
262
file_name = iter->file_name;
264
return (iter->enabled);
271
void AudioEventScheduler::set_file_name(const std::string & event_name, const std::string & file_name, AudioOutputPS ps, bool enabled)
273
PWaitAndSignal m(event_file_list_mutex);
277
for (std::vector<EventFileName>::iterator iter = event_file_list.begin ();
278
iter != event_file_list.end ();
281
if (iter->event_name == event_name) {
282
iter->file_name = file_name;
283
iter->enabled = enabled;
291
EventFileName event_file_name;
292
event_file_name.event_name = event_name;
293
event_file_name.file_name = file_name;
294
event_file_name.enabled = enabled;
295
event_file_name.ps = secondary;
296
event_file_list.push_back(event_file_name);