00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "SoundPlay/entry.h"
00015 #include <OPENR/OPENRAPI.h>
00016 #include <OPENR/OSyslog.h>
00017 #include <OPENR/core_macro.h>
00018 #include "SoundPlay.h"
00019
00020 #include <iostream>
00021 #include "SoundPlay/SoundManager.h"
00022 #include "Shared/RobotInfo.h"
00023 #include "Shared/Config.h"
00024 #include "Shared/debuget.h"
00025 #include "Events/EventRouter.h"
00026
00027 SoundPlay::SoundPlay()
00028 : active(0), soundManagerMemRgn(NULL), eventTranslatorQueueMemRgn(NULL), etrans(), speakerID(oprimitiveID_UNDEF)
00029 {
00030 for (unsigned int i = 0; i < SOUND_NUM_BUFFER; i++)
00031 region[i] = 0;
00032 }
00033
00034 OStatus
00035 SoundPlay::DoInit(const OSystemEvent&)
00036 {
00037
00038
00039 NEW_ALL_SUBJECT_AND_OBSERVER;
00040 REGISTER_ALL_ENTRY;
00041 SET_ALL_READY_AND_NOTIFY_ENTRY;
00042
00043 observer[obsSoundManagerComm]->SetBufCtrlParam(0,1,SoundManager::MAX_SND+1);
00044
00045
00046
00047 ProcessID::setID(ProcessID::SoundProcess);
00048
00049
00050 config=new Config("/ms/config/tekkotsu.cfg");
00051
00052 erouter = new EventRouter;
00053
00054
00055 soundManagerMemRgn = InitRegion(sizeof(SoundManager));
00056 sndman=new ((SoundManager*)soundManagerMemRgn->Base()) SoundManager;
00057 sndman->InitAccess(subject[sbjSoundManagerComm]);
00058 for(unsigned int i=0; i<config->sound.preload.size(); i++)
00059 sndman->LoadFile(config->sound.preload[i].c_str());
00060
00061 OpenSpeaker();
00062 NewSoundVectorData();
00063 SetPowerAndVolume();
00064
00065 return oSUCCESS;
00066 }
00067
00068 OStatus
00069 SoundPlay::DoStart(const OSystemEvent&)
00070 {
00071
00072
00073 ENABLE_ALL_SUBJECT;
00074 ASSERT_READY_TO_ALL_OBSERVER;
00075
00076 return oSUCCESS;
00077 }
00078
00079 OStatus
00080 SoundPlay::DoStop(const OSystemEvent&)
00081 {
00082
00083
00084 sndman->StopPlay();
00085
00086 DISABLE_ALL_SUBJECT;
00087 DEASSERT_READY_TO_ALL_OBSERVER;
00088
00089 return oSUCCESS;
00090 }
00091
00092 OStatus
00093 SoundPlay::DoDestroy(const OSystemEvent&)
00094 {
00095 for(unsigned int i=0; i<config->sound.preload.size(); i++)
00096 sndman->ReleaseFile(config->sound.preload[i].c_str());
00097 delete erouter;
00098 eventTranslatorQueueMemRgn->RemoveReference();
00099 DELETE_ALL_SUBJECT_AND_OBSERVER;
00100 return oSUCCESS;
00101 }
00102
00103 void
00104 SoundPlay::ReadySendSound(const OReadyEvent&)
00105 {
00106
00107 doSendSound();
00108 }
00109
00110 void
00111 SoundPlay::ReadyRegisterSoundManager(const OReadyEvent&) {
00112 static bool is_init=true;
00113 if(is_init) {
00114 is_init=false;
00115 cout << objectName << " Registering SoundManager" << endl;
00116 subject[sbjRegisterSoundManager]->SetData(soundManagerMemRgn);
00117 subject[sbjRegisterSoundManager]->NotifyObservers();
00118 }
00119 }
00120
00121 void
00122 SoundPlay::GotEventTranslatorQueue(const ONotifyEvent& event){
00123 std::cout << "SoundPlay-GOTEventTranslatorQueue..." << std::flush;
00124 ASSERT(event.NumOfData()==1,"Too many EventTranslatorQueue");
00125 eventTranslatorQueueMemRgn = event.RCData(0);
00126 eventTranslatorQueueMemRgn->AddReference();
00127 etrans.setQueue(reinterpret_cast<EventTranslator::Queue_t*>(eventTranslatorQueueMemRgn->Base()));
00128 erouter->addTrapper(&etrans);
00129 observer[obsReceiveEventTranslatorQueue]->AssertReady();
00130 cout << "done" << endl;
00131 }
00132
00133 void
00134 SoundPlay::GotSoundMsg(const ONotifyEvent& event) {
00135
00136 sndman->ReceivedMsg(event);
00137 unsigned int curact=sndman->GetNumPlaying();
00138
00139 if(active==0 && curact>0) {
00140 active=curact;
00141 doSendSound();
00142 }
00143 observer[obsSoundManagerComm]->AssertReady();
00144 }
00145
00146 void
00147 SoundPlay::doSendSound() {
00148
00149 static unsigned int bufInUse=0;
00150
00151 active=sndman->GetNumPlaying();
00152 if(active==0) {
00153 if(bufInUse>0)
00154 bufInUse--;
00155 return;
00156 }
00157
00158 RCRegion* rgn = FindFreeRegion();
00159 if(rgn==NULL)
00160 return;
00161 active=sndman->CopyTo(reinterpret_cast<OSoundVectorData*>(rgn->Base()));
00162 subject[sbjSpeaker]->SetData(rgn);
00163
00164 if(bufInUse<SOUND_NUM_BUFFER-1) {
00165 bufInUse++;
00166 doSendSound();
00167 } else
00168 subject[sbjSpeaker]->NotifyObservers();
00169 }
00170
00171 void
00172 SoundPlay::OpenSpeaker()
00173 {
00174 OStatus result = OPENR::OpenPrimitive(SpeakerLocator, &speakerID);
00175 if (result != oSUCCESS)
00176 OSYSLOG1((osyslogERROR, "%s : %s %d","SoundPlay::OpenSpeaker()","OPENR::OpenPrimitive() FAILED", result));
00177 }
00178
00179 void
00180 SoundPlay::NewSoundVectorData()
00181 {
00182 OStatus result;
00183 MemoryRegionID soundVecDataID;
00184 OSoundVectorData* soundVecData;
00185
00186
00187
00188
00189
00190
00191
00192 size_t soundUnitSize = config->sound.sample_rate*config->sound.sample_bits/8*SoundBufferTime/1000;
00193
00194 for (unsigned int i = 0; i < SOUND_NUM_BUFFER; i++) {
00195 result = OPENR::NewSoundVectorData(1, soundUnitSize,&soundVecDataID, &soundVecData);
00196 if (result != oSUCCESS) {
00197 OSYSLOG1((osyslogERROR, "%s : %s %d","SoundPlay::NewSoundVectorData()","OPENR::NewSoundVectorData() FAILED", result));
00198 return;
00199 }
00200
00201 soundVecData->SetNumData(1);
00202 OSoundInfo* sinfo = soundVecData->GetInfo(0);
00203 sinfo->Set(odataSOUND_VECTOR,speakerID,soundUnitSize);
00204 sinfo->dataSize = soundUnitSize;
00205 sinfo->format = osoundformatPCM;
00206 sinfo->channel = osoundchannelMONO;
00207 sinfo->samplingRate = config->sound.sample_rate;
00208 sinfo->bitsPerSample = config->sound.sample_bits;
00209
00210 region[i] = new RCRegion(soundVecData->vectorInfo.memRegionID,soundVecData->vectorInfo.offset,(void*)soundVecData,soundVecData->vectorInfo.totalSize);
00211 }
00212 }
00213
00214 void
00215 SoundPlay::SetPowerAndVolume()
00216 {
00217 OStatus result;
00218
00219 result = OPENR::ControlPrimitive(speakerID,oprmreqSPEAKER_MUTE_OFF, 0, 0, 0, 0);
00220 if (result != oSUCCESS)
00221 OSYSLOG1((osyslogERROR, "%s : %s %d","SoundPlay::SetPowerAndVolume()","OPENR::ControlPrimitive(SPEAKER_MUTE_OFF) FAILED", result));
00222
00223 OPrimitiveControl_SpeakerVolume volume(config->sound.volume);
00224 result = OPENR::ControlPrimitive(speakerID,oprmreqSPEAKER_SET_VOLUME,&volume, sizeof(volume), 0, 0);
00225 if (result != oSUCCESS)
00226 OSYSLOG1((osyslogERROR, "%s : %s %d","SoundPlay::SetPowerAndVolume()","OPENR::ControlPrimitive(SPEAKER_SET_VOLUME) FAILED",result));
00227
00228 if (config->sound.sample_rate == 16000 && config->sound.sample_bits == 16) {
00229 OPrimitiveControl_SpeakerSoundType soundType(ospksndMONO16K16B);
00230 result = OPENR::ControlPrimitive(speakerID,oprmreqSPEAKER_SET_SOUND_TYPE,&soundType, sizeof(soundType), 0, 0);
00231 if (result != oSUCCESS)
00232 OSYSLOG1((osyslogERROR, "%s : %s %d","SoundPlay::SetPowerAndVolume()","OPENR::ControlPrimitive(SPEAKER_SET_SOUND_TYPE) FAILED",result));
00233 }
00234 }
00235
00236
00237 RCRegion*
00238 SoundPlay::InitRegion(unsigned int size) {
00239 unsigned int pagesize=4096;
00240 sError err=GetPageSize(&pagesize);
00241 ASSERT(err==sSUCCESS,"Error "<<err<<" getting page size");
00242 unsigned int pages=(size+pagesize-1)/pagesize;
00243 return new RCRegion(pages*pagesize);
00244 }
00245
00246 RCRegion*
00247 SoundPlay::FindFreeRegion()
00248 {
00249 for (unsigned int i = 0; i < SOUND_NUM_BUFFER; i++)
00250 if (region[i]->NumberOfReference() == 1)
00251 return region[i];
00252 return 0;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277