Homepage Demos Overview Downloads Tutorials Reference
Credits

MicrophoneServer.cc

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

Tekkotsu v2.2.1
Generated Tue Nov 23 16:36:39 2004 by Doxygen 1.3.9.1