kopia lustrzana https://gitlab.com/eliggett/wfview
First working rtaudio (output only)
rodzic
ae69ef05e5
commit
9c29732376
|
@ -90,7 +90,7 @@ bool audioHandler::init(const quint8 bits, const quint8 channels, const quint16
|
||||||
if (isInput) {
|
if (isInput) {
|
||||||
resampler = wf_resampler_init(radioChannels, INTERNAL_SAMPLE_RATE, samplerate, resampleQuality, &resample_error);
|
resampler = wf_resampler_init(radioChannels, INTERNAL_SAMPLE_RATE, samplerate, resampleQuality, &resample_error);
|
||||||
try {
|
try {
|
||||||
audio.openStream(NULL, &aParams, RTAUDIO_SINT16, INTERNAL_SAMPLE_RATE, &this->chunkSize, &staticWrite);
|
audio.openStream(NULL, &aParams, RTAUDIO_SINT16, INTERNAL_SAMPLE_RATE, &this->chunkSize, &staticWrite, this);
|
||||||
audio.startStream();
|
audio.startStream();
|
||||||
}
|
}
|
||||||
catch (RtAudioError& e) {
|
catch (RtAudioError& e) {
|
||||||
|
@ -103,7 +103,7 @@ bool audioHandler::init(const quint8 bits, const quint8 channels, const quint16
|
||||||
resampler = wf_resampler_init(radioChannels, samplerate, INTERNAL_SAMPLE_RATE, resampleQuality, &resample_error);
|
resampler = wf_resampler_init(radioChannels, samplerate, INTERNAL_SAMPLE_RATE, resampleQuality, &resample_error);
|
||||||
try {
|
try {
|
||||||
unsigned int length = chunkSize / 2;
|
unsigned int length = chunkSize / 2;
|
||||||
audio.openStream(&aParams, NULL, RTAUDIO_SINT16, INTERNAL_SAMPLE_RATE, &length, &staticRead);
|
audio.openStream(&aParams, NULL, RTAUDIO_SINT16, INTERNAL_SAMPLE_RATE, &length, &staticRead, this);
|
||||||
audio.startStream();
|
audio.startStream();
|
||||||
}
|
}
|
||||||
catch (RtAudioError& e) {
|
catch (RtAudioError& e) {
|
||||||
|
@ -137,15 +137,69 @@ int audioHandler::readData(void* outputBuffer, void* inputBuffer, unsigned int n
|
||||||
// Calculate output length, always full samples
|
// Calculate output length, always full samples
|
||||||
int sentlen = 0;
|
int sentlen = 0;
|
||||||
qint16* buffer = (qint16*)outputBuffer;
|
qint16* buffer = (qint16*)outputBuffer;
|
||||||
qDebug(logAudio()) << "looking for: " << nFrames;
|
//qDebug(logAudio()) << "looking for: " << nFrames << this->audioBuffer.size();
|
||||||
|
|
||||||
for (int f = 0; f < nFrames; f++)
|
|
||||||
|
if (!audioBuffer.isEmpty())
|
||||||
{
|
{
|
||||||
qDebug(logAudio()) << "*";
|
|
||||||
|
// Output buffer is ALWAYS 16 bit.
|
||||||
*buffer++ = getBuffer(f);
|
auto packet = audioBuffer.begin();
|
||||||
//*buffer++ = f;
|
|
||||||
|
while (packet != audioBuffer.end() && sentlen < nFrames/2)
|
||||||
|
{
|
||||||
|
int timediff = packet->time.msecsTo(QTime::currentTime());
|
||||||
|
|
||||||
|
if (timediff > (int)audioLatency * 2) {
|
||||||
|
qInfo(logAudio()) << (isInput ? "Input" : "Output") << "Packet " << hex << packet->seq <<
|
||||||
|
" arrived too late (increase output latency!) " <<
|
||||||
|
dec << packet->time.msecsTo(QTime::currentTime()) << "ms";
|
||||||
|
while (packet != audioBuffer.end() && timediff > (int)audioLatency) {
|
||||||
|
timediff = packet->time.msecsTo(QTime::currentTime());
|
||||||
|
lastSeq = packet->seq;
|
||||||
|
packet = audioBuffer.erase(packet); // returns next packet
|
||||||
|
}
|
||||||
|
if (packet == audioBuffer.end()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got here then packet time must be within latency threshold
|
||||||
|
|
||||||
|
if (packet->seq == lastSeq + 1 || packet->seq <= lastSeq)
|
||||||
|
{
|
||||||
|
int send = qMin((int)nFrames*2 - sentlen, packet->dataout.length() - packet->sent);
|
||||||
|
lastSeq = packet->seq;
|
||||||
|
//qInfo(logAudio()) << "Packet " << hex << packet->seq << " arrived on time " << Qt::dec << packet->time.msecsTo(QTime::currentTime()) << "ms";
|
||||||
|
|
||||||
|
memcpy(buffer + sentlen, packet->dataout.constData() + packet->sent, send);
|
||||||
|
|
||||||
|
sentlen = sentlen + send;
|
||||||
|
|
||||||
|
if (send == packet->dataout.length() - packet->sent)
|
||||||
|
{
|
||||||
|
//qInfo(logAudio()) << "Get next packet";
|
||||||
|
packet = audioBuffer.erase(packet); // returns next packet
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Store sent amount (could be zero if audioOutput buffer full) then break.
|
||||||
|
packet->sent = send;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qInfo(logAudio()) << (isInput ? "Input" : "Output") << "Missing audio packet(s) from: " << hex << lastSeq + 1 << " to " << hex << packet->seq - 1;
|
||||||
|
lastSeq = packet->seq;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Fool audio system into thinking it has valid data, this seems to be required
|
||||||
|
// for MacOS Built in audio but shouldn't cause any issues with other platforms.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +278,11 @@ void audioHandler::stateChanged(QAudio::State state)
|
||||||
|
|
||||||
void audioHandler::incomingAudio(audioPacket data)
|
void audioHandler::incomingAudio(audioPacket data)
|
||||||
{
|
{
|
||||||
|
// No point buffering audio until stream is actually running.
|
||||||
|
if (!audio.isStreamRunning())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Incoming data is 8bits?
|
// Incoming data is 8bits?
|
||||||
if (radioSampleBits == 8)
|
if (radioSampleBits == 8)
|
||||||
{
|
{
|
||||||
|
@ -245,7 +303,7 @@ void audioHandler::incomingAudio(audioPacket data)
|
||||||
data.datain = inPacket; // Replace incoming data with converted.
|
data.datain = inPacket; // Replace incoming data with converted.
|
||||||
}
|
}
|
||||||
|
|
||||||
qInfo(logAudio()) << "Adding packet to buffer:" << data.seq << ": " << data.datain.length();
|
//qInfo(logAudio()) << "Adding packet to buffer:" << data.seq << ": " << data.datain.length();
|
||||||
|
|
||||||
/* We now have an array of 16bit samples in the NATIVE samplerate of the radio
|
/* We now have an array of 16bit samples in the NATIVE samplerate of the radio
|
||||||
If the radio sample rate is below 48000, we need to resample.
|
If the radio sample rate is below 48000, we need to resample.
|
||||||
|
@ -273,9 +331,9 @@ void audioHandler::incomingAudio(audioPacket data)
|
||||||
data.dataout = data.datain;
|
data.dataout = data.datain;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buf, data.dataout.constData(), data.dataout.length());
|
//memcpy(buf, data.dataout.constData(), data.dataout.length());
|
||||||
qDebug(logAudio()) << "Got data: " << data.dataout.length();
|
//qDebug(logAudio()) << "Got data: " << data.dataout.length();
|
||||||
//audioBuffer.insert({ data.seq, data });
|
audioBuffer.insert( data.seq, data );
|
||||||
}
|
}
|
||||||
|
|
||||||
void audioHandler::changeLatency(const quint16 newSize)
|
void audioHandler::changeLatency(const quint16 newSize)
|
||||||
|
|
|
@ -834,7 +834,7 @@ private:
|
||||||
|
|
||||||
quint16 *buf;
|
quint16 *buf;
|
||||||
|
|
||||||
std::map<quint32, audioPacket>audioBuffer;
|
QMap<quint32, audioPacket>audioBuffer;
|
||||||
|
|
||||||
unsigned int ratioNum;
|
unsigned int ratioNum;
|
||||||
unsigned int ratioDen;
|
unsigned int ratioDen;
|
||||||
|
|
Ładowanie…
Reference in New Issue