C++ - RtMidi send nothing to out ports - c++

I'm working on a program using RtMidi to communicate with MIDI applications.
Compilation, opening input and output ports, reading input ports works as well, but when I send message with output port, nothing happens.
No exception, no message in terminal, everything seems to be ok, but other apps never receives MIDI message.
$ uname
Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt7-1 (2015-03-01) x86_64 GNU/Linux
Audio server is ALSA 1.0.28.
$ cat /proc/asound/version
Advanced Linux Sound Architecture Driver Version k3.16.0-4-amd64.
MidiConnection::MidiConnection(QString Name, QObject *Object) : QThread(Object)
{
/*...*/
midiIn = new RtMidiIn(RtMidi::UNSPECIFIED, "Mecanique");
midiIn->openPort(0, Name.toStdString());
midiOut = new RtMidiOut(RtMidi::UNSPECIFIED, "Mecanique");
midiOut->openPort(0, Name.toStdString());
/*...*/
}
void MidiConnection::sendMessage(QVector<unsigned char> message)
{
std::vector<unsigned char> tempVector = message.toStdVector();
midiOut->sendMessage(&tempVector);
}
When I'm testing, tempVector contains right bytes (which are correct about the MIDI specs) (see answer below).

Solution found: this code is absolutely correct, it was the data given to the function sendMessage() which was wrong. When execution start, a value upper than 127 was included in a vector. As result, it seems that ALSA don't listen more the connection without force to close it.
Thanks for your suggestions!

Related

Qt Serial Communication not sending all data

I am writing a Qt application for serial communication with a Qorvo MDEK-1001. All built-in serial commands I've had to use work fine except for one: aurs n k, where n and k are integers corresponding to the desired rate of data transmission (e.g. "aurs 1 1\r"). Write function is:
void MainWindow::serialWrite(const QByteArray &command)
{
if(mdek->isOpen())
{
mdek->write(command);
qDebug() << "Command: " << command;
//mdek->flush();
}
}
If I send the command "aurs 1 1\r". It doesn't actually get sent to the device until I send another command for some reason. So if I subsequently send the "quit" command to the device, the returned data from the device is: "aurs 1quit", which registers as an unknown command. Any assistance getting this command to send properly is appreciated.
I've tried a bunch of stuff (setting bytes to write as second parameter in write(), using QDataStream, appending individual hex bytes onto QByteArray and writing that), but nothing has worked. This is the first time I've had to use Qt's serial communication software so I've probably missed something obvious.
On Linux Manjaro (same thing happens on Windows 8.1)
Connection settings: 8 data bits, Baud: 115200, No Flow Control, No Parity, One Stop Bit

Can't open a serial port in g++ on Ubuntu

