Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QAudioInput does not notify



  • Hallo,
    I have a problem.

    why isn't KVideoChatDialog::audioInNotify called?

    void KVideoChatDialog::callAccepted(uint16_t port) {
    	
    	auto device = this->settings->getVideoDevice();
    	if (!device.has_value()) {
    		QMessageBox::warning(nullptr, "No Device", "No Device was selected");
    		return;
    	}
    	
    	auto lambda = [this]() {
    		QAudioFormat format;
    		format.setChannelCount(1);
    		format.setSampleRate(8000);
    		format.setSampleSize(8);
    		format.setCodec("audio/pcm");
    		format.setByteOrder(QAudioFormat::Endian::LittleEndian);
    		format.setSampleType(QAudioFormat::UnSignedInt);
    		this->audioIn = new QAudioInput(this->settings->getAudioInput(), format);
    		this->audioOut = new QAudioOutput(this->settings->getAudioOutput(), format);
    		this->audioOut->setBufferSize(2048);
    		this->audioIn->setNotifyInterval(1000);
    		connect(this->audioIn, &QAudioInput::notify, this, &KVideoChatDialog::audioInNotify);
    		connect(this->audioIn, &QAudioInput::stateChanged, this, [](QAudio::State state) {QMessageBox::warning(nullptr, "State changed", QString::number(state)); });
    		this->audioInDevice = this->audioIn->start();
    		//this->capture.open(0,cv::CAP_ANY);
    		auto state = this->audioIn->state();
    		int i = 0;
    		//cv::VideoCapture cap;
    		this->cap.open(0);
    		while (!this->capture.isOpened()) {
    			
    			cv::Mat frame;
    			cap >> frame;
    			if (frame.empty())
    				continue;
    			auto img = QImage(frame.data, frame.cols, frame.rows, frame.step, QImage::Format::Format_RGB888);
    			emit this->changeOwnPic(img);
    			QByteArray array;
    			QBuffer buffer(&array);
    			buffer.open(QIODevice::WriteOnly);
    			img.save(&buffer,"BMP");
    			buffer.waitForBytesWritten(1000);
    			array = qCompress(array, 5);
    			uint64_t index = 0;
    			int64_t len = 0;
    			do {
    				len = this->video_socket->writeDtlsDatagram(array.mid(index, 4096));
    				index += 4096;
    				std::this_thread::sleep_for(std::chrono::microseconds(10));
    			} while (len >= 4096);
    			this->video_socket->writeDtlsDatagram("<END>");
    			//auto len = this->video_socket->writeDtlsDatagram(bytes);
    		}
    	};
    	connect(this, &KVideoChatDialog::startVideo, this, [&](std::function<void()> foo) {
    		this->videothread = std::make_unique<boost::thread>([=]() {
    			foo();
    			});
    		});
    
    	emit this->startVideo(lambda);
    }
    

  • Lifetime Qt Champion

    Very nice and descriptive example on how to not use lambdas...
    I would guess QAudioInput needs a running event loop in it's thread which isn't the case here.



  • @Christian-Ehrlicher said in QAudioInput does not notify:

    Very nice and descriptive example on how to not use lambdas...
    I would guess QAudioInput needs a running event loop in it's thread which isn't the case here.

    In Hindsight I could remove all lambdas except this in the connect function.
    I will remodel it and try your suggestion



  • @Christian-Ehrlicher said in QAudioInput does not notify:

    Very nice and descriptive example on how to not use lambdas...
    I would guess QAudioInput needs a running event loop in it's thread which isn't the case here.

    I remodelled it

    void KVideoChatDialog::callAccepted(uint16_t port) {
    	
    	auto device = this->settings->getVideoDevice();
    	if (!device.has_value()) {
    		QMessageBox::warning(nullptr, "No Device", "No Device was selected");
    		return;
    	}
    	connect(this, &KVideoChatDialog::startVideo, this, [this]() {
    		this->videothread = std::make_unique<boost::thread>(&KVideoChatDialog::startVideoTransferSocket, this);
    		//this->audiothread = std::make_unique<boost::thread>(&KVideoChatDialog::startAudioTransferSocket, this);
    		});
    	
    	emit this->startVideo();
    	this->startAudioTransferSocket();
    }
    
    void KVideoChatDialog::startVideoTransferSocket()
    {
    	this->cap.open(0);
    	while (this->cap.isOpened()) {
    		cv::Mat frame;
    		cap >> frame;
    		if (frame.empty())
    			continue;
    		auto img = QImage(frame.data, frame.cols, frame.rows, frame.step, QImage::Format::Format_RGB888);
    		emit this->changeOwnPic(img);
    		QByteArray array;
    		QBuffer buffer(&array);
    		buffer.open(QIODevice::WriteOnly);
    		img.save(&buffer, "BMP");
    		buffer.waitForBytesWritten(1000);
    		array = qCompress(array, 5);
    		uint64_t index = 0;
    		int64_t len = 0;
    		do {
    			len = this->video_socket->writeDtlsDatagram(array.mid(index, 4096));
    			index += 4096;
    			std::this_thread::sleep_for(std::chrono::microseconds(10));
    		} while (len >= 4096);
    		this->video_socket->writeDtlsDatagram("<END>");
    	}
    }
    
    void KVideoChatDialog::startAudioTransferSocket()
    {
    	this->audioInBuffer = new QBuffer(&this->QAudioInArray);
    	this->audioInBuffer->open(QIODevice::WriteOnly);
    	QAudioFormat format;
    	format.setChannelCount(1);
    	format.setSampleRate(8000);
    	format.setSampleSize(8);
    	format.setCodec("audio/pcm");
    	format.setByteOrder(QAudioFormat::Endian::LittleEndian);
    	format.setSampleType(QAudioFormat::UnSignedInt);
    	this->audioIn = new QAudioInput(this->settings->getAudioInput(), format);
    	this->audioOut = new QAudioOutput(this->settings->getAudioOutput(), format);
    	this->audioOut->setBufferSize(2048);
    	this->audioIn->setNotifyInterval(1000);
    	connect(this->audioIn, &QAudioInput::notify, this, &KVideoChatDialog::audioInNotify);
    	connect(this->audioIn, &QAudioInput::stateChanged, this, [](QAudio::State state) {QMessageBox::warning(nullptr, "State changed", QString::number(state)); });
    	this->audioIn->start(this->audioInBuffer);
    	auto state = this->audioIn->state();
    	//this->AudioINLoop.exec();
    	int i = 0;
    }
    

    Now it works.


Log in to reply