QAudioOutput doesn't work correctly. I hear only noise - c++

my program capture raw data from microphone in QT.
QAudioRecorder* recorder = new QAudioRecorder();
QAudioProbe* probe = new QAudioProbe;
connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer)));
QAudioEncoderSettings audioSettings;
audioSettings.setCodec("audio/mpeg");
audioSettings.setQuality(QMultimedia::HighQuality);
recorder->setEncodingSettings(audioSettings);
qDebug() << "probe ritorna " << probe->setSource(recorder); // Returns true, hopefully.
//qDebug() << "" << recorder->setOutputLocation(QUrl::fromLocalFile("test"));
recorder->record(); // Now we can do things like calculating levels or performing an FFT
myAudioServer = new MyAudioServer();
myAudioServer->startServer();
In previous code I record audio and I start a Qthread for send audio via QTcpSocket.
void QtVideoWidgetsIssueTrack::processBuffer(const QAudioBuffer& buffer){
QByteArray byteArr;
byteArr.append(buffer.constData<char>(), buffer.byteCount());
QByteArray Data = byteArr;
qDebug() << myAudioServer->isListening();
QTcpSocket* myAudioClient = myAudioServer->getSocket();
qDebug() << myAudioClient;
qDebug() << "in processBuffer";
if (myAudioClient != nullptr) {
myAudioClient->write(Data, Data.count());
myAudioClient->waitForBytesWritten();
}
}
The method processBuffer take data from microphone and send it from server to client.
void MyThreadAudioTcpSocket::readyRead()
{
while (socket->bytesAvailable() > 0) {
//fare il play da QByteArray
// get default output device
QByteArray* yourSoundData = new QByteArray(socket->readAll());
QBuffer* buffer = new QBuffer;
buffer->setData(yourSoundData->data(),yourSoundData->size());
buffer->open(QBuffer::ReadOnly);
QAudioFormat format;
format.setSampleSize(16);
format.setSampleRate(22050);
format.setChannelCount(1);
format.setCodec("audio/mpeg");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
if (!info.isFormatSupported(format)) {
format = info.nearestFormat(format);
qDebug() << "formato non supportato";
}
QAudioOutput *output = new QAudioOutput(format);
output->moveToThread(this);
output->start(buffer);
}
}
readyRead is where data arrive from socket server. I read all data from socket, I put it in Buffer, set QAudioFormat and I create QAudioOutput linked buffer and start.
Now as you can hear from this link wav file QAudioOutput produce only noise. Why?

Related

how to transfer QImage from QLocalServer to QLocalSocket

I have two mac apps that communicate with each other using QLocalSocket.
Able to send the received QString but not able to send the received QImage Below is my code.
SERVER SIDE CODE
QImage image(":/asset/logo_active.png");
QByteArray ba;
qDebug() << image.sizeInBytes() <<image.size();
ba.append((char *)image.bits(),image.sizeInBytes());
qDebug() <<ba.size(); //262144
this->mSocket->write(ba);
if(!this->mSocket->waitForBytesWritten(-1))
{
qDebug() << "writen Bytes error " << this->mSocket->errorString();
}
this->mSocket->flush();
CLIENT SIDE CODE
connect(mLocalSocket,&QLocalSocket::readyRead, [&]() {
QByteArray ba;
ba = mLocalSocket->readAll();
qDebug() << "size is" << ba.size(); // size is 0
QImage image((uchar *)ba.data(),1024,768,QImage::Format_RGB32);
ui->labelStream->setPixmap(QPixmap::fromImage(img));
});
at sender 262144 is the byte-array size
but at the receiver, byte-array size is 0
Do let me know if I am missing anything.
Thanks In Advance
Finally I got the solutions I used QDataStream below is the code example.
SERVER SIDE CODE:
QDataStream T(mSocket);
T.setVersion(QDataStream::Qt_5_7);
QByteArray ba;
ba.append((char *)img.bits(),img.sizeInBytes());
T << ba;
mSocket->flush();
CLIENT SIDE CODE
QByteArray jsonData;
QDataStream socketStream(mLocalSocket);
socketStream.setVersion(QDataStream::Qt_5_7);
for (;;) {
socketStream.startTransaction();
socketStream >> jsonData;
if (socketStream.commitTransaction()) {
QImage image((uchar *)jsonData.data(),640,480,QImage::Format_RGB888);
ui->labelStream->setPixmap(QPixmap::fromImage(image));
}else {
// the read failed, the socket goes automatically back to the state it was in before the transaction started
// we just exit the loop and wait for more data to become available
break;
}
}
Thanks, Everyone for your support also Stackoverflow.

