197 lines
5.4 KiB
C++
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(¶ms);
|
|
//
|
|
// /* 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;
|
|
} |