I am trying to run the sample programs that came with a development lidar unit (RPLIDAR A1M8 360 Degree Laser Scanner Kit). The sample code for a Linux target compiles without error using g++
(Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0 however when I run it, it stops with the message 'Error, cannot bind to the specified serial port /dev/ttyUSB0'. Using gdb I can trace the code down to the serial port open call to __libc_open64 where I don't have source anymore...
__libc_open64 (file=0x5555557832a9 "/dev/ttyUSB0", oflag=2306) at ../sysdeps/unix/sysv/linux/open64.c:36}
36 ../sysdeps/unix/sysv/linux/open64.c: No such file or directory.
Here is what I tried so far to eliminate obvious failure modes:
The serial port, a USB-to-serial converter on ttyUSB0, works just fine from Putty (115200, 8, none, 1, software flow control only). I connect it to a Raspberry Pi as the console to get a large amount of data without issue and can bidirectionally interact with the console. Therefore I conclude the port and converter work fine
The section of code that calls __libc_open64 is...
bool raw_serial::open(const char * portname, uint32_t baudrate, uint32_t flags)
{
if (isOpened()) close();
serial_fd = ::open(portname, O_RDWR | O_NOCTTY | O_NDELAY);
I looked up the constants that are ORed together and hard coded the value (04403) just in case there was some issue with the version of the header files. Oddly the value is off by 1 from the oflag value in the gdb line. Compiled and ran it, no difference
I verified the call to ::open returned -1 which is treated as a failure in the code immediately after
I can see in dmesg that ttyUSB0 is open and available
I am not a c++ guy. This looks to me like an issue with the g++ __libc_open64 code but that also seems very unlikely. I don't know where to go next. Any advice would be greatly appreciated.
The first comments received pointed to permissions. I chmoded /dev/ttyUSB0 wide open before starting this exercise.
I ran strace and see the line...
openat(AT_FDCWD, "/dev/ttyUSB0", O_ACCMODE|O_NOCTTY|O_NONBLOCK) = -1 ENOENT (No such file or directory)
Well, that's embarrassing! It returns Permission Denied! Yes, I chmoded permissions wide open, then promptly forgot that being a USB device, it goes away and gets redefined when I unplug/plug it in again. Thank you for your help!
The prediction that strace would show "Permission denied" was correct. I was forgetting this is not a fixed serial port but rather a USB-to-serial converter. Even though I chmoded the permissions and verified it use with Putty, I forgot that as soon as I rebooted, or unplugged the USB, the /dev/ttyUSB0 device goes away and is recreated again when I rebooted or plugged it in, requiring that I set the permissions again.

Boost serial port 100% cpu usage

My problem seems to be related to https://svn.boost.org/trac10/ticket/10496.
Simply opening a boost serial port and waiting for data cause one of the cpu
core of the embedded cpu to have 100% usage.
My hardware is the redpitaya STEMLAB 125-14 running Ubuntu 16.04. Some relevant
code snippets below:
// In the header
namespace ba = boost::asio;
typedef std::shared_ptr < boost::asio::serial_port serial_port_ptr;
typedef std::shared_ptr<boost::asio::io_service::work> work_ptr;
class SerialPort {
boost::asio::io_service m_io_service;
serial_port_ptr m_port;
work_ptr m_work;
bool open(const std::string &portname);
};
// in the source file,
bool SerialPort::open(const std::string &portname) {
m_port = serial_port_ptr(new ba::serial_port(m_io_service));
m_work = work_ptr(new ba::io_service::work(m_io_service));
m_port->open(portname, ec);
if (ec) {
std::cout << "open failed" << std::endl;
return false;
}
m_io_service.reset();
std::thread t(boost::bind(&ba::io_service::run, &m_io_service));
t.detach();
}
If I comment out the last two lines, I get 0% cpu utilization. The code works
fine, I can read and send from the serial port. The serial port is a usb to
serial device (can this have any effect?).
Has anyone else experience this before and is there a workaround before it is
‘fixed’ by the boost developers or am I doing something wrong?
EDIT: I initially thought maybe the hardware is not ‘powerful enough’, so I installed Ubuntu on VMWare on my i7 laptop. And run only the serial code on it with the USB serial device and I obtained the same result - 100% CPU usage on one core.
I understand it is difficult to help without seeing the full code, so I created a simple code that demonstrate the problem: this can be downloaded from goo.gl/FD5RNE . For simplicity, the code is only looking for USB serial device and will try to open the first device it found.
If you remove the comment from sp.open(), you will see the cpu usage go close to full utilisation. Thanks.
Edit: Still no solution to this but since I am not expecting the serial device to send unsolicited messages to the client, I have changed the program to always close the port i.e. the write/read are executed together with port opened before write and closed after read.
This has worked well so far and I am getting an average CPU of around 0-0.8%. Maybe a future updates to boost will solve the issue.

ZMQ doesn't work with the raw socket in Linux but works in Windows

I have a client program written with raw socket communicating with a server. It uses 'select' to poll the socket descriptor and get the message from the server. After getting message, I use a ZMQ socket to send the message out.
This works perfectly in windows. But in Linux, after I call the ZMQ 'send' function, I cannot receive message from the server any more. It seems the raw socket has been affected somehow.
The program is a multithread program but I have dealt with ZMQ carefully. The client program is running in a thread A and the ZMQ socket is only used by that thread A. I think I used ZMQ correctly as it is working well in Windows. But how comes the issue in Linux?
Anybody knows if this is normal? I am suspecting this is a ZMQ issue. As long as I remove the ZMQ 'send' function, the program works well. Anybody knows how to solve this issue? and why it is working well in Windows, not in Linux?
I found it doesn't work even in single thread situation. ZMQ creates more than ten threads automatically for me. I don't use any multithread this time, and the code flow is like this:
create a raw socket A;
connect to a business server B;
STATE = 1
while (raw socket A is connected){
if (STATE==1){
send(Request 1);
}else if (STATE==2){
send(Request 2);
}
int ret = select(fd + 1, &readSet, &writeSet, &errorSet, &timeout);
if (ret > 0){
if (FD_ISSET(fd, &readSet)) {
char buf[8192];
int nResult = receive( buf, sizeof(buf));
if (buf is X){
zmq.send(messageX)
STATE=2
}else if (buf is Y){
STATE=3
}else{...}
}// socket is ready for reading
}
}
After zmq.send(message), I cannot receive any new message!! The server side code is closed to me so that I cannot debug from server side. If I remove "zmq.send(message)", everything works fine. In Windows, this program works fine too.
Well, it is hard to tell u whats wrong without a code. But you should probably look at ZMQ versions in Linux and Windows because the "formats of sending" etc can differ between versions and stuff that works in one version will not in another.

QTcpSocket Read Error

I have a Qt based TCP client and server making use of QTcpServer and QTcpSocket classes for communication. The server is compiled using Qt 5.3.1 and the client is compiled using Qt 4.8.1. This is done so because the client is a part of a framework that uses Qt 4.8.1 running on Ubuntu 12.04.
Since the classes I make use is available in both Qt versions I assume this wont create a problem.
However my client has some weird issues that it does not receive data from the server! I checked the server side and the data is sent from the server and I can also see the data packet on the wire using wireshark. However on my client code, the data does not arrive!
I investigated this a bit and it led me to a strange conclusion that this happens only if I use the read method of QTcpSocket! If I use the native POSIX read system call, I am able to read the data correctly! Please see my code below:
qDebug() << "QTcpSocket::bytesAvailable() gives" << m_pSocket->bytesAvailable();
char nData;
qint32 szReceived;
if(sizeof(char) != (szReceived = m_pSocket->read((char*)&nData,sizeof(char))))
{
qDebug() << "Error reading data from QTcpSocket::read()" << m_pSocket->errorString();
}
else
{
qDebug() << "QTcpSocket::read() returned" << szReceived;
}
int nDesc = m_pSocket->socketDescriptor();
if(sizeof(char) != (szReceived = read(nDesc, &nData,sizeof(char))))
{
perror("Error reading data from POSIX read()");
}
else
{
qDebug() << "POSIX read() returned" << szReceived;
}
This produces the following output:
QTcpSocket::bytesAvailable() gives 0
Error reading data from QTcpSocket::read() "Network operation timed out"
POSIX read() returned 1
How is it that the POSIX system calls reads the buffered data as expected and the Qt class cannot read it? Plus I have not set any socket options and so I don't know why it reports an error that network operation timed out!
"read" is a blocking call in POSIX, it waits till the data is arrived. while QTcpSocket is non-blocking operation it immediately returns the buffered data. Call waitForReadyRead before doing a read
socket->waitForReadyRead();
if(sizeof(char) != (szReceived = m_pSocket->read((char*)&nData,sizeof(char))))
I think that it is misuse of QTcpSocket concept. QTcpSocket implements asynchronous architecture while POSIX read/write calls are blocking until the success or error of I/O on socket. It is much better to process read in slot for readyRead signal. Consider this:
class MyClient
{
Q_OBJECT
...
private slots:
readFromSocket();
};
In your intialization:
QObject::connect(
m_pSocket, SIGNAL(readyRead()),
this, SLOT(readFromSocket()));
And real job done here:
void
MyClient::readFromSocket()
{
QByteArray buffer = m_pSocket->readAll();
// All your data in buffer.
}
I'm aware of the non-blocking nature of QTcpSocket and blocking nature of POSIX read call. Unfortunately I cannot use the signal readFromSocket because my communication architecture expects a header to be sent before each communication (TCP way) to see the payload that is streamed for that particular message. Hence I have to wait till I receive at least the header.
I do believe that this has something to do with the mode (blocking or non-blocking). I did some more tests and none of them were conclusive. In one of my tests, I tried to call a waitForReadyRead with a timeout of 1ms, 2ms, 3ms. This still wasn't sufficent for the read to succeed! I doubt if the read would need such time to read from the kernel buffers to user space as I can clearly see from wireshark that the message was received within 400ms.
When I give -1 as the timeout value of waitForReadyRead, the read succeeds! To put it in another way, the read succeeds only when the socket waits indefinitely like in the case of POSIX read call.
Another strange thing I observed was, this issue was originally observed when I was running a server compiled using Qt 5.3.1 and client compiled using Qt 4.8.1. When I compile my client to use Qt 5.3.1, I do not see this problem!!! I even tried compiling using Qt 4.7.1 and it worked without any issues!!!
Are there any known issues with socket implementation of Qt 4.8.1? I couldn't find much info regarding this unfortunately.