Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

MicrophoneServer.cc

Go to the documentation of this file.
00001 #include "Shared/RobotInfo.h"
00002 #ifdef TGT_HAS_MICROPHONE
00003 
00004 #include "MicrophoneServer.h"
00005 
00006 #include "Events/DataEvent.h"
00007 #include "Events/EventRouter.h"
00008 #include "Shared/Config.h"
00009 #include "Wireless/Wireless.h"
00010 
00011 #include "Shared/ODataFormats.h"
00012 #ifdef PLATFORM_APERIOS
00013 #  include "OPENR/OPENRAPI.h"
00014 #endif
00015 
00016 typedef BehaviorSwitchControl<MicrophoneServer,SingletonFactory<MicrophoneServer> > MicrophoneServerControl;
00017 REGISTER_CONTROL_INSTANCE_OPT(MicrophoneServer,new MicrophoneServerControl("Microphone Server",false),"TekkotsuMon",BEH_NONEXCLUSIVE);
00018 
00019 MicrophoneServer* MicrophoneServer::instance = 0;
00020 const char* const MicrophoneServer::MIC_LOCATOR = "PRM:/r1/c1/c2/c3/m1-Mic:M1";
00021 
00022 MicrophoneServer& MicrophoneServer::getInstance() {
00023   if (instance == 0) {
00024     instance = new MicrophoneServer();
00025   }
00026   return *instance;
00027 }
00028 
00029 MicrophoneServer::MicrophoneServer()
00030   : BehaviorBase("Microphone Server"), socket(0) {
00031     
00032   addReference();
00033 }
00034 
00035 MicrophoneServer::~MicrophoneServer() {
00036   if (references == 1) {
00037     instance = 0;
00038   }
00039 }
00040 
00041 
00042 void MicrophoneServer::doStart() {
00043   BehaviorBase::doStart();
00044   
00045   if (socket != 0) {
00046     wireless->setDaemon(socket, false);
00047     wireless->close(socket);
00048     socket = 0;
00049   }
00050     
00051   socket = wireless->socket(Socket::SOCK_STREAM, 512, SEND_BUFFER_SIZE);
00052   wireless->setDaemon(socket, true);
00053   wireless->listen(socket->sock, config->sound.streaming.mic_port);
00054   
00055   erouter->addListener(this, EventBase::micOSndEGID);
00056 }
00057 
00058 void MicrophoneServer::doStop() {
00059   erouter->removeListener(this);
00060   
00061   if (socket != 0) {
00062     wireless->setDaemon(socket, false);
00063     wireless->close(socket);
00064     socket = 0;
00065   }
00066   
00067   BehaviorBase::doStop();
00068 }
00069 
00070 void MicrophoneServer::doEvent() {
00071   if (event->getGeneratorID() != EventBase::micOSndEGID) {
00072     return;
00073   }
00074   
00075   // Got an audio frame from the microphone
00076   if ((socket == 0) || (!wireless->isConnected(socket->sock))) {
00077     return;
00078   }
00079   
00080   const DataEvent<const OSoundVectorData*>* e =
00081     reinterpret_cast<const DataEvent<const OSoundVectorData*>*>(event);
00082   OSoundVectorData* data = const_cast<OSoundVectorData *>(e->getData());
00083   const char* samples = reinterpret_cast<char*>(data->GetData(0));
00084   const int samplesSize = data->GetInfo(0)->dataSize;
00085   
00086   unsigned int sampleRate = config->sound.streaming.mic_sample_rate;
00087   unsigned int sampleBits = config->sound.streaming.mic_sample_bits;
00088   bool stereo = config->sound.streaming.mic_stereo;
00089   
00090   unsigned int newSamplesSize = GetResampledFrameSize(samplesSize, sampleRate, sampleBits, stereo);
00091   if (newSamplesSize == 0) {
00092     return;
00093   }
00094   
00095   const unsigned int headerSize = 8;
00096   char* buf = (char*) socket->getWriteBuffer(headerSize + newSamplesSize);
00097   if (buf == 0) {
00098     // Network not ready, drop this frame
00099     return;
00100   }
00101     
00102   unsigned int resampledSize = 0;
00103   resampledSize = ResampleFrame(samples, samplesSize, sampleRate, sampleBits, stereo, buf + headerSize, newSamplesSize);
00104   if (resampledSize != newSamplesSize) {
00105     return;
00106   }
00107   
00108   encode(&buf, (unsigned short) (newSamplesSize + headerSize - 4));
00109   encode(&buf, (unsigned short) 0); // PCM frame
00110   encode(&buf, (unsigned short) sampleRate);
00111   encode(&buf, (byte)  sampleBits);
00112   encode(&buf, stereo);
00113 
00114   socket->write(headerSize + newSamplesSize);
00115 }
00116 
00117 unsigned int MicrophoneServer::GetResampledFrameSize(
00118   unsigned int samplesSize,
00119   unsigned int newSampleRate,
00120   unsigned int newSampleBits,
00121   bool newStereo) {
00122   
00123   if (newSampleRate > 16000) {
00124     newSampleRate = 16000;
00125   } else if (newSampleRate < 1) {
00126     newSampleRate = 1;
00127   }
00128   
00129   if (newSampleBits >= 12) {
00130     newSampleBits = 16;
00131   } else {
00132     newSampleBits = 8;
00133   }
00134   
00135   if ((newSampleRate == 16000) && (newSampleBits == 16) && (newStereo)) {
00136     // No need to resample
00137     return samplesSize;
00138   } else {
00139     // Resample from 16 kHz 16 bit stereo
00140     const unsigned int frameCount = samplesSize / 4; 
00141     const unsigned int newFrameCount = frameCount * newSampleRate / 16000;
00142     const unsigned int newFrameSize =
00143     ((newSampleBits == 8) ? 1 : 2) * ((newStereo) ? 2 : 1);
00144     return newFrameCount * newFrameSize;    
00145   }
00146 }
00147 
00148 unsigned int MicrophoneServer::ResampleFrame(
00149   const char* samples,
00150   unsigned int samplesSize,
00151   unsigned int& newSampleRate,
00152   unsigned int& newSampleBits,
00153   bool& newStereo,
00154   void* buf,
00155   unsigned int bufSize) {
00156      
00157   
00158   if (newSampleRate > 16000) {
00159     newSampleRate = 16000;
00160   } else if (newSampleRate < 1) {
00161     newSampleRate = 1;
00162   }
00163   
00164   if (newSampleBits >= 12) {
00165     newSampleBits = 16;
00166   } else {
00167     newSampleBits = 8;
00168   }
00169       
00170   if ((newSampleRate == 16000) && (newSampleBits == 16) && (newStereo)) {
00171     // No need to resample
00172     if (samplesSize <= bufSize) {
00173       memcpy(buf, samples, samplesSize);
00174       return samplesSize;
00175     } else {
00176       return 0;
00177     }
00178   } else {
00179     // Resample from 16 kHz 16 bit stereo
00180     const unsigned int frameCount = samplesSize / 4; 
00181     const unsigned int newFrameCount = frameCount * newSampleRate / 16000;
00182     const unsigned int newFrameSize =
00183       ((newSampleBits == 8) ? 1 : 2) * ((newStereo) ? 2 : 1);
00184     unsigned int newSamplesSize = newFrameCount * newFrameSize;
00185     if (newSamplesSize > bufSize) {
00186       return 0;
00187     }
00188     
00189     char* newSamplesChar = (char*) buf;
00190     short* newSamplesShort = (short*) buf;
00191     const short* samplesShort = (const short*) samples;
00192     for (unsigned int newFrame = 0; newFrame < newFrameCount; newFrame++) {
00193       const int frame = newFrame * 16000 / newSampleRate;
00194       if (newSampleBits == 8) {
00195         // 8-bit
00196         if (newStereo) {
00197           // 8-bit stereo
00198           newSamplesChar[newFrame * 2 + 0] = samples[frame * 4 + 1];
00199           newSamplesChar[newFrame * 2 + 1] = samples[frame * 4 + 3];
00200         } else {
00201           // 8-bit mono
00202           newSamplesChar[newFrame] =
00203             ((int) samplesShort[frame * 2 + 0]
00204               + (int) samplesShort[frame * 2 + 1]) >> 9;
00205         }
00206       } else {
00207         // 16-bit
00208         if (newStereo) {
00209           // 16-bit stereo
00210           newSamplesShort[newFrame * 2 + 0] = samplesShort[frame * 2 + 0];
00211           newSamplesShort[newFrame * 2 + 1] = samplesShort[frame * 2 + 1];
00212         } else {
00213           // 16-bit mono
00214           newSamplesShort[newFrame] =
00215             ((int) samplesShort[frame * 2 + 0]
00216               + (int) samplesShort[frame * 2 + 1]) >> 1;
00217         }
00218       }
00219     }
00220     return newSamplesSize;
00221   }
00222 }
00223 
00224 #ifdef PLATFORM_APERIOS
00225 bool MicrophoneServer::SetMicrophoneUnidirectional(bool unidirectional) {
00226   OPrimitiveID micID;
00227   OStatus result = OPENR::OpenPrimitive(MIC_LOCATOR, &micID);
00228   if (result != oSUCCESS) {
00229     return false;
00230   }
00231   
00232   result = OPENR::ControlPrimitive(
00233     micID, ((unidirectional) ? oprmreqMIC_UNI : oprmreqMIC_OMNI), 0, 0, 0, 0);
00234   if (result != oSUCCESS) {
00235     return false;
00236   }
00237 #else
00238 bool MicrophoneServer::SetMicrophoneUnidirectional(bool /*unidirectional*/) {
00239 #endif
00240   return true;
00241 }
00242 
00243 #ifdef PLATFORM_APERIOS
00244 bool MicrophoneServer::SetMicrophoneAlcEnabled(bool enabled) {
00245   OPrimitiveID micID;
00246   OStatus result = OPENR::OpenPrimitive(MIC_LOCATOR, &micID);
00247   if (result != oSUCCESS) {
00248     return false;
00249   }
00250   
00251   result = OPENR::ControlPrimitive(
00252     micID, ((enabled) ? oprmreqMIC_ALC_ON : oprmreqMIC_ALC_OFF),  0, 0, 0, 0);
00253   if (result != oSUCCESS) {
00254     return false;
00255   }
00256 #else
00257 bool MicrophoneServer::SetMicrophoneAlcEnabled(bool /*enabled*/) {
00258 #endif  
00259   return true;
00260 }
00261 
00262 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:45 2016 by Doxygen 1.6.3