Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

SpeakerServer.cc

Go to the documentation of this file.
00001 #include "Shared/RobotInfo.h"
00002 #ifdef TGT_HAS_SPEAKERS
00003 
00004 #include "SpeakerServer.h"
00005 
00006 #include "Shared/Buffer.h"
00007 #include "Shared/Config.h"
00008 #include "Shared/RobotInfo.h"
00009 #include "Wireless/Wireless.h"
00010 
00011 typedef BehaviorSwitchControl<SpeakerServer,SingletonFactory<SpeakerServer> > SpeakerServerControl;
00012 REGISTER_CONTROL_INSTANCE_OPT(SpeakerServer,new SpeakerServerControl("Speaker Server",false),"TekkotsuMon",BEH_NONEXCLUSIVE);
00013 
00014 SpeakerServer* SpeakerServer::instance = 0;
00015 
00016 SpeakerServer& SpeakerServer::getInstance() {
00017   if (instance == 0) {
00018     instance = new SpeakerServer();
00019   }
00020   return *instance;
00021 }
00022 
00023 SpeakerServer::SpeakerServer()
00024   : BehaviorBase("Speaker Server"), socket(0),
00025     packet(), frame(0), resampled(0),
00026     channel(SoundManager::invalid_Play_ID) {
00027     
00028   addReference();
00029 }
00030 
00031 SpeakerServer::~SpeakerServer() {
00032   delete frame;
00033   delete resampled;
00034   
00035   if (references == 1) {
00036     instance = 0;
00037   }
00038 }
00039 
00040 
00041 void SpeakerServer::doStart() {
00042   BehaviorBase::doStart();
00043   
00044   if (socket != 0) {
00045     wireless->setDaemon(socket, false);
00046     wireless->close(socket);
00047     socket = 0;
00048   }
00049   
00050   packet.header->SetPosition(0);
00051   channel = SoundManager::invalid_Play_ID;
00052     
00053   socket =
00054     wireless->socket(Socket::SOCK_STREAM, RECEIVE_BUFFER_SIZE + 8, 512);
00055   wireless->setReceiver(socket->sock, socket_callback);
00056   wireless->setDaemon(socket, true);
00057   wireless->listen(socket->sock, config->sound.streaming.speaker_port);
00058 }
00059 
00060 void SpeakerServer::doStop() {
00061   if (socket != 0) {
00062     wireless->setDaemon(socket, false);
00063     wireless->close(socket);
00064     socket = 0;
00065   }
00066   
00067   sndman->stopPlay(channel);
00068   channel = SoundManager::invalid_Play_ID;
00069   
00070   packet.samples->SetCapacity(0);
00071   
00072   delete frame;
00073   delete resampled;
00074 
00075   BehaviorBase::doStop();
00076 }
00077 
00078 int SpeakerServer::socket_callback(char *buf, int size) {
00079   if (instance == 0) {
00080     return 0;
00081   } else {
00082     return instance->GotSocketData(buf, size);
00083   }
00084 }
00085 
00086 SpeakerServer::Packet::Packet()
00087   : header(new Buffer(4)), size(0), type(0), skipped(false),
00088     pcmHeader(new Buffer(4)), sampleRate(0), sampleBits(0),
00089     samples(new Buffer(0)) {}
00090     
00091 SpeakerServer::Packet::~Packet() {
00092   delete header;
00093   delete pcmHeader;
00094   delete samples;
00095 }
00096 
00097 int SpeakerServer::GotSocketData(char* data, int dataSize) {
00098   while (dataSize > 0) {
00099     if (!packet.header->IsFull()) {
00100       if (!packet.header->Fill(data, dataSize)) {
00101         break;
00102       }
00103       packet.size =
00104         (unsigned short) GetShort(&packet.header->GetData()[0]);
00105       packet.type = GetShort(&packet.header->GetData()[2]);
00106       if ((packet.type == 0) && (packet.size >= 4)) {
00107         // PCM packet
00108         packet.pcmHeader->SetPosition(0);
00109         packet.skipped = false;
00110       } else {
00111         packet.skipped = true;
00112       }
00113     }
00114     
00115     if (packet.skipped) {
00116       if (packet.size > dataSize) {
00117         packet.size -= dataSize;
00118         break;
00119       } else {
00120         data += packet.size;
00121         dataSize -= packet.size;
00122         // Start reading next packet
00123         packet.header->SetPosition(0);
00124         continue;
00125       }
00126     }
00127     
00128     if (!packet.pcmHeader->IsFull()) {
00129       if (!packet.pcmHeader->Fill(data, dataSize)) {
00130         break;
00131       }
00132       packet.size -= packet.pcmHeader->GetLimit();
00133       packet.sampleRate =
00134         (unsigned short) GetShort(&packet.pcmHeader->GetData()[0]);
00135       packet.sampleBits = packet.pcmHeader->GetData()[2];
00136       
00137       const int resampledSize =
00138         packet.size *
00139           ((packet.sampleBits == 8) ? 2 : 1)
00140           * config->sound.sample_rate / packet.sampleRate;
00141       
00142       if ((packet.size > MAX_PACKET_SIZE)
00143             || (resampledSize > MAX_PACKET_SIZE)) {
00144         // Too many samples
00145         packet.skipped = true;
00146         continue;
00147       }
00148       packet.samples->SetCapacity(MAX_PACKET_SIZE);
00149       packet.samples->SetLimit(packet.size);
00150       packet.samples->SetPosition(0);
00151     }
00152         
00153     if (!packet.samples->IsFull()) {
00154       if (!packet.samples->Fill(data, dataSize)) {
00155         break;
00156       }
00157       AddPacket(
00158         packet.samples->GetData(),
00159         packet.samples->GetLimit(),
00160         packet.sampleRate,
00161         packet.sampleBits);
00162       // Start reading next packet
00163       packet.header->SetPosition(0);
00164       continue;
00165     }
00166   }
00167 
00168   return 0;
00169 }
00170 
00171 void SpeakerServer::AddPacket(
00172   const void* samples,
00173   int samplesSize,
00174   int sampleRate,
00175   byte sampleBits) {
00176 
00177   if (samplesSize < 1) {
00178     return;
00179   }
00180 
00181   samples =
00182     ResampleForSpeaker(
00183       samples, samplesSize, sampleRate, sampleBits, samplesSize);
00184   if (samples == 0) {
00185     return;
00186   }
00187   
00188   const int frameSize =
00189     config->sound.streaming.speaker_frame_length
00190       * config->sound.sample_rate
00191       * ((config->sound.sample_bits == 8u) ? 1 : 2)
00192       / 1000;
00193   if (frame == 0) {
00194     frame = new Buffer(frameSize);
00195   } else if (frameSize != frame->GetLimit()) {
00196     if (frame->GetPosition() > frameSize) {
00197       QueueFrame(frame->GetData(), frame->GetPosition());
00198       frame->SetPosition(0);
00199     } else {
00200       frame->SetLimit(frameSize);
00201     }
00202     
00203     if (frame->GetLimit() < frameSize) {
00204       if (frame->GetCapacity() < frameSize) {
00205         frame->SetCapacity(frameSize);
00206       }
00207       frame->SetLimit(frameSize);
00208     }
00209   }
00210   
00211   if (frame->GetLimit() < 1) {
00212     return;
00213   }
00214   
00215   const char* buf = (const char*) samples;
00216   while (frame->Fill(buf, samplesSize)) {
00217     QueueFrame(frame->GetData(), frame->GetPosition());
00218     frame->SetPosition(0);
00219   }
00220 }
00221     
00222     
00223 void SpeakerServer::QueueFrame(const char* samples, int samplesSize) {
00224   if (channel != SoundManager::invalid_Play_ID) {
00225     const int remainingTime = sndman->getRemainTime(channel) - RobotInfo::SoundBufferTime;
00226     if (remainingTime > (int) config->sound.streaming.speaker_max_delay) {
00227       // Queue too long
00228       sndman->stopPlay(channel);
00229       channel = SoundManager::invalid_Play_ID;
00230     } else if (remainingTime < 0) {
00231       // Queue underrun
00232     } else {
00233       // Try queueing
00234       SoundManager::Play_ID newChannel =
00235         sndman->chainBuffer(channel, samples, (int) samplesSize);
00236       if (newChannel != SoundManager::invalid_Play_ID) {
00237         channel = newChannel;
00238         return;
00239       }
00240     }
00241   }
00242   
00243   // Start a new channel
00244   channel = sndman->playBuffer(samples, samplesSize);
00245 }
00246 
00247 const void* SpeakerServer::ResampleForSpeaker(
00248   const void* samples,
00249   int samplesSize,
00250   int sampleRate,
00251   byte bitsPerSample,
00252   int& newSamplesSize) {
00253     
00254   const int newSampleRate = config->sound.sample_rate;
00255   const int newBitsPerSample = config->sound.sample_bits;
00256   
00257   if ((sampleRate == newSampleRate) && (bitsPerSample == newBitsPerSample)) {
00258     newSamplesSize = samplesSize;
00259     return samples;
00260   }
00261   
00262   const int sampleCount = samplesSize / ((bitsPerSample == 16) ? 2 : 1);  
00263   const int newSampleCount = sampleCount * newSampleRate / sampleRate;
00264   newSamplesSize = newSampleCount * ((newBitsPerSample == 16) ? 2 : 1);
00265   
00266   if (newSampleCount == 0) {
00267     newSamplesSize = 0;
00268     return 0;
00269   }
00270   
00271   if (resampled == 0) {
00272     resampled = new Buffer(newSamplesSize);
00273   } else if (resampled->GetCapacity() < newSamplesSize) {
00274     resampled->SetCapacity(newSamplesSize);
00275   }
00276   
00277   // The code below is biased towards upsampling (normal case).
00278   // It does not average samples during downsampling.
00279   
00280   if (bitsPerSample == 16) {
00281     // 16-bit signed source
00282     const short* source = (const short*) samples; 
00283     if (newBitsPerSample == 16) {
00284       // 16-bit signed source, 16-bit signed destination
00285       short* dest = (short*) resampled->GetData();
00286       for (int i = 0; i < newSampleCount; i++) {  
00287         dest[i] = source[i * sampleRate / newSampleRate];
00288       }
00289     } else if (newBitsPerSample == 8) {
00290       // 16-bit signed source, 8-bit unsigned destination
00291       byte* dest = (byte*) resampled->GetData();
00292       for (int i = 0; i < newSampleCount; i++) {  
00293         dest[i] = ((byte) (source[i * sampleRate / newSampleRate] >> 8)) ^ 0x80;
00294       }
00295     } else {
00296       newSamplesSize = 0;
00297       return 0;
00298     }
00299   } else if (bitsPerSample == 8) {
00300     // 8-bit unsigned source
00301     const byte* source = (const byte*) samples;
00302     if (newBitsPerSample == 8) {
00303       // 8-bit unsigned source, 8-bit unsigned destination
00304       byte* dest = (byte*) resampled->GetData();
00305       for (int i = 0; i < newSampleCount; i++) {  
00306         dest[i] = source[i * sampleRate / newSampleRate];
00307       }
00308     } else if (newBitsPerSample == 16) {
00309       // 8-bit unsigned source, 16-bit signed destination
00310       short* dest = (short*) resampled->GetData();
00311       for (int i = 0; i < newSampleCount; i++) {  
00312         dest[i] = (source[i * sampleRate / newSampleRate] ^ 0x80) << 8;
00313       }
00314     } else {
00315       newSamplesSize = 0;
00316       return 0;
00317     }
00318   } else {
00319     newSamplesSize = 0;
00320     return 0;
00321   }
00322   
00323   return resampled->GetData();
00324 }
00325 
00326 #endif

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