QSerialPort readings refresh too fast for the Qt widget

I am using QSerialPort to read from a device connected to a COM port on my computer, and it sends characters every half a second to my computer. I can read them from the qDebug window, so I know the connection works and Qt receives the data.
However I continuously read from the serial port and refresh a label widget on my GUI. The label becomes blank when I run the app, I think this problem is caused by the label name constantly refreshing.
My QserialPort is managed in the mainwindow constructor, closed in destructor, and the readings are done in a function called serialReceived(), which I believe is called (or causes the label to refresh) too often
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
serial = new QSerialPort(this);
qDebug() << "nb ports: " << QSerialPortInfo::availablePorts().length();
foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts())
{
qDebug() << "name" << serialPortInfo.portName();
}
serial->setPortName("COM11");
serial->setBaudRate(QSerialPort::Baud9600);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
qDebug() << "is " << serial->open(QSerialPort::ReadOnly);
qDebug() << "err " << serial->error();
//serial->write("ok");
// Create the signal and slot
connect(serial, SIGNAL(readyRead()), this, SLOT(serialReceived()));
}
MainWindow::~MainWindow()
{
delete ui;
serial->close(); // instance is closed when mainwindow destroyed
}
void MainWindow::serialReceived()
{
QByteArray ba;
ba = serial->readAll();
ui->label->setText(serial->readAll());
qDebug()<<ba;
}
void MainWindow::serialReceived()
{
QByteArray ba;
ba = serial->readAll();
ui->label->setText(serial->readAll());
qDebug()<<ba;
}
You're first reading the data into ba, then you try to read again but since readAll() already read the data there is nothing left. You want
void MainWindow::serialReceived()
{
QByteArray ba = serial->readAll();
ui->label->setText(ba);
qDebug() << ba;
}
You just can read data at any time you want, not only by readyRead signal. The QSerialPort class will buffer all received data until you read it.
You also can append every received part of data to some scrollable QPlainTextEdit. I recommend this way.
void MainWindow::serialReceived()
{
QByteArray ba;
ba = serial->readAll();
ui->plainTextEdit->appendPlainText(ba);
}
Using timer:
connect(&m_timer, &QTimer::timeout, this, &MyClass::onTimer);
...
m_timer->start(5000);
...
void MyClass::onTimer()
{
if(serial->bytesAvailable() > 0)
{
QByteArray ba;
ba = serial->readAll();
ui->label->setText(ba);
qDebug() << ba;
}
}
You can also temporary disable visual updates of a widget using QWidget::setUpdatesEnabled(), but seems you should not miss part of the data.
Be note, QIODevice (and QSerialPort as its sublass, too) class makes no guarantee that a certain amount of data will be available on the readyRead event. For example, if you wrote 10 bytes to the port at a time on the other end, in some cases you will receive the signal that will allow less data to be available at the monent, that is, before all the transmitted bytes arrives.

How can i write the serial port incoming data into text file (.txt)

