void MusicPlayerBlockCode::processLocalEvent(EventPtr pev) {
	stringstream info;
	MessagePtr message;
	BlinkyBlocksBlock *bb = (BlinkyBlocksBlock*) hostBlock;
	info.str("");
	
	OUTPUT << bb->blockId << " processLocalEvent: date: "<< BaseSimulator::getScheduler()->now() << " process event " << pev->getEventName() << "(" << pev->eventType << ")" << ", random number : " << pev->randomNumber << endl;
	
	switch (pev->eventType) {
		case EVENT_PLAY_NOTE:
			{
			int SAMPLES;
			int sleepDuration;
			switch(toPlay[0].timeDiv) {
				case 2:
				SAMPLES=SAMPLES_H;
				sleepDuration=(60000/TEMPO)*2;
				break;
				case 4:
				SAMPLES=SAMPLES_Q;
				sleepDuration=60000/TEMPO;
				break;
				case 6:
				SAMPLES=SAMPLES_DQ;
				sleepDuration=(60000/TEMPO)*1.5;
				break;
				case 8:
				SAMPLES=SAMPLES_E;
				sleepDuration=60000/(2*TEMPO);
				break;
				case 16:
				SAMPLES=SAMPLES_S;
				sleepDuration=60000/(4*TEMPO);
				break;
				default:
				break;
			}
			sf::Int16 raw[SAMPLES];
			const double TWO_PI = 6.28318;
			double increment = toPlay.at(0).frequency/44100;
			double x = 0;
			float rel=toPlay.at(0).startTime;

			for (unsigned i = 0; i < SAMPLES; i++) {
			    raw[i] = AMPLITUDE * sin(x*TWO_PI);
			    x += increment;
			}
			sf::SoundBuffer buffer;	
	 		if (!buffer.loadFromSamples(raw, SAMPLES_Q, 1, SAMPLE_RATE)) {
  				info << "Loading failed!" << endl;
			}
			toPlay.erase(toPlay.begin());
			if (!toPlay.empty()){
				BlinkyBlocks::getScheduler()->schedule(new PlayNoteEvent(bb->getTime()+delay+(60000/TEMPO)*float((toPlay.at(0).startTime-rel)*1000),bb));
				info<<"Note scheduled at: "<<toPlay.at(0).startTime-rel<<endl;
			}
			sf::Sound Sound;
			Sound.setBuffer(buffer);
			Sound.play();
			info<<"note played"<<endl;
			sf::sleep(sf::milliseconds(sleepDuration));//We wait for the note to end 
			Sound.resetBuffer();
			}
			break;
		case EVENT_NI_RECEIVE:
			{
			message = (boost::static_pointer_cast<NetworkInterfaceReceiveEvent>(pev))->message; 
			P2PNetworkInterface * recvInterface = message->destinationInterface;
			switch(message->id){
				case SYNC_MSG_ID: 
					{
					SynchroMessage_ptr recvMessage = boost::static_pointer_cast<SynchroMessage>(message);
					if (!received[recvMessage->idSync]){//If the block didn't already received the sync message of the wave, it synchronizes 
						received[recvMessage->idSync]=true;
						block2Answer=recvInterface;
						sendClockToNeighbors(block2Answer,recvMessage->nbhop+1,recvMessage->time,recvMessage->idSync); 	
						delay = recvMessage->time - bb->getTime() + 6000*recvMessage->nbhop;
						//info<<"synchronized with delay : "<< delay << endl;
						}
					}
					break;
				case SCORE_MSG_ID:
					{
					ScoreMessage_ptr recvMessage = boost::static_pointer_cast<ScoreMessage>(message);
					block2Answer=recvInterface;
					if(!assigned){
						toPlay.push_back(recvMessage->score.at(0)); //We pick the first note, then erase it
						recvMessage->score.erase(recvMessage->score.begin());
						for (std::vector<Note>::iterator it = recvMessage->score.begin() ; it!=recvMessage->score.end() ; ++it){
							if(it->frequency==toPlay[1].frequency){ //as 0 is an empty Note to initialize
								toPlay.push_back(*it);
								recvMessage->score.erase(it);
								it--;
							}
						}
						assigned=true;
					}
					if (!recvMessage->score.empty())
						sendSongToNeighbors(block2Answer,recvMessage->score);
	
					info<<"Note assigned : "<<toPlay[1].frequency<<endl;
					}
					break;					
				default:
					break;
				}
			}
			break;
		case EVENT_SYNC:
			{
			received[idMessage]=true;
			sendClockToNeighbors(NULL,1,bb->getTime(),idMessage);
			idMessage++;
			uint64_t nextSync = bb->getTime()+SYNC_PERIOD;
			BlinkyBlocks::getScheduler()->schedule(new SynchronizeEvent(nextSync,bb));
			info << "scheduled synchro" << endl;
			}
			break;
		default:
			ERRPUT << "*** ERROR *** : unknown local event" << endl;
			break;
		}
		BlinkyBlocks::getScheduler()->trace(info.str(),hostBlock->blockId);
}
Example #2
0
void msrSyncBlockCode::processLocalEvent(EventPtr pev) {
  stringstream info;
  BlinkyBlocksBlock *bb = (BlinkyBlocksBlock*) hostBlock;
  info.str("");
	
  OUTPUT << bb->blockId << " processLocalEvent: date: "<< BaseSimulator::getScheduler()->now() << " process event " << pev->getEventName() << "(" << pev->eventType << ")" << ", random number : " << pev->randomNumber << endl;

  switch (pev->eventType) {
  case EVENT_SET_COLOR:
    {
      Color color = (boost::static_pointer_cast<SetColorEvent>(pev))->color;
      bb->setColor(color);
      info << "set color "<< color << endl;
    }
    break;
  case EVENT_MSRSYNC:
    {
      round++;
      info << "MASTER sync " << round;
#ifdef PRINT_NODE_INFO
      // cout << "MASTER SYNC " << getTime() << endl;
#endif
      synchronize(NULL,getTime());
      // schedule the next sync round
      if (round < LIMIT_NUM_ROUNDS) {
	uint64_t nextSync = hostBlock->getSchedulerTimeForLocalTime(hostBlock->getTime()+SYNC_PERIOD_US);
	//cout << nextSync << " " << BaseSimulator::getScheduler()->now() << endl;
	// or based on global time now ? BaseSimulator::getScheduler()->now()+SYNC_PERIOD
	BlinkyBlocks::getScheduler()->schedule(new MsrSyncEvent(nextSync,hostBlock));
      }
    }
    break;
  case EVENT_NI_RECEIVE:
    {
      MessagePtr message = (boost::static_pointer_cast<NetworkInterfaceReceiveEvent>(pev))->message;
      P2PNetworkInterface * recvInterface = message->destinationInterface;
      switch(message->type) {
      case SYNC_MSG_ID : {
	SyncMessagePtr recvMessage = boost::static_pointer_cast<SyncMessage>(message);
	info << "sync msg " << recvMessage->getRound();
	//cout << "@" << hostBlock->blockId << ": " << getTime() << "/" << globalTime << endl;
	if (recvMessage->getRound() > round) {
	  round = recvMessage->getRound();
	  uint64_t globalTime = recvMessage->getTime() + COM_DELAY_US;
	  uint64_t localTime = hostBlock->getTime();
	  // window of 5 last measures
	  syncPoints.push_back(make_pair(localTime,globalTime));
#ifdef PRINT_NODE_INFO
	  if (hostBlock->blockId == INFO_NODE_ID) {
	    cout << "Reception time: " << BaseSimulator::getScheduler()->now()/1000 << endl;
	    cout <<  "x0= " << x0 << ", y0= " << y0 << endl;
	    cout << "estimation: " << getTime()/1000 << "(" << hostBlock->getTime()/1000 << ")" << ", reception: " << recvMessage->getTime()/1000 << ", => " << globalTime/1000 << endl; 
	  }
#endif
#ifdef PRINT_DATA_2_FILE
	  uint64_t realTime = BaseSimulator::getScheduler()->now();
	  ofstream file;
	  string name = "data/"+to_string(bb->blockId)+".dat";
	  file.open(name.c_str(), fstream::app);
	  file << realTime << " " << globalTime << " " << localTime << " " << getTime() << endl;
	  file.close();
#endif

	  error.push_back(abs(((double)getTime()-(double)globalTime)/1000));
	  if (syncPoints.size() > 5) {
	    syncPoints.erase(syncPoints.begin());
	  }
	  adjust();
#ifdef PRINT_NODE_INFO
	  if (hostBlock->blockId == INFO_NODE_ID) {
	    cout << "@" << hostBlock->blockId << " x0= " << x0 << ", y0= " << y0 << endl;
	  }
#endif
	  synchronize(recvInterface, globalTime);
	  
	  if (round == LIMIT_NUM_ROUNDS) {
	    // display error vector
#ifdef PRINT_NODE_INFO
	    // if (hostBlock->blockId == INFO_NODE_ID) {
	    cout << "@" << hostBlock->blockId << " error: ";
	    for (vector<uint64_t>::iterator it = error.begin() ; it != error.end(); it++){
	      cout << *it << " ";
	    }
	    cout << endl;
	    // }
#endif
	  }
	}
      }
	break;
      default: 
	ERRPUT << "*** ERROR *** : unknown message" << message->id << endl;
      }
    }
    break;
  default:
    ERRPUT << "*** ERROR *** : unknown local event" << endl;
    break;
  }
		
  if (info.str() != "") {
    BlinkyBlocks::getScheduler()->trace(info.str(),hostBlock->blockId);
  }
}