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

Tekkotsu v4.0
Generated Thu Nov 22 00:54:54 2007 by Doxygen 1.5.4