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