Statistics
| Branch: | Tag: | Revision:

hlrc / server / src / AudioPlayerRSB.cpp @ 340bb7ae

History | View | Annotate | Download (6.243 KB)

1
/*
2
 * 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

    
29
#include "AudioPlayerRSB.h"
30

    
31
#ifdef RSB_SUPPORT
32
#include <rsb/converter/Repository.h>
33
#include <rsb/converter/ProtocolBufferConverter.h>
34
#include <rsb/Factory.h>
35
#include <boost/make_shared.hpp>
36
using namespace std;
37
using namespace rsb;
38
using namespace boost;
39

    
40
// new audio player with gievn device type (default is pulse)
41
AudioPlayerRSB::AudioPlayerRSB(string driver) : AudioPlayer(driver) {
42
        assert(driver.length() > 3);
43

    
44
        string scope = driver.substr(3);
45

    
46
        printf("> using rsb for playback, scope = '%s'\n", scope.c_str());
47

    
48
        printf("> registering converters\n");
49
        rsb::converter::Converter<string>::Ptr soundChunkConverter(
50
           new rsb::converter::ProtocolBufferConverter<rst::audition::SoundChunk>());
51
        rsb::converter::converterRepository<string>()->registerConverter(soundChunkConverter);
52

    
53
        // first get a factory instance that is used to create RSB domain objects
54
        Factory& factory = getFactory();
55

    
56
        // create informer
57
        informer = factory.createInformer<rst::audition::SoundChunk>(scope);
58

    
59
        // start audio playback thread:
60
        playback_thread_ptr = new boost::thread(boost::bind(&AudioPlayerRSB::playback_thread, this));
61
}
62

    
63
// this will return once we start playing
64
void AudioPlayerRSB::play(std::shared_ptr<AudioData> _audio_data) {
65
        audio_data = _audio_data;
66

    
67
        printf("> AudioPlayerRSB: play() %d samples requested\n", (int)audio_data->samples.size());
68

    
69
        // check if we can play this file:
70
        while (playback_state != IDLE) {
71
                printf("> player not ready yet, waiting for 10ms\n");
72
                std::this_thread::sleep_for(std::chrono::milliseconds(10));
73
        }
74

    
75
        // ok, we can play the audio. copy/setup data:
76
        // audio_data_ptr = std::shared_ptr<rst::audition::SoundChunk>(boost::make_shared<rst::audition::SoundChunk>(*audio_chunk));
77
        playback_requested = true;
78
}
79

    
80
void AudioPlayerRSB::playback_thread() {
81
        printf("> playback thread started\n");
82
        playback_state = IDLE;
83

    
84
        while (playback_state != EXITING) {
85
                switch (playback_state) {
86
                        default:
87
                        case (INITIALIZING):
88
                                // waiting to be ready
89
                                break;
90

    
91
                        case (IDLE):
92
                                // nothing to do, wait here until we are triggered to play!
93
                                if (playback_requested) {
94
                                        printf("> AudioPlayerRSB: loading\n");
95
                                        playback_state = LOADING;
96
                                }
97
                                break;
98

    
99
                        case (LOADING):
100
                        {
101
                                // send the data
102
                                try {
103
                                        publish_audio_data();
104
                                }
105
                                catch (std::exception e) {
106
                                        printf(
107
                                           "> AudioPlayerRSB: WARNING: failed to call informer. audio playback probably failed\n> error message = %s",
108
                                           e.what());
109
                                        playback_active = false;
110
                                        playback_requested = false;
111
                                        playback_state = IDLE;
112
                                        break;
113
                                }
114

    
115
                                // add some delay to meet the delay until playback starts (FIXME: this should be determined!)
116
                                // std::this_thread::sleep_for(std::chrono::milliseconds(100));
117

    
118
                                // ok we can now play the data
119
                                printf("> AudioPlayer: playback started\n");
120
                                // mark request as beeing processed
121
                                playback_requested = false;
122
                                // enter actual playing state
123
                                playback_state = PLAYING;
124
                                playback_active = true;
125

    
126
                                // now we have to wait until the audio playback finished....
127
                                long sample_count = audio_data_ptr->sample_count();
128
                                int sampling_rate = audio_data_ptr->rate();
129
                                double playback_time = (double)sample_count / (double)sampling_rate;
130
                                printf("> AudioPlayerRSB estimated playbacktime to %5.3lf seconds. will wait now...", playback_time);
131
                                boost::this_thread::sleep(std::chrono::seconds(playback_time));
132
                                printf("> AudioPlayerRSB finished waiting...\n");
133
                                break;
134
                        }
135

    
136
                        case (PLAYING):
137
                                // when we reach this case, the playback finshed
138
                                playback_state = IDLE;
139
                                playback_active = false;
140
                                printf("> AudioPlayerRSB: finished playback");
141
                                break;
142

    
143
                        case (ERROR):
144
                                printf("> AudioPlayerRSB ERROR! exiting\n");
145
                                exit(EXIT_FAILURE);
146
                                break;
147
                }
148

    
149
                // 1ms delay to safe cpu time
150
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
151
        }
152

    
153
        // done
154
        playback_state = CLOSED;
155
}
156

    
157
void AudioPlayerRSB::publish_audio_data() {
158
        std::shared_ptr<rst::audition::SoundChunk> request(new rst::audition::SoundChunk());
159

    
160
        request->set_channels(audio_data->sample_channels);
161
        request->set_data(audio_data->samples.data());
162
        /*
163
            if (audio_data.sample_big_endian){
164
                request->set_endianness(rst::audition::SoundChunk_EndianNess_ENDIAN_BIG);
165
            }else{
166
                request->set_endianness(rst::audition::SoundChunk_EndianNess_ENDIAN_LITTLE);
167
            }
168

169
            request->set_rate(audio_data.sample_rate);
170
            request->set_sample_count(audio_data.samples.size() / audio_data.sample_channels / (audio_data.sample_bit/8));
171

172
            switch (audio_data.sample_bit){
173
                case(8):
174
                    request->set_sample_type(audio_data.sample_signed?(rst::audition::SoundChunk::SAMPLE_S8):(rst::audition::SoundChunk::SAMPLE_U8));
175
                    break;
176
                case(16):
177
                    request->set_sample_type(audio_data.sample_signed?(rst::audition::SoundChunk::SAMPLE_S16):(rst::audition::SoundChunk::SAMPLE_U16));
178
                    break;
179
                case(24):
180
                    request->set_sample_type(audio_data.sample_signed?(rst::audition::SoundChunk::SAMPLE_S24):(rst::audition::SoundChunk::SAMPLE_U24));
181
                    break;
182
                default:
183
                    throw runtime_error("AudioPlayerRSB::publish_audio_data() unsupported sample type bit width");
184
            }
185
        */
186
        informer->publish(request);
187
}
188

    
189
AudioPlayerRSB::~AudioPlayerRSB() {
190
}
191

    
192
#endif