Always use 16bit samples internally

merge-requests/2/head
Phil Taylor 2021-02-12 14:28:55 +00:00
rodzic 518b70c0e6
commit dc151f5268
4 zmienionych plików z 57 dodań i 33 usunięć

Wyświetl plik

@ -99,9 +99,10 @@ bool audioHandler::init(const quint8 bits, const quint8 channels, const quint16
if (isInitialized) { if (isInitialized) {
return false; return false;
} }
format.setSampleSize(bits); /* Always use 16 bit 48K samples internally*/
format.setSampleSize(16);
format.setChannelCount(channels); format.setChannelCount(channels);
format.setSampleRate(samplerate); format.setSampleRate(48000);
format.setCodec("audio/pcm"); format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian); format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt); format.setSampleType(QAudioFormat::SignedInt);
@ -109,6 +110,8 @@ bool audioHandler::init(const quint8 bits, const quint8 channels, const quint16
this->bufferSize = buffer; this->bufferSize = buffer;
this->isUlaw = ulaw; this->isUlaw = ulaw;
this->isInput = isinput; this->isInput = isinput;
this->radioSampleBits = bits;
this->radioSampleRate = samplerate;
if (isInput) if (isInput)
isInitialized = setDevice(QAudioDeviceInfo::defaultInputDevice()); isInitialized = setDevice(QAudioDeviceInfo::defaultInputDevice());
@ -272,15 +275,26 @@ qint64 audioHandler::readData(char* data, qint64 maxlen)
qToLittleEndian<qint16>(uLawDecode(buffer.at(f)), data + f * 2); qToLittleEndian<qint16>(uLawDecode(buffer.at(f)), data + f * 2);
} }
buffer.remove(0, outlen); buffer.remove(0, outlen);
outlen = outlen * 2; outlen = outlen * 2;
} }
else { else {
// Just copy it. if (radioSampleBits == 8)
outlen = qMin(buffer.length(), (int)maxlen); {
if (outlen % 2 != 0) { outlen = qMin(buffer.length(), (int)maxlen/2);
outlen += 1; for (int f = 0; f < outlen; f++)
{
qToLittleEndian<qint16>((qint16)(buffer[f]<<8) - 32640, data + f * 2);
}
buffer.remove(0, outlen);
outlen = outlen * 2;
} else {
// Just copy it.
outlen = qMin(buffer.length(), (int)maxlen);
if (outlen % 2 != 0) {
outlen += 1;
}
memcpy(data, buffer.data(), outlen);
} }
memcpy(data, buffer.data(), outlen);
buffer.remove(0, outlen); buffer.remove(0, outlen);
} }
@ -289,20 +303,26 @@ qint64 audioHandler::readData(char* data, qint64 maxlen)
qint64 audioHandler::writeData(const char* data, qint64 len) qint64 audioHandler::writeData(const char* data, qint64 len)
{ {
int chunkSize = 960; // Assume 8bit or uLaw.
if (isUlaw) { if (isUlaw) {
for (int f = 0; f < len / 2; f++) for (int f = 0; f < len / 2; f++)
{ {
buffer.append(uLawEncode(qFromLittleEndian<qint16>(data + f * 2))); buffer.append(uLawEncode(qFromLittleEndian<qint16>(data + f * 2)));
} }
} }
else { else if (radioSampleBits == 8) {
buffer.append(QByteArray::fromRawData(data, len)); for (int f = 0; f < len / 2; f++)
{
buffer.append((quint8)(((qFromLittleEndian<qint16>(data + f * 2) >> 8) ^ 0x80) & 0xff));
}
} }
int chunkSize = 960; else if (radioSampleBits == 16) {
if (format.sampleSize() == 16 && !isUlaw) buffer.append(QByteArray::fromRawData(data, len));
{
chunkSize = 1920; chunkSize = 1920;
} }
else {
qWarning() << "Unsupported number of bits! :" << radioSampleBits;
}
while (buffer.length() >= chunkSize) while (buffer.length() >= chunkSize)
{ {

Wyświetl plik

@ -70,6 +70,8 @@ private:
QByteArray buffer; QByteArray buffer;
QAudioFormat format; QAudioFormat format;
QAudioDeviceInfo deviceInfo; QAudioDeviceInfo deviceInfo;
quint16 radioSampleRate;
quint8 radioSampleBits;
}; };

Wyświetl plik

@ -298,18 +298,6 @@ void udpHandler::DataReceived()
qint64 udpHandler::SendRequestSerialAndAudio() qint64 udpHandler::SendRequestSerialAndAudio()
{ {
/*
0x72 is RX audio codec
0x73 is TX audio codec (only single channel options)
0x01 uLaw 1ch 8bit
0x02 PCM 1ch 8bit
0x04 PCM 1ch 16bit
0x08 PCM 2ch 8bit
0x10 PCM 2ch 16bit
0x20 uLaw 2ch 8bit
*/
quint8* usernameEncoded = Passcode(username); quint8* usernameEncoded = Passcode(username);
int txSeqBufLengthMs = 50; int txSeqBufLengthMs = 50;
@ -569,12 +557,26 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 aport, quint16 b
QUdpSocket::connect(udp, &QUdpSocket::readyRead, this, &udpAudio::DataReceived); QUdpSocket::connect(udp, &QUdpSocket::readyRead, this, &udpAudio::DataReceived);
if (rxCodec == 0x01 || rxCodec == 0x20) /*
0x72 is RX audio codec
0x73 is TX audio codec (only single channel options)
0x01 uLaw 1ch 8bit
0x02 PCM 1ch 8bit
0x04 PCM 1ch 16bit
0x08 PCM 2ch 8bit
0x10 PCM 2ch 16bit
0x20 uLaw 2ch 8bit
*/
if (rxCodec == 0x01 || rxCodec == 0x20) {
rxIsUlawCodec = true; rxIsUlawCodec = true;
if (rxCodec == 0x08 || rxCodec == 0x10 || rxCodec == 0x20) }
if (rxCodec == 0x08 || rxCodec == 0x10 || rxCodec == 0x20) {
rxChannelCount = 2; rxChannelCount = 2;
if (rxCodec == 0x02 || rxCodec == 0x8) }
rxNumSamples = 8; // uLaw is actually 16bit. if (rxCodec == 0x04 || rxCodec == 0x10) {
rxNumSamples = 16;
}
rxaudio = new audioHandler(); rxaudio = new audioHandler();
rxAudioThread = new QThread(this); rxAudioThread = new QThread(this);
@ -588,8 +590,8 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 aport, quint16 b
if (txCodec == 0x01) if (txCodec == 0x01)
txIsUlawCodec = true; txIsUlawCodec = true;
else if (txCodec == 0x02) else if (txCodec == 0x04)
txNumSamples = 8; // uLaw is actually 16bit. txNumSamples = 16;
txChannelCount = 1; // Only 1 channel is supported. txChannelCount = 1; // Only 1 channel is supported.

Wyświetl plik

@ -145,10 +145,10 @@ private:
quint8 txCodec; quint8 txCodec;
quint8 rxChannelCount = 1; quint8 rxChannelCount = 1;
bool rxIsUlawCodec = false; bool rxIsUlawCodec = false;
quint8 rxNumSamples = 16; quint8 rxNumSamples = 8;
quint8 txChannelCount = 1; quint8 txChannelCount = 1;
bool txIsUlawCodec = false; bool txIsUlawCodec = false;
quint8 txNumSamples = 16; quint8 txNumSamples = 8;
bool sentPacketConnect2 = false; bool sentPacketConnect2 = false;
uint16_t sendAudioSeq = 0; uint16_t sendAudioSeq = 0;