Revision 2e526a15

View differences:

server/include/Arbiter.h
48 48
    void set_default_emotion(EmotionState e);
49 49
    void set_current_emotion(EmotionState e);
50 50
    void set_mouth_config(MouthConfig m);
51
    void speak(Utterance u);
51
    void speak(boost::shared_ptr<Utterance> u);
52 52
    bool speak_active();
53 53

  
54 54
    void set_gaze_target(humotion::GazeState g);
......
73 73

  
74 74
    MouthConfig mouth_config;
75 75

  
76
    Utterance utterance;
76
    boost::shared_ptr<Utterance> utterance;
77 77

  
78 78
    humotion::GazeState requested_gaze_state;
79 79
    humotion::MouthState requested_mouth_state;
server/include/AudioPlayer.h
49 49
        CLOSED
50 50
    } PLAYBACKSTATE_T;
51 51

  
52
    virtual void play(AudioData audio) = 0;
52
    virtual void play(boost::shared_ptr<AudioData> audio) = 0;
53 53
    bool is_playing();
54 54

  
55 55
protected:
56
    AudioData audio_data;
56
    boost::shared_ptr<AudioData> audio_data;
57 57
    PLAYBACKSTATE_T playback_state;
58 58
    std::string audio_driver;
59 59
    bool playback_requested;
server/include/AudioPlayerLibAO.h
37 37
    ~AudioPlayerLibAO();
38 38

  
39 39
    void playback_thread();
40
    void play(AudioData audio);
40
    void play(boost::shared_ptr<AudioData> audio);
41 41
    bool is_playing();
42 42

  
43 43

  
44 44

  
45 45
private:
46
    ao_sample_format extract_ao_format(AudioData audio);
46
    ao_sample_format extract_ao_format(boost::shared_ptr<AudioData> audio);
47 47
    boost::thread *playback_thread_ptr;
48 48

  
49 49
    //std::vector<char> audio_data;
server/include/AudioPlayerRSB.h
42 42
    ~AudioPlayerRSB();
43 43

  
44 44
    void playback_thread();
45
    void play(AudioData audio);
45
    void play(boost::shared_ptr<AudioData> audio);
46 46
    bool is_playing();
47 47

  
48 48
private:
server/include/Middleware.h
41 41
    virtual void tick() = 0;
42 42

  
43 43
    void speak_callback(std::string text);
44
    void utterance_callback(Utterance u);
44
    void utterance_callback(boost::shared_ptr<Utterance> u);
45 45
    void gaze_callback(humotion::GazeState gaze);
46 46
    void mouth_callback(humotion::MouthState mouth);
47 47
    void default_emotion_callback(EmotionState emotion_state);
48 48
    void current_emotion_callback(EmotionState emotion_state);
49 49
    void animation_callback(boost::shared_ptr<Animation> ani);
50 50

  
51
    virtual Utterance tts_call(std::string text) = 0;
51
    virtual boost::shared_ptr<Utterance> tts_call(std::string text) = 0;
52 52

  
53 53
protected:
54 54
    Arbiter *arbiter;
server/include/MiddlewareROS.h
58 58
    void init(){};
59 59
    void tick(){};
