event/audio.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015 Aldebaran
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #include <iostream>
19 #include <vector>
20 
21 #include <boost/make_shared.hpp>
22 
23 #include <ros/ros.h>
24 
25 #include <qi/anyobject.hpp>
26 
29 
30 #include "audio.hpp"
31 
32 namespace naoqi
33 {
34 
35 AudioEventRegister::AudioEventRegister( const std::string& name, const float& frequency, const qi::SessionPtr& session )
36  : serviceId(0),
37  p_audio_( session->service("ALAudioDevice")),
38  p_robot_model_(session->service("ALRobotModel")),
39  session_(session),
40  naoqi_version_(helpers::driver::getNaoqiVersion(session)),
41  isStarted_(false),
42  isPublishing_(false),
43  isRecording_(false),
44  isDumping_(false)
45 {
46  // _getMicrophoneConfig is used for NAOqi < 2.9, _getConfigMap for NAOqi > 2.9
47  int micConfig;
48 
50  {
51  micConfig = p_robot_model_.call<int>("_getMicrophoneConfig");
52  }
53  else
54  {
55  std::map<std::string, std::string> config_map =\
56  p_robot_model_.call<std::map<std::string, std::string> >("_getConfigMap");
57 
58  micConfig = std::atoi(
59  config_map["RobotConfig/Head/Device/Micro/Version"].c_str());
60  }
61 
62  if(micConfig){
63  channelMap.push_back(3);
64  channelMap.push_back(5);
65  channelMap.push_back(0);
66  channelMap.push_back(2);
67  }
68  else{
69  channelMap.push_back(0);
70  channelMap.push_back(2);
71  channelMap.push_back(1);
72  channelMap.push_back(4);
73  }
74  publisher_ = boost::make_shared<publisher::BasicPublisher<naoqi_bridge_msgs::AudioBuffer> >( name );
75  recorder_ = boost::make_shared<recorder::BasicEventRecorder<naoqi_bridge_msgs::AudioBuffer> >( name );
76  converter_ = boost::make_shared<converter::AudioEventConverter>( name, frequency, session );
77 
79  converter_->registerCallback( message_actions::RECORD, boost::bind(&recorder::BasicEventRecorder<naoqi_bridge_msgs::AudioBuffer>::write, recorder_, _1) );
80  converter_->registerCallback( message_actions::LOG, boost::bind(&recorder::BasicEventRecorder<naoqi_bridge_msgs::AudioBuffer>::bufferize, recorder_, _1) );
81 
82 }
83 
85 {
86  stopProcess();
87 }
88 
90 {
91  publisher_->reset(nh);
92 }
93 
95 {
96  recorder_->reset(gr, converter_->frequency());
97 }
98 
100 {
101  boost::mutex::scoped_lock start_lock(subscription_mutex_);
102  if (!isStarted_)
103  {
104  if(!serviceId)
105  {
106  serviceId = session_->registerService("ROS-Driver-Audio", shared_from_this());
107  p_audio_.call<void>(
108  "setClientPreferences",
109  "ROS-Driver-Audio",
110  48000,
111  0,
112  0
113  );
114  p_audio_.call<void>("subscribe","ROS-Driver-Audio");
115  std::cout << "Audio Extractor: Start" << std::endl;
116  }
117  isStarted_ = true;
118  }
119 }
120 
122 {
123  boost::mutex::scoped_lock stop_lock(subscription_mutex_);
124  if (isStarted_)
125  {
126  if(serviceId){
127  p_audio_.call<void>("unsubscribe", "ROS-Driver-Audio");
128  session_->unregisterService(serviceId);
129  serviceId = 0;
130  }
131  std::cout << "Audio Extractor: Stop" << std::endl;
132  isStarted_ = false;
133  }
134 }
135 
137 {
138  if (isStarted_)
139  {
140  recorder_->writeDump(time);
141  }
142 }
143 
145 {
146  recorder_->setBufferDuration(duration);
147 }
148 
150 {
151  boost::mutex::scoped_lock rec_lock(processing_mutex_);
152  isRecording_ = state;
153 }
154 
156 {
157  boost::mutex::scoped_lock pub_lock(processing_mutex_);
158  isPublishing_ = state;
159 }
160 
162 {
163  boost::mutex::scoped_lock dump_lock(processing_mutex_);
164  isDumping_ = state;
165 }
166 
168 {
169 }
170 
172 {
173 }
174 
175 void AudioEventRegister::processRemote(int nbOfChannels, int samplesByChannel, qi::AnyValue altimestamp, qi::AnyValue buffer)
176 {
177  naoqi_bridge_msgs::AudioBuffer msg = naoqi_bridge_msgs::AudioBuffer();
178  msg.header.stamp = ros::Time::now();
179  msg.frequency = 48000;
180  msg.channelMap = channelMap;
181 
182  std::pair<char*, size_t> buffer_pointer = buffer.asRaw();
183 
184  int16_t* remoteBuffer = (int16_t*)buffer_pointer.first;
185  int bufferSize = nbOfChannels * samplesByChannel;
186  msg.data = std::vector<int16_t>(remoteBuffer, remoteBuffer+bufferSize);
187 
188  std::vector<message_actions::MessageAction> actions;
189  boost::mutex::scoped_lock callback_lock(processing_mutex_);
190  if (isStarted_) {
191  // CHECK FOR PUBLISH
192  if ( isPublishing_ && publisher_->isSubscribed() )
193  {
194  actions.push_back(message_actions::PUBLISH);
195  }
196  // CHECK FOR RECORD
197  if ( isRecording_ )
198  {
199  actions.push_back(message_actions::RECORD);
200  }
201  if ( !isDumping_ )
202  {
203  actions.push_back(message_actions::LOG);
204  }
205  if (actions.size() >0)
206  {
207  converter_->callAll( actions, msg );
208  }
209  }
210 
211 }
212 
213 }//namespace
msg
std::vector< uint8_t > channelMap
Definition: event/audio.hpp:93
void writeDump(const ros::Time &time)
void isRecording(bool state)
qi::AnyObject p_robot_model_
Definition: event/audio.hpp:91
void resetPublisher(ros::NodeHandle &nh)
Definition: event/audio.cpp:89
void processRemote(int nbOfChannels, int samplesByChannel, qi::AnyValue altimestamp, qi::AnyValue buffer)
void resetRecorder(boost::shared_ptr< naoqi::recorder::GlobalRecorder > gr)
Definition: event/audio.cpp:94
const robot::NaoqiVersion & naoqi_version_
Definition: event/audio.hpp:95
boost::mutex subscription_mutex_
Definition: event/audio.hpp:97
boost::shared_ptr< publisher::BasicPublisher< naoqi_bridge_msgs::AudioBuffer > > publisher_
Definition: event/audio.hpp:86
const robot::NaoqiVersion & getNaoqiVersion(const qi::SessionPtr &session)
Function that retrieves the NAOqi version of the robot.
void isDumping(bool state)
void isPublishing(bool state)
boost::shared_ptr< converter::AudioEventConverter > converter_
Definition: event/audio.hpp:85
AudioEventRegister(const std::string &name, const float &frequency, const qi::SessionPtr &session)
Constructor for recorder interface.
Definition: event/audio.cpp:35
static Time now()
boost::mutex processing_mutex_
Definition: event/audio.hpp:98
void setBufferDuration(float duration)
bool isNaoqiVersionLesser(const robot::NaoqiVersion &naoqi_version, const int &major, const int &minor, const int &patch, const int &build)
Function that returns true if the provided naoqi_version is (strictly) lesser than the specified one ...
boost::shared_ptr< recorder::BasicEventRecorder< naoqi_bridge_msgs::AudioBuffer > > recorder_
Definition: event/audio.hpp:87


naoqi_driver
Author(s): Karsten Knese
autogenerated on Sat Jul 1 2023 02:53:24