How to use running status with midiOutShortMsg? - midi

As described here, it should be possible to omit the status byte and only send data bytes after I set the status byte by sending the first command.
I'm testing with NoteOn command code (90 hex) and trying to play a chord, but it only works when the status byte is set at each call.
I tried putting the tone number into the lowest byte and velocity into second lowest but no sound was produced...

What you describe sounds correct, however, if you are not getting the expected result then it's possible your MIDI device is not fully MIDI compliant.
The following example code successfully plays a broken chord using running status on the Windows built-in MIDI device on my Windows 11 machine:
#pragma comment(lib, "Winmm.lib")
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <mmsystem.h>
#include <mmeapi.h>
#include <iostream>
int main()
{
try
{
HMIDIOUT hMidiOut = 0;
MMRESULT mmResult = midiOutOpen(&hMidiOut, -1, NULL, NULL, CALLBACK_NULL);
if (mmResult != MMSYSERR_NOERROR)
throw std::exception("Failed to open the MIDI device.");
mmResult = midiOutShortMsg(hMidiOut, 0x007F4090);
if (mmResult != MMSYSERR_NOERROR)
throw std::exception("midiOutShortMsg() failed.");
Sleep(500);
mmResult = midiOutShortMsg(hMidiOut, 0x00007F42);
if (mmResult != MMSYSERR_NOERROR)
throw std::exception("midiOutShortMsg() failed.");
Sleep(500);
mmResult = midiOutShortMsg(hMidiOut, 0x00007F44);
if (mmResult != MMSYSERR_NOERROR)
throw std::exception("midiOutShortMsg() failed.");
Sleep(3000);
midiOutReset(hMidiOut);
midiOutClose(hMidiOut);
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}

Related

Why is pcap only capturing PTP messages in live capture mode?

I am using a Intel i210-T1 Network Interface Card.
I am running the avnu gptp client (https://github.com/Avnu/gptp) with:
sudo ./daemon_cl -S -V
The other side is a gPTP Master.
I want to live capture incoming UDP packets on an network interface with hardware timestamps.
I can see the UDP Packets with wireshark, so the packets are actually on the wire.
My problem is that pcap doesn't return any packets other than PTP (ethertype 0x88f7) at all.
Is this a bug or am i using pcap the wrong way?
I wrote a minimal example to show my problem.
The code prints:
enp1s0
returnvalue pcap_set_tstamp_type: 0
returnvalue pcap_set_tstamp_precision: 0
returnvalue pcap_activate: 0
and afterwards only:
packet received with ethertype:88f7
#include <iostream>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <pcap/pcap.h>
int main(int argc, char **argv)
{
char errbuf[PCAP_ERRBUF_SIZE];
std::string dev = "enp1s0";
pcap_t* pcap_dev;
int i = 0;
printf("%s\n", dev.c_str());
pcap_dev = pcap_create(dev.c_str(), errbuf);
if(pcap_dev == NULL)
{
printf("pcap_create(): %s\n", errbuf);
exit(1);
}
i = pcap_set_tstamp_type(pcap_dev, PCAP_TSTAMP_ADAPTER_UNSYNCED);
printf("returnvalue pcap_set_tstamp_type: %i\n", i);
i = pcap_set_tstamp_precision(pcap_dev, PCAP_TSTAMP_PRECISION_NANO);
printf("returnvalue pcap_set_tstamp_precision: %i\n", i);
i = pcap_activate(pcap_dev);
printf("returnvalue pcap_activate: %i\n", i);
struct pcap_pkthdr* pkthdr;
const u_char* bytes;
while (pcap_next_ex(pcap_dev, &pkthdr, &bytes))
{
struct ether_header* ethhdr = (struct ether_header*) bytes;
std::cout << "packet received with ethertype:" << std::hex << ntohs(ethhdr->ether_type) << std::endl;
}
}
The solution is to enable promiscuous mode by using function:
https://linux.die.net/man/3/pcap_set_promisc
promiscuous mode disables any filtering by lower layers so you get every message arriving on the interface.
int pcap_set_promisc(pcap_t *p, int promisc);
pcap_set_promisc() sets whether promiscuous mode should be set on a capture handle when the handle is activated. If promisc is non-zero, promiscuous mode will be set, otherwise it will not be set.
Return Value
pcap_set_promisc() returns 0 on success or PCAP_ERROR_ACTIVATED if called on a capture handle that has been activated.

What does it mean when CreateNamedPipe returns of 0xFFFFFFFF perror() says "NO ERROR'?

I am using CreateNamedPipe. It returns 0XFFFFFFFF but when I call GetLastError and perror I get "NO ERROR".
I have checked https://learn.microsoft.com/en-us/windows/win32/ipc/multithreaded-pipe-server and I heve coded very similar.
I coded this using an example provided here: https://stackoverflow.com/questions/47731784/c-createnamedpipe-error-path-not-found-3#= and he says it means ERROR_PATH_NOT_FOUND (3). But my address is "\\.\pipe\pipe_com1. Note that StackOverflow seems to remove the extra slashes but you will see them in the paste of my code.
I followed the example here: Create Named Pipe C++ Windows but I still get the error. Here is my code:
// Create a named pipe
// It is used to test TcpToNamedPipe to be sore it it is addressing the named pipe
#include <windows.h>
#include <stdio.h>
#include <process.h>
char ch;
int main(int nargs, char** argv)
{
if (nargs != 2)
{
printf("Usage pipe name is first arg\n");
printf("press any key to exit ");
scanf("%c", &ch);
return -1;
}
char buffer[1024];
HANDLE hPipe;
DWORD dwRead;
sprintf(buffer, "\\\\.\\pipe\\%s", argv[1]);
hPipe = CreateNamedPipe((LPCWSTR)buffer,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists...
1,
1024*16,
1024*16,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
if (hPipe == INVALID_HANDLE_VALUE)
{
//int errorno = GetLastError();
//printf("error creating pipe %d\n", errorno);
perror("");
printf("press any key to exit ");
scanf("%c", &ch);
return -1;
}
while (hPipe != INVALID_HANDLE_VALUE)
{
if (ConnectNamedPipe(hPipe, NULL) != FALSE) // wait for someone to connect to the pipe
{
while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) != FALSE)
{
/* add terminating zero */
buffer[dwRead] = '\0';
/* do something with data in buffer */
printf("%s", buffer);
}
}
DisconnectNamedPipe(hPipe);
}
return 0;
}
I'm guessing that the pointer to the address may be wrong and CreateNamedPipe is not seeing the name of the pipe properly. So I used disassembly and notice that the address is in fact a far pointer. Here is that disassembly:
00CA1A45 mov esi,esp
00CA1A47 push 0
00CA1A49 push 0
00CA1A4B push 4000h
00CA1A50 push 4000h
00CA1A55 push 1
00CA1A57 push 0
00CA1A59 push 3
00CA1A5B lea eax,[buffer]
00CA1A61 push eax
00CA1A62 call dword ptr [__imp__CreateNamedPipeW#32 (0CAB00Ch)]
Can someone spot my problem?

Access to OS functions from CAPL

I'm doing a script using CAPL and am stuck for a solution to grep the login ID from Windows. Could some please help show how to get Windows user login ID from within a CAPL program code, if this is possible?
For example, if the Windows user login ID is 'kp21ml' , I want to read this ID from a CAPL function, as shown below.
byte UserIdCheck()
{
char uid[10];
byte CanMessageTrasmission;
strncpy(uid, xxxx(), 6); // where xxxx() is the unknown OS or system function that could return the login ID ?
if (strncmp(uid, "kp21ml") != 0)
{
write("Access denied!"); // Message to CANoe's Write window
CanMessageTrasmission = 0;
}
else
{
// Access ok
CanMessageTrasmission = 1;
}
return CanMessageTrasmission;
}
I use this CAPL book as my reference guide, which is very good:
http://docplayer.net/15013371-Programming-with-capl.html
But I couldn't find anything to do with system access. I would appreciate your help.
Thanks
Juno
I'm afraid you won't be able to do that directly from a CAPL script.
I generally create a CAPL-DLL and include that in my CANoe project when I need to access some OS level functionality. Though I use it mostly for accessing an external device (e.g. USB) or to interact with another program using sockets over local host, the principle is the same.
You can find more information in CANoe's documentation with examples but the CAPL-DLL source code provided in CANoe samples is a little difficult to understand.
I've attempted to strip some of the "unnecessary" parts in the following code sample; this example will create a CAPL-DLL which "exposes" the multiplyBy10 function and basically allows you to call multiplyBy10 from you CAPL script):
#define USECDLL_FEATURE
#define _BUILDNODELAYERDLL
#pragma warning( disable : 4786 )
#include "cdll.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <map>
char moduleName[_MAX_FNAME];
HINSTANCE moduleHandle;
unsigned int
CAPLEXPORT far CAPLPASCAL multiplyBy10 (unsigned char value)
{
unsigned int result = value * 10;
freopen("CONOUT$", "w", stdout);
std::cout << "multiplyBy10() - value: " << int(value) << ", result: " << result << std::endl;
return (result);
}
CAPL_DLL_INFO4 table[] =
{
{CDLL_VERSION_NAME, (CAPL_FARCALL)CDLL_VERSION, "", "", CAPL_DLL_CDECL, 0xABD, CDLL_EXPORT},
{"multiplyBy10", (CAPL_FARCALL)multiplyBy10, "CAPL_DLL", "This is a demo function", 'L', 1, "D", "", { "value"}},
{0, 0}
};
CAPLEXPORT CAPL_DLL_INFO4 far * caplDllTable4 = table;
bool
WINAPI DllMain(HINSTANCE handle, DWORD reason, void*)
{
static FILE * stream;
switch (reason)
{
case DLL_PROCESS_ATTACH:
{
moduleHandle = handle;
char path_buffer[_MAX_PATH];
DWORD result = GetModuleFileName(moduleHandle, path_buffer, _MAX_PATH);
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath_s(path_buffer, drive, dir, fname, ext);
strcpy_s(moduleName, fname);
AllocConsole();
freopen_s(&stream, "conout$", "w", stdout);
std::cout << "DLL_PROCESS_ATTACH" << std::endl;
return 1;
}
case DLL_PROCESS_DETACH:
{
std::cout << "DLL_PROCESS_DETACH" << std::endl;
FreeConsole();
fclose(stream);
return 1;
}
}
return 1;
}

ncurses interrupts system call when resizing terminal

I have a problem with ncurses and couldn't find a solution on the web, so I've written following little program to demonstrate the problem.
You can compile it via:
sudo aptitude install ncurses-dev
g++ -lncurses -o resize resize.cpp
It displays an integer counter incremented every second by forking into a timer process which periodically sends one byte to the parent process via a socketpair. You can quit it by pressing CTRL+C.
When you resize the terminal you should get an error message of 'Interrupted system call'. So the read call gets interrupted by SIGWINCH when resizing. But how can I avoid this? Or is it common that the system call gets interrupted? But how would I handle an interrupted system call in order to proceed incrementing the counter since the file descripter appears to be dead after interruption.
If you use non-blocking sockets, you would get 'Resource temporarily unavailable' instead.
I am using stable debian wheezy, so the ncurses version is 5.9-10 and the libstdc++ version is 4.7.2-5.
#include <ncurses.h>
#include <signal.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <string>
#include <iostream>
//Define a second.
timespec span = {1, 0};
//Handles both, SIGWINCH and SIGINT
void handle(int signal) {
switch (signal) {
case SIGWINCH:
//Reinitialize ncurses to get new size
endwin();
refresh();
printw("Catched SIGWINCH and handled it.\n");
refresh();
break;
case SIGINT:
//Catched CTRL+C and quit
endwin();
exit(0);
break;
}
}
//This registers above signal handler function
void set_handler_for(int signal) {
struct sigaction action;
action.sa_handler = handle;
action.sa_flags = 0;
if (-1 == sigemptyset(&action.sa_mask) or -1 == sigaction(signal, &action, NULL))
throw "Cannot set signal handler";
}
main() {
int fd[2];
//In this try block we fork into the timer process
try {
set_handler_for(SIGINT);
set_handler_for(SIGWINCH);
//Creating a socketpair to communicate between timer and parent process
if (-1 == socketpair(PF_LOCAL, SOCK_STREAM, 0, fd))
throw "Cannot create socketpair";
pid_t pid;
//Doing the fork
if (-1 == (pid = fork()))
throw "Cannot fork process";
if (!pid) {
//We are the timer, so closing the other end of the socketpair
close(fd[0]);
//We send one byte every second to the parent process
while (true) {
char byte;
ssize_t bytes = write(fd[1], &byte, sizeof byte);
if (0 >= bytes)
throw "Cannot write";
nanosleep(&span, 0);
}
//Here the timer process ends
exit(0);
}
//We are the parent process, so closing the other end of the socketpair
close(fd[1]);
}
catch (const char*& what) {
std::cerr << what << std::endl;
exit(1);
}
//Parent process - Initializing ncurses
initscr();
noecho();
curs_set(0);
nodelay(stdscr, TRUE);
//In this try block we read (blocking) the byte from the timer process every second
try {
int tick = 0;
while (true) {
char byte;
ssize_t bytes = read(fd[0], &byte, sizeof byte);
if (0 >= bytes)
throw "Cannot read";
//Clear screen and print increased counter
clear();
mvprintw(0, 0, "Tick: %d - Resize terminal and press CTRL+C to quit.\n", ++tick);
//Catch special key KEY_RESIZE and reinitialize ncurses to get new size (actually not necassary)
int key;
while ((key = getch()) != ERR) {
if (key == KEY_RESIZE) {
endwin();
refresh();
printw("Got KEY_RESIZE and handled it.\n");
}
}
//Update the screen
refresh();
}
}
catch (const char*& what) {
//We got an error - print it but don't quit in order to have time to read it
std::string error(what);
if (errno) {
error.append(": ");
error.append(strerror(errno));
}
error = "Catched exception: "+error+"\n";
printw(error.c_str());
refresh();
//Waiting for CTRL+C to quit
while (true)
nanosleep(&span, 0);
}
}
Thank you!
Regards
Most (if not all) system calls have an interrupted error code (errno == EINTR), this is normal.
I would check for EINTR on the read from the pipe and ignore it, just read again.
I wouldn't call any ncurses functions in the signal handler, some are re-entrant but I doubt printw is. Just do the KEY_RESIZE check.
Okay, I got it working by only using re-entrant functions within signal handlers. Now the socketpair is still working after an EINTR or EAGAIN.
Thank you!
#include <ncurses.h>
#include <signal.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <string>
#include <iostream>
// Define a second.
timespec base = {1, 0};
// Holds raised SIGINTs.
size_t raised_SIGINT = 0;
// Holds raised SIGWINCHs.
size_t raised_SIGWINCH = 0;
// Handle SIGWINCH
void handle_SIGWINCH(int) {
++raised_SIGWINCH;
}
// Handle SIGINT
void handle_SIGINT(int) {
++raised_SIGINT;
}
// Registers signal handlers.
void assign(int signal, void (*handler)(int)) {
struct sigaction action;
action.sa_handler = handler;
action.sa_flags = 0;
if (-1 == sigemptyset(&action.sa_mask) or -1 == sigaction(signal, &action, NULL))
throw "Cannot set signal handler";
}
// Prints ticks alive and usage information.
inline void print(size_t ticks) {
mvprintw(0, 0, "%ds alive. Resize terminal and press CTRL+C to quit.\n\n", ticks);
}
int main() {
// Holds the two socketpair file descriptors.
int fd[2];
// Fork into the timer process.
try {
// Register both signals.
assign(SIGINT, handle_SIGINT);
assign(SIGWINCH, handle_SIGWINCH);
// Create a socketpair to communicate between timer and parent process.
if (-1 == socketpair(PF_LOCAL, SOCK_STREAM, 0, fd))
throw "Cannot create socketpair";
// Doing the fork.
pid_t pid;
if (-1 == (pid = fork()))
throw "Cannot fork process";
if (!pid) {
// We are the timer, so closing the parent end of the socketpair.
close(fd[0]);
// We send one byte every second to the parent process.
while (true) {
timespec less = base;
int ret;
// Continue sleeping after SIGWINCH but only for the time left.
while (-1 == (ret = nanosleep(&less, &less)) and errno == EINTR and raised_SIGWINCH);
// Maybe quit by user.
if (raised_SIGINT)
return 0;
// If something went wrong, terminate.
if (-1 == ret)
throw "Cannot sleep";
// Repeated writing if interrupted by SIGWINCH.
char byte;
ssize_t bytes;
do {
// Doing the write.
bytes = write(fd[1], &byte, sizeof byte);
}
while (0 >= bytes and (errno == EAGAIN or errno == EINTR) and raised_SIGWINCH);
// Maybe quit by user.
if (raised_SIGINT)
return 0;
// If something went wrong, terminate.
if (0 >= bytes)
throw "Cannot write";
}
// Here the timer process ends.
return 0;
}
// We are the parent process, so closing the timer end of the socketpair.
close(fd[1]);
}
catch (const char*& what) {
// Print fatal error and terminate timer process causing parent process to terminate, too.
std::cerr << what << std::endl;
return 1;
}
// Initializing ncurses for the parent process.
initscr();
// Disable typing.
noecho();
// Disable cursor.
curs_set(0);
// Make reading characters non-blocking.
nodelay(stdscr, TRUE);
// Catch fatal errors.
try {
// Holds ticks alive.
size_t ticks = 0;
// Blockingly read the byte from the timer process awaiking us every second.
while (true) {
// Print ticks alive before incrementing them.
print(ticks++);
// Holds typed keys.
std::string keys;
// Read typed keys.
for (int key = getch(); key != ERR; key = getch())
if (key != KEY_RESIZE)
keys += key;
// Format typed keys string.
if (keys.size())
printw("You've typed: ");
else
keys += "\n";
keys += "\n\n";
// Print typed keys string.
printw(keys.c_str());
// Doing the prints.
refresh();
// Repeated reading if interrupted by SIGWINCH.
ssize_t bytes = 0;
bool again = false;
do {
// Doing the read.
char byte;
bytes = read(fd[0], &byte, sizeof byte);
again = (0 >= bytes and (errno == EAGAIN or errno == EINTR) and raised_SIGWINCH);
// Print how often we got interrupted by SIGWINCH per time base.
if (again) {
// Next two calls are the common way to handle a SIGWINCH.
endwin();
refresh();
// For simpicity clear everything.
clear();
// Re-print ticks.
print(ticks);
// Print the interruption counter.
printw("%dx catched SIGWINCH per time base.\n\n", raised_SIGWINCH);
// Doing the prints.
refresh();
}
}
while (again);
// Reset SIGWINCH raises per time base.
raised_SIGWINCH = 0;
// Maybe quit by user.
if (raised_SIGINT) {
endwin();
return 0;
}
// If something went wrong, terminate.
if (0 >= bytes)
throw "Cannot read";
}
}
catch (const char*& what) {
// We got an error, appending errno if set.
std::string error(what);
if (errno) {
error.append(": ");
error.append(strerror(errno));
}
error = "Catched exception: "+error+"\n";
// Print the fatal error.
printw(error.c_str());
//Doing the print.
refresh();
// Waiting for CTRL+C to quit.
while (true)
nanosleep(&base, 0);
// Quit by user.
endwin();
return 0;
}
}

streaming with tcp using opencv and socket

i have done simple tcp client/server program got working well with strings and character data...i wanted to take each frames(from a webcam) and sent it to server.. here is the part of client program where error happened:
line:66 if(send(sock, frame, sizeof(frame), 0)< 0)
error:
client.cpp:66:39: error: cannot convert ‘cv::Mat’ to ‘const void*’ for argument ‘2’ to ‘ssize_t send(int, const void*, size_t, int)
i cant recognise this error....kindly help...the following complete client program:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>
#include<netdb.h>
#include<unistd.h>
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc,char *argv[])
{
int sock;
struct sockaddr_in server;
struct hostent *hp;
char buff[1024];
VideoCapture capture;
Mat frame;
capture.open( 1 );
if ( ! capture.isOpened() ) { printf("--(!)Error opening video capture\n"); return -1; }
begin:
capture.read(frame);
if( frame.empty() )
{
printf(" --(!) No captured frame -- Break!");
goto end;
}
sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket failed");
exit(1);
}
server.sin_family =AF_INET;
hp= gethostbyname(argv[1]);
if(hp == 0)
{
perror("get hostname failed");
close(sock);
exit(1);
}
memcpy(&server.sin_addr,hp->h_addr,hp->h_length);
server.sin_port = htons(5000);
if(connect(sock,(struct sockaddr *) &server, sizeof(server))<0)
{
perror("connect failed");
close(sock);
exit(1);
}
int c = waitKey(30);
if( (char)c == 27 ) { goto end; }
if(send(sock, frame, sizeof(frame), 0)< 0)
{
perror("send failed");
close(sock);
exit(1);
}
goto begin;
end:
printf("sent\n",);
close(sock);
return 0;
}
Because TCP provides a stream of bytes, before you can send something over a TCP socket, you must compose the exact bytes you want to send. Your use of sizeof is incorrect. The sizeof function tells you how many bytes are needed on your system to store the particular type. This bears no relationship to the number of bytes the data will require over the TCP connection which depends on the particular protocol layered on top of TCP you are implementing which must specify how data is to be sent at the byte level.
like david already said, you got the length wrong. sizeof() won't help, what you want is probably
frame.total() * frame.channels()
you can't send a Mat object, but you can send the pixels ( the data pointer ) , so this would be:
send(sock, frame.data,frame.total() * frame.channels(), 0)
but still a bad idea. sending uncompressed pixels over the netwotrk ? bahh.
please look at imencode/imdecode
i'm pretty sure, you got the client / server roles in reverse here.
usually the server holds the information to retrieve ( the webcam ), and the client connects to that
and requests an image.