60 60

  
61
    Utterance tts_call(std::string text){
62
        return Utterance();
61
    boost::shared_ptr<Utterance> tts_call(std::string text){
62
        return boost::shared_ptr<Utterance>(new Utterance());
63 63
    }
64 64

  
65 65
#else
......
68 68
    ~MiddlewareROS();
69 69
    void init();
70 70
    void tick();
71
    Utterance tts_call(std::string text);
71
    boost::shared_ptr<Utterance> tts_call(std::string text);
72 72

  
73 73
private:
74 74
    //boost::shared_ptr<ros::NodeHandle> node_handle;
server/include/MiddlewareRSB.h
46 46
    ~MiddlewareRSB(){}
47 47
    void init(){};
48 48
    void tick(){};
49
    Utterance tts_call(std::string text){
50
        return Utterance();
49
    boost::shared_ptr<Utterance> tts_call(std::string text){
50
        return boost::shared_ptr<Utterance>(new Utterance());
51 51
    }
52 52

  
53 53
#else
......
56 56
    ~MiddlewareRSB();
57 57
    void init();
58 58
    void tick();
59
    Utterance tts_call(std::string text);
59
    boost::shared_ptr<Utterance> tts_call(std::string text);
60 60

  
61 61
private:
62 62
    void init_callbacks();
server/include/ROS/UtteranceCallbackWrapperROS.h
51 51
        //everything is ok, will be cleared on failures
52 52
        feedback.result = 1;
53 53

  
54
        Utterance utterance;
54
        boost::shared_ptr<Utterance> utterance(new Utterance());
55 55

  
56 56
        //copy values:
57
        utterance.set_text(request->text);
58
        AudioData audio_data;
59
        if (!extract_audio(request->audio, &audio_data)){
57
        utterance->set_text(request->text);
58

  
59
        boost::shared_ptr<AudioData> audio_data(new AudioData());
60
        if (!extract_audio(request->audio, audio_data)){
60 61
            feedback.result = 0;
61 62
        }
62 63

  
63
        utterance.set_audio_data(audio_data);
64
        utterance.set_phoneme_vector(extract_phoneme_vector(request->phonemes));
64
        utterance->set_audio_data(audio_data);
65
        utterance->set_phoneme_vector(extract_phoneme_vector(request->phonemes));
65 66

  
66 67
        //send to application;
67 68
        mw->utterance_callback(utterance);
......
77 78

  
78 79

  
79 80
    //convert ros message audio data to our own implementation
80
    bool extract_audio(hlrc_server::soundchunk sound_chunk, AudioData *audio_data){
81
    bool extract_audio(hlrc_server::soundchunk sound_chunk, boost::shared_ptr<AudioData> audio_data){
81 82
        //extract data:
82 83
        unsigned int audio_len = sound_chunk.data.size();
83 84
        char *audio_data_char = (char *)sound_chunk.data.data();
server/include/RSB/UtteranceCallbackWrapper.h
39 39
            rst::audition::Utterance *rst_utterance = param.get();
40 40
            printf("> incoming utterance '%s' (%d phone symbols)\n", param->text().c_str(), (int)rst_utterance->phonemes().size());
41 41

  
42
            Utterance utterance = UtteranceRSB(*rst_utterance);
42
            boost::shared_ptr<Utterance> utterance(new UtteranceRSB(*rst_utterance));
43 43

  
44 44
            //send to application;
45 45
            mw->utterance_callback(utterance);
server/include/RSB/UtteranceRSB.h
56 56
            char *audio_data_char = (char *)sound_chunk.data().c_str();
57 57

  
58 58
            //audio.samples = vector<char>(audio_data_char, audio_data_char+audio_len);
59
            audio_data.samples.resize(audio_len);
60
            audio_data.samples.assign(audio_data_char, audio_data_char+audio_len);
59
            audio_data->samples.resize(audio_len);
60
            audio_data->samples.assign(audio_data_char, audio_data_char+audio_len);
61 61

  
62
            printf("audio samplesize is %d bytes\n",(unsigned int)audio_data.samples.size());
62
            printf("audio samplesize is %d bytes\n",(unsigned int)audio_data->samples.size());
63 63

  
64 64
            //extract format:
65
            audio_data.sample_signed = true;
65
            audio_data->sample_signed = true;
66 66
            switch (sound_chunk.sample_type()){
67
                case(rst::audition::SoundChunk::SAMPLE_U8):  audio_data.sample_signed = false; //and fall through:
68
                case(rst::audition::SoundChunk::SAMPLE_S8):  audio_data.sample_bit =  8; break;
67
                case(rst::audition::SoundChunk::SAMPLE_U8):  audio_data->sample_signed = false; //and fall through:
68
                case(rst::audition::SoundChunk::SAMPLE_S8):  audio_data->sample_bit =  8; break;
69 69

  
70
                case(rst::audition::SoundChunk::SAMPLE_U16): audio_data.sample_signed = false; //and fall through:
71
                case(rst::audition::SoundChunk::SAMPLE_S16): audio_data.sample_bit = 16; break;
70
                case(rst::audition::SoundChunk::SAMPLE_U16): audio_data->sample_signed = false; //and fall through:
71
                case(rst::audition::SoundChunk::SAMPLE_S16): audio_data->sample_bit = 16; break;
72 72

  
73
                case(rst::audition::SoundChunk::SAMPLE_U24): audio_data.sample_signed = false; //and fall through:
74
                case(rst::audition::SoundChunk::SAMPLE_S24): audio_data.sample_bit = 24; break;
73
                case(rst::audition::SoundChunk::SAMPLE_U24): audio_data->sample_signed = false; //and fall through:
74
                case(rst::audition::SoundChunk::SAMPLE_S24): audio_data->sample_bit = 24; break;
75 75

  
76 76
                default:
77 77
                    printf("> invalid sample type %d in RST SoundChunk! ignoring request!\n", sound_chunk.sample_type());
......
79 79
            }
80 80

  
81 81
            //bitrate
82
            audio_data.sample_rate = sound_chunk.rate();
82
            audio_data->sample_rate = sound_chunk.rate();
83 83

  
84 84
        //endianness
85 85
        if (sound_chunk.endianness() == rst::audition::SoundChunk::ENDIAN_LITTLE){
86
            audio_data.sample_big_endian = false;
86
            audio_data->sample_big_endian = false;
87 87
        }else if (sound_chunk.endianness() == rst::audition::SoundChunk::ENDIAN_BIG){
88
            audio_data.sample_big_endian = true;
88
            audio_data->sample_big_endian = true;
89 89
        }else{
90 90
            printf("> invalid SoundChunk byte_format");
91 91
            throw runtime_error("UtteranceRSB::convert_audio_data() unsupported byte_format in rst::audition::SoundChunk");
92 92
        }
93 93

  
94 94
        //number of channels
95
        audio_data.sample_channels = sound_chunk.channels();
95
        audio_data->sample_channels = sound_chunk.channels();
96 96

  
97
        printf("> new AudioData: %s\n",audio_data.to_string().c_str());
97
        printf("> new AudioData: %s\n",audio_data->to_string().c_str());
98 98
    }
99 99

  
100 100
    void extract_phonemes(rst::audition::Utterance rst_utterance){
server/include/Utterance.h
44 44

  
45 45
    void set_phoneme_vector(phonemes_vector_t p);
46 46
    void set_text(std::string t);
47
    void set_audio_data(AudioData a);
47
    void set_audio_data(boost::shared_ptr<AudioData> a);
48 48

  
49 49
    void start_playback();
50 50
    bool is_playing();
51 51
    std::string currently_active_phoneme();
52
    AudioData get_audio_data();
52
    boost::shared_ptr<AudioData> get_audio_data();
53 53
    std::string get_text();
54 54

  
55 55
protected:
56
    AudioData audio_data;
56
    boost::shared_ptr<AudioData> audio_data;
57 57
    std::string text;
58 58
    phonemes_vector_t phonemes_vector;
59 59

  
server/src/Arbiter.cpp
52 52
    emotion_config_current.init_sad();
53 53
    emotion_config_current.set_duration(2000);
54 54
    emotion_config_default.init_neutral();
55

  
56
    utterance = boost::shared_ptr<Utterance>(new Utterance());
55 57
}
56 58

  
57 59
Arbiter::~Arbiter(){
......
145 147
    }
146 148
}
147 149

  
148
void Arbiter::speak(Utterance u){ //, ao_sample_format audio_format, char *audio_data, unsigned int audio_len){
150
void Arbiter::speak(boost::shared_ptr<Utterance> u){ //, ao_sample_format audio_format, char *audio_data, unsigned int audio_len){
149 151
    //lock audio playback as such:
150 152
    mutex::scoped_lock scoped_lock_audio(audio_player_mutex);
151 153

  
......
155 157
    scoped_lock.unlock();
156 158

  
157 159
    //start audio playback, this function returns once we started playback
158
    audio_player->play(utterance.get_audio_data());
159
    utterance.start_playback();
160
    audio_player->play(utterance->get_audio_data());
161
    utterance->start_playback();
160 162

  
161 163
    //wait until audio playback was finished:
162 164
    while(audio_player->is_playing()){
......
165 167
    }
166 168
    //in case the audio output fails, we end up here before the utterance is finished.
167 169
    //so check now if the utterance finished as well:
168
    while (utterance.is_playing()){
170
    while (utterance->is_playing()){
169 171
        //save some cpu cycles:
170 172
        usleep(1*1000); //1ms
171 173
    }
......
197 199

  
198 200
void Arbiter::override_by_utterance(){
199 201
    //fetch MouthState by utterance:
200
    if (!utterance.is_playing()){
202
    if (!utterance->is_playing()){
201 203
        //not playing -> return
202 204
        return;
203 205
    }
204 206

  
205 207
    //fetch symbol
206
    string symbol = utterance.currently_active_phoneme();
208
    string symbol = utterance->currently_active_phoneme();
207 209
    if ((symbol.empty()) || (symbol == "")){
208 210
        return;
209 211
    }
server/src/AudioPlayerLibAO.cpp
52 52

  
53 53

  
54 54
//this will return once we start playing
55
void AudioPlayerLibAO::play(AudioData audio){
55
void AudioPlayerLibAO::play(boost::shared_ptr<AudioData> audio){
56 56
    audio_data = audio;
57 57

  
58
    printf("> AudioPlayerLibAO: play() %d samples requested\n",(int)audio_data.samples.size());
58
    printf("> AudioPlayerLibAO: play() %d samples requested\n",(int)audio_data->samples.size());
59 59

  
60 60
    //skip empty audio data
61
    if (audio_data.samples.size() == 0){
61
    if (audio_data->samples.size() == 0){
62 62
        printf("> warning: empty audio data - skipped.\n");
63 63
        return;
64 64
    }
......
82 82
}
83 83

  
84 84

  
85
ao_sample_format AudioPlayerLibAO::extract_ao_format(AudioData audio){
85
ao_sample_format AudioPlayerLibAO::extract_ao_format(boost::shared_ptr<AudioData> audio){
86 86
    ao_sample_format ao_format;
87 87

  
88 88
    //get bits per sample
89
    ao_format.bits = audio.sample_bit;
89
    ao_format.bits = audio->sample_bit;
90 90
    //bitrate
91
    ao_format.rate = audio.sample_rate;
91
    ao_format.rate = audio->sample_rate;
92 92
    //endianess
93
    ao_format.byte_format = audio.sample_big_endian?AO_FMT_BIG:AO_FMT_LITTLE;
93
    ao_format.byte_format = audio->sample_big_endian?AO_FMT_BIG:AO_FMT_LITTLE;
94 94
    //number of channels
95
    ao_format.channels = audio.sample_channels;
95
    ao_format.channels = audio->sample_channels;
96 96

  
97 97
    //format matrix:
98 98
    if (ao_format.channels == 1){
......
156 156
                    playback_state = PLAYING;
157 157
                    playback_active = true;
158 158

  
159
                    ao_play(device, audio_data.samples.data(), audio_data.samples.size());
159
                    ao_play(device, audio_data->samples.data(), audio_data->samples.size());
160 160
                    printf("> AudioPlayer: finished playback\n");
161 161
                }
162 162
                break;
server/src/AudioPlayerRSB.cpp
63 63

  
64 64

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

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

  
71 71
    //check if we can play this file:
72 72
    while(playback_state != IDLE){
......
156 156
void AudioPlayerRSB::publish_audio_data(){
157 157
    boost::shared_ptr<rst::audition::SoundChunk> request(new rst::audition::SoundChunk());
158 158

  
159
    request->set_channels(audio_data.sample_channels);
160
    request->set_data(audio_data.samples.data());
159
    request->set_channels(audio_data->sample_channels);
160
    request->set_data(audio_data->samples.data());
161 161
/*
162 162
    if (audio_data.sample_big_endian){
163 163
        request->set_endianness(rst::audition::SoundChunk_EndianNess_ENDIAN_BIG);
server/src/Middleware.cpp
44 44
    printf("> %s(%s) called\n", __FUNCTION__,text.c_str());
45 45

  
46 46
    //call a tts system to convert the text to an utterance:
47
    Utterance utterance = tts_call(text);
47
    boost::shared_ptr<Utterance> utterance = tts_call(text);
48 48

  
49 49
    //and then process it
50 50
    utterance_callback(utterance);
51 51
}
52 52

  
53
void Middleware::utterance_callback(Utterance utterance){
54
    printf("> %s(text=%s) called\n", __FUNCTION__,utterance.get_text().c_str());
53
void Middleware::utterance_callback(boost::shared_ptr<Utterance> utterance){
54
    printf("> %s(text=%s) called\n", __FUNCTION__,utterance->get_text().c_str());
55 55

  
56 56
    //can we speak this now?
57 57
    if (arbiter->speak_active()){
server/src/MiddlewareROS.cpp
93 93
}
94 94

  
95 95
//call a tts system to convert a string to an utterance
96
Utterance MiddlewareROS::tts_call(string text){
96
boost::shared_ptr<Utterance> MiddlewareROS::tts_call(string text){
97 97
    //double tts_timeout = 1.0; //seconds. DO NOT CHANGE THIS!
98 98

  
99
    Utterance utterance;
99
    boost::shared_ptr<Utterance> utterance(new Utterance());
100 100

  
101 101
    printf("> WARNING: ros tts call not implemented yet\n");
102 102

  
......
120 120

  
121 121
    printf("> done. got utterance (text=%s)\n",utterance.get_text().c_str());
122 122
    */
123

  
123 124
    return utterance;
124 125
}
125 126

  
server/src/MiddlewareRSB.cpp
136 136
}
137 137

  
138 138
//call a tts system to convert a string to an utterance
139
Utterance MiddlewareRSB::tts_call(string text){
139
boost::shared_ptr<Utterance> MiddlewareRSB::tts_call(string text){
140 140
    double tts_timeout = 1.0; //seconds. DO NOT CHANGE THIS!
141 141

  
142
    Utterance utterance;
143

  
144 142
    //build request
145 143
    boost::shared_ptr<std::string> request(new string(text));
146 144

  
......
150 148

  
151 149
        //try to fetch the result
152 150
        boost::shared_ptr<rst::audition::Utterance> utterance_ptr = future_ptr.get(tts_timeout);
153
        utterance = UtteranceRSB(*(utterance_ptr.get()));
151

  
152
        //done, return utterance ptr
153
        boost::shared_ptr<Utterance> utterance(new UtteranceRSB(*(utterance_ptr.get())));
154
        printf("> done. got utterance (text=%s)\n",utterance->get_text().c_str());
155
        return utterance;
154 156

  
155 157
    }catch(rsc::threading::FutureTimeoutException e){
156 158
        printf("> error: tts_call timed out after %3.1f seconds.\n", tts_timeout);
......
158 160
        printf("> error: tts_call failed: %s\n", e.what());
159 161
    }
160 162

  
161
    printf("> done. got utterance (text=%s)\n",utterance.get_text().c_str());
163
    printf("> failed... got no utterance\n");
164
    boost::shared_ptr<Utterance> utterance(new Utterance());
162 165
    return utterance;
163 166
}
164 167

  
server/src/Utterance.cpp
35 35
Utterance::Utterance(){
36 36
    playing = false;
37 37
    text = "UNINITIALISED UTTERANCE";
38
    audio_data = boost::shared_ptr<AudioData>(new AudioData());
38 39
}
39 40

  
40 41
void Utterance::set_phoneme_vector(phonemes_vector_t p){
......
45 46
    text = t;
46 47
}
47 48

  
48
void Utterance::set_audio_data(AudioData a){
49
void Utterance::set_audio_data(boost::shared_ptr<AudioData> a){
49 50
    audio_data = a;
50 51
}
51 52

  
......
56 57
    return text;
57 58
}
58 59

  
59
AudioData Utterance::get_audio_data(){
60
boost::shared_ptr<AudioData> Utterance::get_audio_data(){
60 61
    return audio_data;
61 62
}
62 63

  

Also available in: Unified diff