SDRPlusPlus/src/io/audio.h
2020-08-04 21:34:56 +02:00

90 lines
2.8 KiB
C++

#pragma once
#include <thread>
#include <dsp/stream.h>
#include <dsp/types.h>
#include <fstream>
#include <portaudio.h>
#include <spdlog/spdlog.h>
namespace io {
class AudioSink {
public:
AudioSink() {
}
AudioSink(dsp::stream<float>* in, int bufferSize) {
_bufferSize = bufferSize;
_input = in;
buffer = new float[_bufferSize * 2];
_volume = 1.0f;
Pa_Initialize();
}
void init(dsp::stream<float>* in, int bufferSize) {
_bufferSize = bufferSize;
_input = in;
buffer = new float[_bufferSize * 2];
_volume = 1.0f;
Pa_Initialize();
}
void setVolume(float volume) {
_volume = volume;
}
void start() {
PaStreamParameters outputParams;
outputParams.channelCount = 2;
outputParams.sampleFormat = paFloat32;
outputParams.hostApiSpecificStreamInfo = NULL;
outputParams.device = Pa_GetDefaultOutputDevice();
outputParams.suggestedLatency = Pa_GetDeviceInfo(outputParams.device)->defaultLowOutputLatency;
PaError err = Pa_OpenStream(&stream, NULL, &outputParams, 48000.0f, _bufferSize, paClipOff, _callback, this);
if (err != 0) {
spdlog::error("Error while opening audio stream: ({0}) => {1}", err, Pa_GetErrorText(err));
return;
}
err = Pa_StartStream(stream);
if (err != 0) {
spdlog::error("Error while starting audio stream: ({0}) => {1}", err, Pa_GetErrorText(err));
return;
}
spdlog::info("Audio device open.");
}
void stop() {
Pa_CloseStream(stream);
}
void setBlockSize(int blockSize) {
stop();
_bufferSize = blockSize;
start();
}
private:
static int _callback(const void *input,
void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, void *userData ) {
AudioSink* _this = (AudioSink*)userData;
float* outbuf = (float*)output;
_this->_input->read(_this->buffer, frameCount);
float vol = powf(_this->_volume, 2);
for (int i = 0; i < frameCount; i++) {
outbuf[(i * 2) + 0] = _this->buffer[i] * vol;
outbuf[(i * 2) + 1] = _this->buffer[i] * vol;
}
return 0;
}
int _bufferSize;
dsp::stream<float>* _input;
float* buffer;
float _volume;
PaStream *stream;
};
};