Statistics
| Branch: | Tag: | Revision:

hlrc / server / src / AudioPlayerLibAO.cpp @ 2a6db5bb

History | View | Annotate | Download (5.395 KB)

1 0c286af0 Simon Schulz
/*
2 f150aab5 Robert Haschke
 * This file is part of hlrc_server
3
 *
4
 * Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
5
 * http://opensource.cit-ec.de/projects/hlrc_server
6
 *
7
 * This file may be licensed under the terms of the
8
 * GNU General Public License Version 3 (the ``GPL''),
9
 * or (at your option) any later version.
10
 *
11
 * Software distributed under the License is distributed
12
 * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
13
 * express or implied. See the GPL for the specific language
14
 * governing rights and limitations.
15
 *
16
 * You should have received a copy of the GPL along with this
17
 * program. If not, go to http://www.gnu.org/licenses/gpl.html
18
 * or write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
 *
21
 * The development of this software was supported by the
22
 * Excellence Cluster EXC 277 Cognitive Interaction Technology.
23
 * The Excellence Cluster EXC 277 is a grant of the Deutsche
24
 * Forschungsgemeinschaft (DFG) in the context of the German
25
 * Excellence Initiative.
26
 *
27
 */
28 0c286af0 Simon Schulz
29
#include "AudioPlayerLibAO.h"
30 e8a50634 Robert Haschke
#include <thread>
31
#include <chrono>
32 0c286af0 Simon Schulz
33
using namespace std;
34
35 f150aab5 Robert Haschke
// new audio player with gievn device type (default is pulse)
36
AudioPlayerLibAO::AudioPlayerLibAO(string driver) : AudioPlayer(driver) {
37
        printf("> using libao for playback\n");
38 0c286af0 Simon Schulz
39 f150aab5 Robert Haschke
        // initialize
40
        ao_initialize();
41 0c286af0 Simon Schulz
42 f150aab5 Robert Haschke
        // configure driver
43
        if (audio_driver.empty()) {
44
                // use default:
45
                driver = ao_default_driver_id();
46
        }
47
        else {
48
                driver = ao_driver_id(audio_driver.c_str());
49
        }
50 0c286af0 Simon Schulz
51 f150aab5 Robert Haschke
        // start audio playback thread:
52
        playback_thread_ptr = new boost::thread(boost::bind(&AudioPlayerLibAO::playback_thread, this));
53 0c286af0 Simon Schulz
}
54
55 f150aab5 Robert Haschke
// this will return once we start playing
56 482adb6d Robert Haschke
void AudioPlayerLibAO::play(std::shared_ptr<AudioData> audio) {
57 f150aab5 Robert Haschke
        audio_data = audio;
58 0c286af0 Simon Schulz
59 f150aab5 Robert Haschke
        printf("> AudioPlayerLibAO: play() %d samples requested\n", (int)audio_data->samples.size());
60 0c286af0 Simon Schulz
61 f150aab5 Robert Haschke
        // skip empty audio data
62
        if (audio_data->samples.size() == 0) {
63
                printf("> warning: empty audio data - skipped.\n");
64
                return;
65
        }
66 0c286af0 Simon Schulz
67 f150aab5 Robert Haschke
        // check if we can play this file:
68
        while (playback_state != IDLE) {
69
                printf("> player not ready yet, waiting for 10ms\n");
70 e8a50634 Robert Haschke
                std::this_thread::sleep_for(std::chrono::milliseconds(10));
71 f150aab5 Robert Haschke
        }
72 0c286af0 Simon Schulz
73 f150aab5 Robert Haschke
        audio_format = extract_ao_format(audio_data);
74 0c286af0 Simon Schulz
75 f150aab5 Robert Haschke
        playback_requested = true;
76 0c286af0 Simon Schulz
77 f150aab5 Robert Haschke
        // wait for playback to start:
78
        printf("> waiting for playback start...\n");
79
        while (playback_requested) {
80 e8a50634 Robert Haschke
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
81 f150aab5 Robert Haschke
        }
82
        printf("> playback running.\n");
83 0c286af0 Simon Schulz
}
84
85 482adb6d Robert Haschke
ao_sample_format AudioPlayerLibAO::extract_ao_format(std::shared_ptr<AudioData> audio) {
86 f150aab5 Robert Haschke
        ao_sample_format ao_format;
87
88
        // get bits per sample
89
        ao_format.bits = audio->sample_bit;
90
        // bitrate
91
        ao_format.rate = audio->sample_rate;
92
        // endianess
93
        ao_format.byte_format = audio->sample_big_endian ? AO_FMT_BIG : AO_FMT_LITTLE;
94
        // number of channels
95
        ao_format.channels = audio->sample_channels;
96
97
        // format matrix:
98
        if (ao_format.channels == 1) {
99
                ao_format.matrix = (char*)"L";
100
        }
101
        else if (ao_format.channels == 2) {
102
                ao_format.matrix = (char*)"L,R";
103
        }
104
        else {
105
                printf("> invalid AudioData channel count given. ignoring request\n");
106
                throw runtime_error("AudioPlayerLibAO::extract_ao_format() unsupported number of audio channels given in AudioData");
107
        }
108
109
        printf("> AudioPlayerLibAO: format=%d rate=%d endianess=%d channels=%d\n", ao_format.bits, ao_format.rate,
110
               ao_format.byte_format, ao_format.channels);
111
112
        return ao_format;
113 0c286af0 Simon Schulz
}
114
115 f150aab5 Robert Haschke
void AudioPlayerLibAO::playback_thread() {
116
        printf("> playback thread started\n");
117
        playback_state = IDLE;
118
119
        while (playback_state != EXITING) {
120
                switch (playback_state) {
121
                        default:
122
                        case (INITIALIZING):
123
                                // waiting to be ready
124
                                break;
125
126
                        case (IDLE):
127
                                // nothing to do, wait here until we are triggered to play!
128
                                if (playback_requested) {
129
                                        printf("> AudioPlayer: loading\n");
130
                                        playback_state = LOADING;
131
                                }
132
                                break;
133
134
                        case (LOADING):
135
                                // check if we can play that format:
136
                                device = ao_open_live(driver, &audio_format, NULL /* no options */);
137
138
                                if (device == NULL) {
139
                                        printf(
140
                                           "> AudioPlayer: WARNING: can not open requested audio device. trying to fall back to default driver\n");
141
                                        driver = ao_default_driver_id();
142
                                        device = ao_open_live(driver, &audio_format, NULL /* no options */);
143
                                }
144
145
                                if (device == NULL) {
146
                                        // failed to init device for format:
147
                                        printf("> AudioPlayer: WARNING: can not open audio device, not playing audio file!\n");
148
                                        playback_active = false;
149
                                        playback_requested = false;
150
                                        playback_state = IDLE;
151
                                        break;
152
                                }
153
                                else {
154
                                        // ok we can now play the data
155
                                        printf("> AudioPlayer: playback started\n");
156
                                        // mark request as beeing processed
157
                                        playback_requested = false;
158
                                        // enter actual playing state
159
                                        playback_state = PLAYING;
160
                                        playback_active = true;
161
162
                                        ao_play(device, audio_data->samples.data(), audio_data->samples.size());
163
                                        printf("> AudioPlayer: finished playback\n");
164
                                }
165
                                break;
166
167
                        case (PLAYING):
168
                                // when we reach this case, the ao_play() call finished
169
                                //-> we can close this now:
170
                                ao_close(device);
171
                                playback_state = IDLE;
172
                                playback_active = false;
173
                                printf("> AudioPlayer: device closed\n");
174
                                break;
175
176
                        case (ERROR):
177
                                printf("> AudioPlayer ERROR! exiting\n");
178
                                exit(EXIT_FAILURE);
179
                                break;
180
                }
181
182
                // 1ms delay to safe cpu time
183 e8a50634 Robert Haschke
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
184 f150aab5 Robert Haschke
        }
185
186
        // shutdown audio!
187
        ao_shutdown();
188
189
        // done
190
        playback_state = CLOSED;
191 0c286af0 Simon Schulz
}
192
193 f150aab5 Robert Haschke
AudioPlayerLibAO::~AudioPlayerLibAO() {
194 0c286af0 Simon Schulz
}