SampleReceiver/main.cpp

197 lines
5.4 KiB
C++

#include <iostream>
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
#include <math.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "src/ALSADevice.h"
#include "src/SampleWriter.h"
#include "src/audio_types.h"
//int main() {
// long loops;
// int rc;
// int size;
// snd_pcm_t *handle;
// snd_pcm_hw_params_t *params;
// unsigned int val;
// int dir;
// snd_pcm_uframes_t frames;
//
// /* Open PCM device for playback. */
// rc = snd_pcm_open(&handle, "default",SND_PCM_STREAM_PLAYBACK, 0);
// if (rc < 0) {
// fprintf(stderr,"unable to open pcm device: %s\n", snd_strerror(rc));
// exit(1);
// }
//
// /* Allocate a hardware parameters object. */
// snd_pcm_hw_params_alloca(&params);
//
// /* Fill it in with default values. */
// snd_pcm_hw_params_any(handle, params);
//
// /* Set the desired hardware parameters. */
//
// /* Interleaved mode */
// snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
//
// /* Signed 16-bit little-endian format */
// snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
//
// /* Two channels (stereo) */
// snd_pcm_hw_params_set_channels(handle, params, 2);
//
// /* 44100 bits/second sampling rate (CD quality) */
// unsigned sampleRate = 44100;
// val = sampleRate;
// snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
//
// /* Set period size to 32 frames. */
// frames = 32;
// snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
//
// /* Write the parameters to the driver */
// rc = snd_pcm_hw_params(handle, params);
// if (rc < 0) {
// fprintf(stderr,"unable to set hw parameters: %s\n", snd_strerror(rc));
// exit(1);
// }
//
// /* Use a buffer large enough to hold one period */
// snd_pcm_hw_params_get_period_size(params, &frames, &dir);
// size = frames * 4; /* 2 bytes/sample, 2 channels */
// int16_t buffer[frames * 2];
//
// /* We want to loop for 5 seconds */
// snd_pcm_hw_params_get_period_time(params, &val, &dir);
// /* 5 seconds in microseconds divided by
// * period time */
//
// loops = 2 * 1000000 / val;
//
// float f = 440;
// float df = 2 * M_PI * f / sampleRate;
// float amplitude = 0.01;
// float phase = 0;
//
// //FILE* wf = fopen("wf.dat", "wb");
//
// for (size_t l = 0; l < loops; l++) {
// for (size_t i = 0; i < 2 * frames; i += 2) {
// buffer[i] = 32767 * amplitude * sin(phase);
// buffer[i+1] = buffer[i];
// phase += df;
// }
//
// //fwrite(buffer, frames * 4, 1, wf);
//
// if (phase > 2 * M_PI) {
// phase -= 2 * M_PI;
// }
//
// std::cout << std::to_string(snd_pcm_avail(handle)) << std::endl;
//
// rc = snd_pcm_writei(handle, buffer, frames);
// if (rc == -EPIPE) {
// /* EPIPE means underrun */
// fprintf(stderr, "underrun occurred\n");
// snd_pcm_prepare(handle);
// } else if (rc < 0) {
// fprintf(stderr, "error from writei: %s\n", snd_strerror(rc));
// } else if (rc != (int) frames) {
// fprintf(stderr, "short write, write %d frames\n", rc);
// }
// }
//
// //fclose(wf);
//
// snd_pcm_drain(handle);
// snd_pcm_close(handle);
// //free(buffer);
//
// return 0;
//}
#define Fs (48000) // sampling frequency
#define F (440) // signal frequency
#define K (0.1) // amplitude
void generate_sine(int16_t *pBuf, uint32_t n) {
double y;
static double phase = 0, dt = 1.0 / Fs;
uint32_t i = 0;
for (i = 0; i < n; i++) {
y = K * 0.5 * (1 + sin(phase));
phase += 2 * M_PI * dt * F;
if (phase > (2 * M_PI)) {
phase -= 2 * M_PI;
}
pBuf[2 * i + 1] = pBuf[2 * i] = ((int16_t) (y * 0x7FFF));
}
}
uint8_t pRecvBuf[8096] __attribute__ ((aligned (32)));
int main(int argc, char * argv[]) {
ALSADevice dev(PERIOD_LEN, SAMPLE_RATE);
MemoryPool<int16_t> pool(STEREO_BUF_LEN, 1000);
//SampleWriter<AudioSampleType> sw(std::string("test_") + argv[1], 2, STEREO_BUF_LEN / 2);
//std::this_thread::sleep_for(std::chrono::seconds(1));
/*for (size_t i = 0; i < 1000; i++) {
auto p = pool.alloc();
generate_sine(p->pBlock, 324);
dev.write(p);
//std::cout << pool.avail() << std::endl;
}
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}*/
int soc = socket(AF_INET, SOCK_DGRAM, 0);
int opt = 1;
setsockopt(soc, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(atoi(argv[1]));
bind(soc, (const sockaddr *)&addr, sizeof(addr));
AudioPayload * pAudioPayload = reinterpret_cast<AudioPayload *>(pRecvBuf);
while (true) {
//while (sw.getSampleCnt() < 100000) {
auto p = pool.alloc();
recv(soc, pRecvBuf, 8096, 0);
//std::cout << pAudioPayload->timestamp_s << ' ' << pAudioPayload->timestamp_ns << std::endl;
Timestamp ts = { pAudioPayload->timestamp_s, pAudioPayload->timestamp_ns };
//sw.addSamples(pAudioPayload->pData, ts);
memcpy(p->pBlock, pAudioPayload->pData, STEREO_BUF_LEN * sizeof(AudioSampleType));
dev.write(p);
//std::cout << pool.avail() << std::endl;
}
close(soc);
return 0;
}