Revision f150aab5 server/src/AudioPlayerRSB.cpp

View differences:

server/src/AudioPlayerRSB.cpp
1 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
*/
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 28

  
29 29
#include "AudioPlayerRSB.h"
30 30

  
......
37 37
using namespace rsb;
38 38
using namespace boost;
39 39

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

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

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

  
47
    printf("> using rsb for playback, scope = '%s'\n", scope.c_str());
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);
48 52

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

  
50
    printf("> registering converters\n");
51
    rsb::converter::Converter<string>::Ptr soundChunkConverter(new rsb::converter::ProtocolBufferConverter<rst::audition::SoundChunk>());
52
    rsb::converter::converterRepository<string>()->registerConverter(soundChunkConverter);
56
	// create informer
57
	informer = factory.createInformer<rst::audition::SoundChunk>(scope);
53 58

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

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

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

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

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

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

  
71
    //check if we can play this file:
72
    while(playback_state != IDLE){
73
        printf("> player not ready yet, waiting for 10ms\n");
74
        usleep(10*1000);
75
    }
69
	// check if we can play this file:
70
	while (playback_state != IDLE) {
71
		printf("> player not ready yet, waiting for 10ms\n");
72
		usleep(10 * 1000);
73
	}
76 74

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

  
82

  
83
void AudioPlayerRSB::playback_thread(){
84
    printf("> playback thread started\n");
85
    playback_state = IDLE;
86

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

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

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

  
114
                //add some delay to meet the delay until playback starts (FIXME: this should be determined!)
115
                //usleep(100*1000); //100ms
116

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

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

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

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

  
148
        //1ms delay to safe cpu time
149
        usleep(1000);
150
    }
151

  
152
    //done
153
    playback_state = CLOSED;
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
				// usleep(100*1000); //100ms
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(boost::posix_time::milliseconds(1000.0 * 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
		usleep(1000);
151
	}
152

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

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

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

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

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

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

  
191 192
#endif

Also available in: Unified diff