How I can write the serial port incoming data into text file(.txt).. The data write should have one hour interval time.
Following this the serial read data code:
void MainWindow::readData()
{
QByteArray data = serial->readAll();
QDataStream stream(data);
double value;
stream>>value;
console->putData(data);
qDebug()<<value;
}
I have tried this way but failed
void Write(QString Filename)
{
QFile mFile(Filename);
if(!mFile.open(QFile::WriteOnly | QFile::Text))
{
qDebug() << "Could not open file for writing";
return;
}
QTextStream out(&mFile);
out << data;
mFile.flush();
mFile.close();
}
I suggest you to use QByteArray for receiving and use signal readyRead() to call receive function when data is received.
QSerialPort *serialPort= new QSerialPort();
connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::receiveData_WriteToFile);
This function read data and write it in file.
void MainWindow::receiveData_WriteToFile()
{
if (serialPort->isOpen())
{
QByteArray DataReceived;
QFile LogFile("D:/data.txt");
if(!LogFile.open(QFile::Append | QFile::Text))
{
//Can't Open Log File.
}
if(serialPort->bytesAvailable())
{
DataReceived = serialPort->readAll();//All Data Received Successfully.
if(DataReceived.size() > 0)
{
if(LogFile.isOpen())
{
QTextStream in(&LogFile);
in << DataReceived;
}
LogFile.close();
}
else
{
//Fail To Receive Data.
}
}
LogFile.close();
}
}
readyRead() : This signal is emitted once every time new data is available for reading from the device's current read channel. It will only be emitted again once new data is available, such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.
output file:
This is a sample project for your question on github download here.

read tcpsocket by qt

hi i want to receive data from FPGA by Ethernet with qt. i can write data to fpga but unfortunately i cant receive data. after writing x"c000" to fpga it should send data but my code doesn't woked.
i write this code for receive data but i cant please help me.
QByteArray ba2;
ba2.resize(2);
ba2[0] = 0x00;
ba2[1] = 0xc0;
Client ob;
ob.connectToHost();
ob.writeData(ba2);
QByteArray Client:: readback(QByteArray data)
{
qDebug() << socket->readAll();
return data;
}
void Client::connectToHost()
{
socket->connectToHost("192.168.100.17", 1134);
}
void Client::close()
{
socket->close();
}
Client::Client(QObject *parent) : QObject(parent)
{
socket = new QTcpSocket();
connect(socket, SIGNAL(readyRead()), this, SLOT(readback(QByteArray data)));
}
Try it asynch:
auto t = make_unique<QTcpSocket>();
QObject::connect(t.data(),&QTcpSocket::connected,[&t](){
QDataStream writer(t.data());
writer << static_cast<quint16>(0xc000);
});
QObject::connect(t.data(),&QTcpSocket::readyRead,[&t](){
qDebug() << t->readAll();
});

Ffmpeg decode H264 video from RTP stream very slow

I have H264 RTP stream over network and I need to decode it. I use libx264 to encode stream and ffmpeg to decode. When I connect to server using VLC, it correct play video without any problem. But when I connect to server using my application I have a long period, when widget, which draw video from this stream, draw only one image.
I check log file and found, that avcodec_decode_video2() set got_image into 1 very rarely! Decoder give me new decoded frame average every 1-2 seconds, but on the server I have 12-15 fps on encoder!
What the reasons of this delays on decoder and how I can fix its?
avcodec_register_all();
av_init_packet(&m_packet);
m_decoder = avcodec_find_decoder(CODEC_ID_H264);
if (!m_decoder)
{
QString str = QString("Can't find H264 decoder!");
emit criticalError(str);
}
m_decoderContext = avcodec_alloc_context3(m_decoder);
m_decoderContext->flags |= CODEC_FLAG_LOW_DELAY;
m_decoderContext->flags2 |= CODEC_FLAG2_CHUNKS;
AVDictionary* dictionary = nullptr;
if (avcodec_open2(m_decoderContext, m_decoder, &dictionary) < 0)
{
QString str = QString("Failed to open decoder!");
emit criticalError(str);
}
qDebug() << "H264 Decoder successfully opened";
m_picture = avcodec_alloc_frame();
...
while(m_packet.size > 0)
{
int got_picture;
int len = avcodec_decode_video2(m_decoderContext, m_picture, &got_picture, &m_packet);
if (len < 0)
{
QString err("Decoding error");
qDebug() << err;
//emit criticalError(err);
return false;
}
if (got_picture)
{
//create from frame QImage and send it into GUI thread
qDebug() << "H264Decoder: frame decoded!";
I try to change some options of m_decoderContext (i.e. thread_count) but this not changing anything.