// // Weather update client in C++ // Connects SUB socket to tcp://localhost:5556 // Collects weather updates and finds avg temp in zipcode // // Olivier Chamoux // #include #include #include #include #include #include #include #include #include #include #include #include #include "chunk.h" #include "stream.h" #include "zhelpers.hpp" using namespace std; int bufferMs; int deviceIdx; Stream* stream; void player() { zmq::context_t context (1); zmq::socket_t subscriber (context, ZMQ_SUB); subscriber.connect("tcp://192.168.0.2:123458"); const char* filter = ""; subscriber.setsockopt(ZMQ_SUBSCRIBE, filter, strlen(filter)); zmq::message_t update; while (1) { subscriber.recv(&update); stream->addChunk((Chunk*)(update.data())); } } std::string getMacAddress() { std::ifstream t("/sys/class/net/eth0/address"); std::string str((std::istreambuf_iterator(t)), std::istreambuf_iterator()); str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::ptr_fun(std::isspace))).base(), str.end()); return str; } void control(Stream* stream) { zmq::context_t context(1); zmq::socket_t worker (context, ZMQ_REQ); srand (time(NULL)); // We use a string identity for ease here string macAddress = getMacAddress(); worker.setsockopt(ZMQ_IDENTITY, macAddress.c_str(), macAddress.length()); worker.connect("tcp://192.168.0.2:123459"); // Tell the router we're ready for work s_send (worker, "ready"); while (1) { std::string cmd = s_recv (worker); istringstream iss(cmd); vector splitCmd; copy(istream_iterator(iss), istream_iterator(), back_inserter >(splitCmd)); for (size_t n=0; n 1) { if (splitCmd[0] == "buffer") stream->setBufferLen(atoi(splitCmd[1].c_str())); } s_send(worker, "ACK " + cmd); } } /* This routine will be called by the PortAudio engine when audio is needed. ** It may called at interrupt level on some machines so don't do anything ** that could mess up the system like calling malloc() or free(). */ static int patestCallback( const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ) { Stream* stream = (Stream*)userData; short* out = (short*)outputBuffer; (void) timeInfo; /* Prevent unused variable warnings. */ (void) statusFlags; (void) inputBuffer; stream->getChunk(out, timeInfo->outputBufferDacTime, framesPerBuffer); return paContinue; } int initAudio() { PaStreamParameters outputParameters; PaStream *paStream; PaError err; printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); err = Pa_Initialize(); if( err != paNoError ) goto error; int numDevices; numDevices = Pa_GetDeviceCount(); if( numDevices < 0 ) { printf( "ERROR: Pa_CountDevices returned 0x%x\n", numDevices ); err = numDevices; goto error; } const PaDeviceInfo *deviceInfo; for(int i=0; iname << "\n"; } outputParameters.device = deviceIdx==-1?Pa_GetDefaultOutputDevice():deviceIdx; /* default output device */ std::cerr << "Using Device: " << outputParameters.device << "\n"; if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); goto error; } outputParameters.channelCount = CHANNELS; /* stereo output */ outputParameters.sampleFormat = paInt16; /* 32 bit floating point output */ outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream( &paStream, NULL, /* no input */ &outputParameters, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, /* we won't output out of range samples so don't bother clipping them */ patestCallback, stream ); if( err != paNoError ) goto error; err = Pa_StartStream( paStream ); if( err != paNoError ) goto error; // err = Pa_StopStream( paStream ); // if( err != paNoError ) goto error; // err = Pa_CloseStream( paStream ); // if( err != paNoError ) goto error; // Pa_Terminate(); // printf("Test finished.\n"); return err; error: Pa_Terminate(); fprintf( stderr, "An error occured while using the portaudio stream\n" ); fprintf( stderr, "Error number: %d\n", err ); fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); return err; } int main (int argc, char *argv[]) { deviceIdx = -1; bufferMs = 300; if (argc > 1) bufferMs = atoi(argv[1]); if (argc > 2) deviceIdx = atoi(argv[2]); stream = new Stream(); stream->setBufferLen(bufferMs); initAudio(); std::thread playerThread(player); /* std::string cmd; while (true && (argc > 3)) { std::cout << "> "; std::getline(std::cin, cmd); // line = fgets( str, 256, stdin ); // if (line == NULL) // continue; // std::string cmd(line); std::cerr << "CMD: " << cmd << "\n"; if (cmd == "quit") break; else { stream->setBufferLen(atoi(cmd.c_str())); } } */ std::thread controlThread(control, stream); // controlThread.join(); playerThread.join(); return 0; }