diff --git a/audiohandler.cpp b/audiohandler.cpp index 5edec5a..fcf126c 100644 --- a/audiohandler.cpp +++ b/audiohandler.cpp @@ -99,9 +99,10 @@ bool audioHandler::init(const quint8 bits, const quint8 channels, const quint16 if (isInitialized) { return false; } - format.setSampleSize(bits); + /* Always use 16 bit 48K samples internally*/ + format.setSampleSize(16); format.setChannelCount(channels); - format.setSampleRate(samplerate); + format.setSampleRate(48000); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); @@ -109,6 +110,8 @@ bool audioHandler::init(const quint8 bits, const quint8 channels, const quint16 this->bufferSize = buffer; this->isUlaw = ulaw; this->isInput = isinput; + this->radioSampleBits = bits; + this->radioSampleRate = samplerate; if (isInput) isInitialized = setDevice(QAudioDeviceInfo::defaultInputDevice()); @@ -272,15 +275,26 @@ qint64 audioHandler::readData(char* data, qint64 maxlen) qToLittleEndian(uLawDecode(buffer.at(f)), data + f * 2); } buffer.remove(0, outlen); - outlen = outlen * 2; + outlen = outlen * 2; } else { - // Just copy it. - outlen = qMin(buffer.length(), (int)maxlen); - if (outlen % 2 != 0) { - outlen += 1; + if (radioSampleBits == 8) + { + outlen = qMin(buffer.length(), (int)maxlen/2); + for (int f = 0; f < outlen; f++) + { + qToLittleEndian((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); } @@ -289,20 +303,26 @@ qint64 audioHandler::readData(char* data, qint64 maxlen) qint64 audioHandler::writeData(const char* data, qint64 len) { + int chunkSize = 960; // Assume 8bit or uLaw. if (isUlaw) { for (int f = 0; f < len / 2; f++) { buffer.append(uLawEncode(qFromLittleEndian(data + f * 2))); } } - else { - buffer.append(QByteArray::fromRawData(data, len)); + else if (radioSampleBits == 8) { + for (int f = 0; f < len / 2; f++) + { + buffer.append((quint8)(((qFromLittleEndian(data + f * 2) >> 8) ^ 0x80) & 0xff)); + } } - int chunkSize = 960; - if (format.sampleSize() == 16 && !isUlaw) - { + else if (radioSampleBits == 16) { + buffer.append(QByteArray::fromRawData(data, len)); chunkSize = 1920; } + else { + qWarning() << "Unsupported number of bits! :" << radioSampleBits; + } while (buffer.length() >= chunkSize) { diff --git a/audiohandler.h b/audiohandler.h index a9da84a..9bac97a 100644 --- a/audiohandler.h +++ b/audiohandler.h @@ -70,6 +70,8 @@ private: QByteArray buffer; QAudioFormat format; QAudioDeviceInfo deviceInfo; + quint16 radioSampleRate; + quint8 radioSampleBits; }; diff --git a/udphandler.cpp b/udphandler.cpp index 0fef728..0dafc60 100644 --- a/udphandler.cpp +++ b/udphandler.cpp @@ -298,18 +298,6 @@ void udpHandler::DataReceived() 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); 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); - 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; - if (rxCodec == 0x08 || rxCodec == 0x10 || rxCodec == 0x20) + } + if (rxCodec == 0x08 || rxCodec == 0x10 || rxCodec == 0x20) { rxChannelCount = 2; - if (rxCodec == 0x02 || rxCodec == 0x8) - rxNumSamples = 8; // uLaw is actually 16bit. + } + if (rxCodec == 0x04 || rxCodec == 0x10) { + rxNumSamples = 16; + } rxaudio = new audioHandler(); rxAudioThread = new QThread(this); @@ -588,8 +590,8 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 aport, quint16 b if (txCodec == 0x01) txIsUlawCodec = true; - else if (txCodec == 0x02) - txNumSamples = 8; // uLaw is actually 16bit. + else if (txCodec == 0x04) + txNumSamples = 16; txChannelCount = 1; // Only 1 channel is supported. diff --git a/udphandler.h b/udphandler.h index 164097b..4beeea9 100644 --- a/udphandler.h +++ b/udphandler.h @@ -145,10 +145,10 @@ private: quint8 txCodec; quint8 rxChannelCount = 1; bool rxIsUlawCodec = false; - quint8 rxNumSamples = 16; + quint8 rxNumSamples = 8; quint8 txChannelCount = 1; bool txIsUlawCodec = false; - quint8 txNumSamples = 16; + quint8 txNumSamples = 8; bool sentPacketConnect2 = false; uint16_t sendAudioSeq = 0;