Commit d40c7145 authored by Your Name's avatar Your Name
Browse files

more zmqaudio.cc

parent cb247ef4
No preview for this file type
// //
// zmqaudio.cc -- play audio samples received over zeromq sockets // zmqaudio.cc -- play audio samples received over zeromq sockets
// Copyright (c) 2020 Günter Winau // Copyright (c) 2020 Günter Winau
// based on the example in paex_sine.c // based on the example in paex_sine.c
// //
// //
...@@ -42,9 +42,9 @@ ...@@ -42,9 +42,9 @@
#include "zmqaudio.h" #include "zmqaudio.h"
#include "portaudio.h" #include "portaudio.h"
#include "zhelpers.hpp" #include "zhelpers.hpp"
#include <iostream>
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <iostream>
#define NUM_SECONDS (5) #define NUM_SECONDS (5)
#define SAMPLE_RATE (44100) #define SAMPLE_RATE (44100)
...@@ -61,23 +61,22 @@ typedef struct { ...@@ -61,23 +61,22 @@ typedef struct {
char message[20]; char message[20];
} paTestData; } paTestData;
int verbose = 0; int verbose = 1;
const int nbuf = 5; const int nrbuffers = 5;
zmq_audiobuffer *buffer[nbuf]; zmq_audiobuffer *buffer[nrbuffers];
zmq_audiobuffer::zmq_audiobuffer(std::uint32_t _fsamp, std::uint32_t _nsamp, zmq_audiobuffer::zmq_audiobuffer(std::uint32_t _fsamp, std::uint32_t _nsamp,
std::uint32_t _nchan) std::uint32_t _nchan)
: fsamp{_fsamp}, nsamp{_nsamp}, nchan{_nchan}, : fsamp{_fsamp}, nsamp{_nsamp}, nchan{_nchan},
data{new float[_nsamp * _nchan]}, idata{0}, frames_per_buffer{64}, data{new float[_nsamp * _nchan]}, idata{0},
playing{false}, stream{nullptr} frames_per_buffer{64}, playing{false}, stream{nullptr} {
{
assert(sizeof(float) == 4); // need 32 bit IEEE 754 floats assert(sizeof(float) == 4); // need 32 bit IEEE 754 floats
PaStreamParameters outputParameters; PaStreamParameters outputParameters;
outputParameters.device = outputParameters.device =
Pa_GetDefaultOutputDevice(); /* default output device */ Pa_GetDefaultOutputDevice(); /* default output device */
if (outputParameters.device == paNoDevice) { if (outputParameters.device == paNoDevice) {
fprintf(stderr, "Error: No default output device.\n"); fprintf(stderr, "Error: No default output device.\n");
return 1; return;
} }
outputParameters.channelCount = nchan; /* stereo output */ outputParameters.channelCount = nchan; /* stereo output */
outputParameters.sampleFormat = outputParameters.sampleFormat =
...@@ -93,18 +92,15 @@ zmq_audiobuffer::zmq_audiobuffer(std::uint32_t _fsamp, std::uint32_t _nsamp, ...@@ -93,18 +92,15 @@ zmq_audiobuffer::zmq_audiobuffer(std::uint32_t _fsamp, std::uint32_t _nsamp,
don't bother clipping them */ don't bother clipping them */
zmq_audiobuffer::stream_callback, this); zmq_audiobuffer::stream_callback, this);
if (err != paNoError) if (err != paNoError)
return err; return;
} }
zmq_audiobuffer::~zmq_audiobuffer() zmq_audiobuffer::~zmq_audiobuffer() {
{
delete data; delete data;
Pa_StopStream(stream); Pa_StopStream(stream);
Pa_CloseStream(stream); Pa_CloseStream(stream);
} }
/* This routine will be called by the PortAudio engine when audio is needed. /* 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 ** 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(). ** that could mess up the system like calling malloc() or free().
...@@ -148,7 +144,7 @@ int zmq_audiobuffer::play() { ...@@ -148,7 +144,7 @@ int zmq_audiobuffer::play() {
idata = 0; idata = 0;
sprintf(message, "No Message"); sprintf(message, "No Message");
err = int err =
Pa_SetStreamFinishedCallback(stream, &zmq_audiobuffer::stream_finished); Pa_SetStreamFinishedCallback(stream, &zmq_audiobuffer::stream_finished);
if (err != paNoError) if (err != paNoError)
return err; return err;
...@@ -158,17 +154,14 @@ int zmq_audiobuffer::play() { ...@@ -158,17 +154,14 @@ int zmq_audiobuffer::play() {
return err; return err;
playing = true; playing = true;
//printf("Play for %d seconds.\n", NUM_SECONDS); // printf("Play for %d seconds.\n", NUM_SECONDS);
//Pa_Sleep((unsigned int)(duration() * 1000)); // Pa_Sleep((unsigned int)(duration() * 1000));
return paNoError;
} }
void zmq_audiobuffer::abort() { void zmq_audiobuffer::abort() { Pa_AbortStream(stream); }
Pa_AbortStream(stream);
}
void zmq_audiobuffer::stop() { void zmq_audiobuffer::stop() { Pa_StopStream(stream); }
Pa_StopStream(stream);
}
void zmq_audiobuffer::fill() { void zmq_audiobuffer::fill() {
// initialise sinusoidal wavetable // initialise sinusoidal wavetable
...@@ -206,14 +199,15 @@ int zmq_recv_multi(zmq::socket_t &socket, zmq::message_t parts[], int nmax) { ...@@ -206,14 +199,15 @@ int zmq_recv_multi(zmq::socket_t &socket, zmq::message_t parts[], int nmax) {
zmq::message_t discard; zmq::message_t discard;
socket.recv(&discard); socket.recv(&discard);
if (verbose) if (verbose)
std::cout << "recv part " << n << " (discarded)." << std::endl; std::cout << "recv part " << n << " (discarded)."
<< std::endl;
} }
socket.getsockopt(ZMQ_RCVMORE, &more, &more_size); socket.getsockopt(ZMQ_RCVMORE, &more, &more_size);
} while (more); } while (more);
} }
catch (std::exception &error) { catch (std::exception &error) {
std::cout << "zmq_rev_multi while receiving frame " << n << ": " std::cout << "zmq_rev_multi while receiving frame " << n << ": "
<< error.what() << std::endl; << error.what() << std::endl;
} }
return n; return n;
} }
...@@ -229,9 +223,9 @@ int main(void) { ...@@ -229,9 +223,9 @@ int main(void) {
zmq::context_t context(1); zmq::context_t context(1);
zmq::socket_t ssub(context, ZMQ_SUB); zmq::socket_t ssub(context, ZMQ_SUB);
ssub.connect("tcp://lsldert00:5557"); ssub.connect("tcp://raspi6.local:5557");
// ssub.connect("tcp://lsldert00.local:5557"); // ssub.connect("tcp://lsldert00.local:5557");
ssub.setsockopt(ZMQ_SUBSCRIBE, "A", 0); ssub.setsockopt(ZMQ_SUBSCRIBE, "A", 1);
int run = 1; int run = 1;
while (run) { while (run) {
...@@ -243,38 +237,36 @@ int main(void) { ...@@ -243,38 +237,36 @@ int main(void) {
zmq::message_t &request = msg[0]; zmq::message_t &request = msg[0];
std::string str((char *)request.data()); std::string str((char *)request.data());
if (verbose) { if (verbose) {
std::cout << "Received: " << str << " (" << request.size() std::cout << "Received: '" << str << "' (" << request.size()
<< " bytes)" << std::endl; << " bytes)" << std::endl;
if (nmsg > 1) { if (nmsg > 1) {
for (int i = 1; i < nmsg; i++) for (int i = 1; i < nmsg; i++)
std::cout << " ...one more message, " << msg[i].size() std::cout << " ...one more message, " << msg[i].size()
<< " bytes" << std::endl; << " bytes" << std::endl;
}
} }
}
// parse the command and data in the message // parse the command and data in the message
std::istringstream s(str); std::istringstream s(str);
std::string cmd; std::string cmd;
s >> cmd; unsigned int ibuf;
s >> cmd >> ibuf;
if (verbose)
std::cout << "cmd=" << str << std::endl;
if (cmd == "AF") { // Fill
}
else if (cmd == "AP") { // Play
} if (verbose)
else if (cmd == "AS") { // Stop std::cout << "cmd='" << cmd << "' ibuf=" << ibuf << std::endl;
if (ibuf >= nrbuffers) {
std::cerr << "buffer index out of range" << std::endl;
continue;
}
} if (cmd == "AF") { // Fill
}
else if (cmd == "AP") { // Play
}
else if (cmd == "AS") { // Stop
}
buffer[0] = new zmq_audiobuffer(44100, 5 * 48000, 2); buffer[0] = new zmq_audiobuffer(44100, 5 * 48000, 2);
zmq_audiobuffer *data = buffer[0]; zmq_audiobuffer *data = buffer[0];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment