From 40a899bd6ee536eae093337bf2d0dcc8db4e46f1 Mon Sep 17 00:00:00 2001 From: Mitja Felicijan Date: Mon, 7 Oct 2024 19:30:56 +0200 Subject: Moved example code examples folder --- portmidi/pm_test/mm.c | 595 -------------------------------------------------- 1 file changed, 595 deletions(-) delete mode 100755 portmidi/pm_test/mm.c (limited to 'portmidi/pm_test/mm.c') diff --git a/portmidi/pm_test/mm.c b/portmidi/pm_test/mm.c deleted file mode 100755 index ab9d32e..0000000 --- a/portmidi/pm_test/mm.c +++ /dev/null @@ -1,595 +0,0 @@ -/* mm.c -- midi monitor */ - -/***************************************************************************** -* Change Log -* Date | Change -*-----------+----------------------------------------------------------------- -* 7-Apr-86 | Created changelog -* 31-Jan-90 | GWL : use new cmdline -* 5-Apr-91 | JDW : Further changes -* 16-Feb-92 | GWL : eliminate label mmexit:; add error recovery -* 18-May-92 | GWL : continuous clocks, etc. -* 17-Jan-94 | GWL : option to display notes -* 20-Nov-06 | RBD : port mm.c from CMU Midi Toolkit to PortMidi -* | mm.c -- revealing MIDI secrets for over 20 years! -*****************************************************************************/ - -#include "stdlib.h" -#include "ctype.h" -#include "string.h" -#include "stdio.h" -#include "porttime.h" -#include "portmidi.h" - -#define STRING_MAX 80 - -#define MIDI_CODE_MASK 0xf0 -#define MIDI_CHN_MASK 0x0f -/*#define MIDI_REALTIME 0xf8 - #define MIDI_CHAN_MODE 0xfa */ -#define MIDI_OFF_NOTE 0x80 -#define MIDI_ON_NOTE 0x90 -#define MIDI_POLY_TOUCH 0xa0 -#define MIDI_CTRL 0xb0 -#define MIDI_CH_PROGRAM 0xc0 -#define MIDI_TOUCH 0xd0 -#define MIDI_BEND 0xe0 - -#define MIDI_SYSEX 0xf0 -#define MIDI_Q_FRAME 0xf1 -#define MIDI_SONG_POINTER 0xf2 -#define MIDI_SONG_SELECT 0xf3 -#define MIDI_TUNE_REQ 0xf6 -#define MIDI_EOX 0xf7 -#define MIDI_TIME_CLOCK 0xf8 -#define MIDI_START 0xfa -#define MIDI_CONTINUE 0xfb -#define MIDI_STOP 0xfc -#define MIDI_ACTIVE_SENSING 0xfe -#define MIDI_SYS_RESET 0xff - -#define MIDI_ALL_SOUND_OFF 0x78 -#define MIDI_RESET_CONTROLLERS 0x79 -#define MIDI_LOCAL 0x7a -#define MIDI_ALL_OFF 0x7b -#define MIDI_OMNI_OFF 0x7c -#define MIDI_OMNI_ON 0x7d -#define MIDI_MONO_ON 0x7e -#define MIDI_POLY_ON 0x7f - - -#define private static - -#ifndef false -#define false 0 -#define true 1 -#endif - -typedef int boolean; - -int debug = false; /* never set, but referenced by userio.c */ -PmStream *midi_in; /* midi input */ -boolean active = false; /* set when midi_in is ready for reading */ -boolean in_sysex = false; /* we are reading a sysex message */ -boolean inited = false; /* suppress printing during command line parsing */ -boolean done = false; /* when true, exit */ -boolean notes = true; /* show notes? */ -boolean controls = true; /* show continuous controllers */ -boolean bender = true; /* record pitch bend etc.? */ -boolean excldata = true; /* record system exclusive data? */ -boolean verbose = true; /* show text representation? */ -boolean realdata = true; /* record real time messages? */ -boolean clksencnt = true; /* clock and active sense count on */ -boolean chmode = true; /* show channel mode messages */ -boolean pgchanges = true; /* show program changes */ -boolean flush = false; /* flush all pending MIDI data */ - -uint32_t filter = 0; /* remember state of midi filter */ - -uint32_t clockcount = 0; /* count of clocks */ -uint32_t actsensecount = 0; /* cout of active sensing bytes */ -uint32_t notescount = 0; /* #notes since last request */ -uint32_t notestotal = 0; /* total #notes */ - -char val_format[] = " Val %d\n"; - -/***************************************************************************** -* Imported variables -*****************************************************************************/ - -extern int abort_flag; - -/***************************************************************************** -* Routines local to this module -*****************************************************************************/ - -private void mmexit(int code); -private void output(PmMessage data); -private int put_pitch(int p); -private void showhelp(); -private void showbytes(PmMessage data, int len, boolean newline); -private void showstatus(boolean flag); -private void doascii(char c); -private int get_number(const char *prompt); - - -/* read a number from console */ -/**/ -int get_number(const char *prompt) -{ - int n = 0, i; - fputs(prompt, stdout); - while (n != 1) { - n = scanf("%d", &i); - while (getchar() != '\n') ; - } - return i; -} - - -void receive_poll(PtTimestamp timestamp, void *userData) -{ - PmEvent event; - int count; - if (!active) return; - while ((count = Pm_Read(midi_in, &event, 1))) { - if (count == 1) output(event.message); - else puts(Pm_GetErrorText(count)); - } -} - - -/**************************************************************************** -* main -* Effect: prompts for parameters, starts monitor -****************************************************************************/ - -int main(int argc, char **argv) -{ - char *argument; - int inp; - PmError err; - int i; - if (argc > 1) { /* first arg can change defaults */ - argument = argv[1]; - while (*argument) doascii(*argument++); - } - showhelp(); - /* use porttime callback to empty midi queue and print */ - Pt_Start(1, receive_poll, 0); - /* list device information */ - puts("MIDI input devices:"); - for (i = 0; i < Pm_CountDevices(); i++) { - const PmDeviceInfo *info = Pm_GetDeviceInfo(i); - if (info->input) printf("%d: %s, %s\n", i, info->interf, info->name); - } - inp = get_number("Type input device number: "); - err = Pm_OpenInput(&midi_in, inp, NULL, 512, NULL, NULL); - if (err) { - puts(Pm_GetErrorText(err)); - Pt_Stop(); - mmexit(1); - } - Pm_SetFilter(midi_in, filter); - inited = true; /* now can document changes, set filter */ - printf("Midi Monitor ready.\n"); - active = true; - while (!done) { - doascii(getchar()); - while (getchar() != '\n') ; - } - active = false; - Pm_Close(midi_in); - Pt_Stop(); - Pm_Terminate(); - mmexit(0); - return 0; // make the compiler happy be returning a value -} - - -/**************************************************************************** -* doascii -* Inputs: -* char c: input character -* Effect: interpret to revise flags -****************************************************************************/ - -private void doascii(char c) -{ - if (isupper(c)) c = tolower(c); - if (c == 'q') done = true; - else if (c == 'b') { - bender = !bender; - filter ^= PM_FILT_PITCHBEND; - if (inited) - printf("Pitch Bend, etc. %s\n", (bender ? "ON" : "OFF")); - } else if (c == 'c') { - controls = !controls; - filter ^= PM_FILT_CONTROL; - if (inited) - printf("Control Change %s\n", (controls ? "ON" : "OFF")); - } else if (c == 'h') { - pgchanges = !pgchanges; - filter ^= PM_FILT_PROGRAM; - if (inited) - printf("Program Changes %s\n", (pgchanges ? "ON" : "OFF")); - } else if (c == 'n') { - notes = !notes; - filter ^= PM_FILT_NOTE; - if (inited) - printf("Notes %s\n", (notes ? "ON" : "OFF")); - } else if (c == 'x') { - excldata = !excldata; - filter ^= PM_FILT_SYSEX; - if (inited) - printf("System Exclusive data %s\n", (excldata ? "ON" : "OFF")); - } else if (c == 'r') { - realdata = !realdata; - filter ^= (PM_FILT_PLAY | PM_FILT_RESET | PM_FILT_TICK | PM_FILT_UNDEFINED); - if (inited) - printf("Real Time messages %s\n", (realdata ? "ON" : "OFF")); - } else if (c == 'k') { - clksencnt = !clksencnt; - if (inited) { - printf("Clock and Active Sense Counting %s\n", (clksencnt ? "ON" : "OFF")); - printf("Resetting Clock and Active Sense counts.\n"); - clockcount = actsensecount = 0; - } - } else if (c == 's') { - if (inited) { - printf("Clock Count %ld\nActive Sense Count %ld\n", - (long) clockcount, (long) actsensecount); - } - } else if (c == 't') { - notestotal+=notescount; - if (inited) - printf("This Note Count %ld\nTotal Note Count %ld\n", - (long) notescount, (long) notestotal); - notescount=0; - } else if (c == 'v') { - verbose = !verbose; - if (inited) - printf("Verbose %s\n", (verbose ? "ON" : "OFF")); - } else if (c == 'm') { - chmode = !chmode; - if (inited) - printf("Channel Mode Messages %s", (chmode ? "ON" : "OFF")); - } else { - if (inited) { - if (c == ' ') { - PmEvent event; - while (Pm_Read(midi_in, &event, 1)) ; /* flush midi input */ - printf("...FLUSHED MIDI INPUT\n\n"); - } else showhelp(); - } - } - if (inited) Pm_SetFilter(midi_in, filter); -} - - - -private void mmexit(int code) -{ - /* if this is not being run from a console, maybe we should wait for - * the user to read error messages before exiting - */ - exit(code); -} - - -/**************************************************************************** -* output -* Inputs: -* data: midi message buffer holding one command or 4 bytes of sysex msg -* Effect: format and print midi data -****************************************************************************/ - -char vel_format[] = " Vel %d\n"; - -private void output(PmMessage data) -{ - int command; /* the current command */ - int chan; /* the midi channel of the current event */ - int len; /* used to get constant field width */ - - /* printf("output data %8x; ", data); */ - - command = Pm_MessageStatus(data) & MIDI_CODE_MASK; - chan = Pm_MessageStatus(data) & MIDI_CHN_MASK; - - if (in_sysex || Pm_MessageStatus(data) == MIDI_SYSEX) { -#define sysex_max 16 - int i; - PmMessage data_copy = data; - in_sysex = true; - /* look for MIDI_EOX in first 3 bytes - * if realtime messages are embedded in sysex message, they will - * be printed as if they are part of the sysex message - */ - for (i = 0; (i < 4) && ((data_copy & 0xFF) != MIDI_EOX); i++) - data_copy >>= 8; - if (i < 4) { - in_sysex = false; - i++; /* include the EOX byte in output */ - } - showbytes(data, i, verbose); - if (verbose) printf("System Exclusive\n"); - } else if (command == MIDI_ON_NOTE && Pm_MessageData2(data) != 0) { - notescount++; - if (notes) { - showbytes(data, 3, verbose); - if (verbose) { - printf("NoteOn Chan %2d Key %3d ", chan, Pm_MessageData1(data)); - len = put_pitch(Pm_MessageData1(data)); - printf(vel_format + len, Pm_MessageData2(data)); - } - } - } else if ((command == MIDI_ON_NOTE /* && Pm_MessageData2(data) == 0 */ || - command == MIDI_OFF_NOTE)) { - if (notes) { - showbytes(data, 3, verbose); - if (verbose) { - printf("NoteOff Chan %2d Key %3d ", chan, - Pm_MessageData1(data)); - len = put_pitch(Pm_MessageData1(data)); - printf(vel_format + len, Pm_MessageData2(data)); - } - } - } else if (command == MIDI_CH_PROGRAM) { - if (pgchanges) { - showbytes(data, 2, verbose); - if (verbose) { - printf(" ProgChg Chan %2d Prog %2d\n", chan, - Pm_MessageData1(data) + 1); - } - } - } else if (command == MIDI_CTRL) { - /* controls 121 (MIDI_RESET_CONTROLLER) to 127 are channel - * mode messages. */ - if (Pm_MessageData1(data) < MIDI_ALL_SOUND_OFF) { - if (controls) { - showbytes(data, 3, verbose); - if (verbose) { - printf("CtrlChg Chan %2d Ctrl %2d Val %2d\n", - chan, Pm_MessageData1(data), Pm_MessageData2(data)); - } - } else /* channel mode */ if (chmode) { - showbytes(data, 3, verbose); - if (verbose) { - switch (Pm_MessageData1(data)) { - case MIDI_ALL_SOUND_OFF: - printf("All Sound Off, Chan %2d\n", chan); - break; - case MIDI_RESET_CONTROLLERS: - printf("Reset All Controllers, Chan %2d\n", chan); - break; - case MIDI_LOCAL: - printf("LocCtrl Chan %2d %s\n", - chan, Pm_MessageData2(data) ? "On" : "Off"); - break; - case MIDI_ALL_OFF: - printf("All Off Chan %2d\n", chan); - break; - case MIDI_OMNI_OFF: - printf("OmniOff Chan %2d\n", chan); - break; - case MIDI_OMNI_ON: - printf("Omni On Chan %2d\n", chan); - break; - case MIDI_MONO_ON: - printf("Mono On Chan %2d\n", chan); - if (Pm_MessageData2(data)) - printf(" to %d received channels\n", - Pm_MessageData2(data)); - else - printf(" to all received channels\n"); - break; - case MIDI_POLY_ON: - printf("Poly On Chan %2d\n", chan); - break; - } - } - } - } - } else if (command == MIDI_POLY_TOUCH) { - if (bender) { - showbytes(data, 3, verbose); - if (verbose) { - printf("P.Touch Chan %2d Key %2d ", chan, - Pm_MessageData1(data)); - len = put_pitch(Pm_MessageData1(data)); - printf(val_format + len, Pm_MessageData2(data)); - } - } - } else if (command == MIDI_TOUCH) { - if (bender) { - showbytes(data, 2, verbose); - if (verbose) { - printf(" A.Touch Chan %2d Val %2d\n", chan, - Pm_MessageData1(data)); - } - } - } else if (command == MIDI_BEND) { - if (bender) { - showbytes(data, 3, verbose); - if (verbose) { - printf("P.Bend Chan %2d Val %2d\n", chan, - (Pm_MessageData1(data) + (Pm_MessageData2(data)<<7))); - } - } - } else if (Pm_MessageStatus(data) == MIDI_SONG_POINTER) { - showbytes(data, 3, verbose); - if (verbose) { - printf(" Song Position %d\n", - (Pm_MessageData1(data) + (Pm_MessageData2(data)<<7))); - } - } else if (Pm_MessageStatus(data) == MIDI_SONG_SELECT) { - showbytes(data, 2, verbose); - if (verbose) { - printf(" Song Select %d\n", Pm_MessageData1(data)); - } - } else if (Pm_MessageStatus(data) == MIDI_TUNE_REQ) { - showbytes(data, 1, verbose); - if (verbose) { - printf(" Tune Request\n"); - } - } else if (Pm_MessageStatus(data) == MIDI_Q_FRAME) { - if (realdata) { - showbytes(data, 2, verbose); - if (verbose) { - printf(" Time Code Quarter Frame Type %d Values %d\n", - (Pm_MessageData1(data) & 0x70) >> 4, - Pm_MessageData1(data) & 0xf); - } - } - } else if (Pm_MessageStatus(data) == MIDI_START) { - if (realdata) { - showbytes(data, 1, verbose); - if (verbose) { - printf(" Start\n"); - } - } - } else if (Pm_MessageStatus(data) == MIDI_CONTINUE) { - if (realdata) { - showbytes(data, 1, verbose); - if (verbose) { - printf(" Continue\n"); - } - } - } else if (Pm_MessageStatus(data) == MIDI_STOP) { - if (realdata) { - showbytes(data, 1, verbose); - if (verbose) { - printf(" Stop\n"); - } - } - } else if (Pm_MessageStatus(data) == MIDI_SYS_RESET) { - if (realdata) { - showbytes(data, 1, verbose); - if (verbose) { - printf(" System Reset\n"); - } - } - } else if (Pm_MessageStatus(data) == MIDI_TIME_CLOCK) { - clockcount++; - if (clksencnt) { - showbytes(data, 1, verbose); - if (verbose) { - printf(" Clock\n"); - } - } - } else if (Pm_MessageStatus(data) == MIDI_ACTIVE_SENSING) { - actsensecount++; - if (clksencnt) { - showbytes(data, 1, verbose); - if (verbose) { - printf(" Active Sensing\n"); - } - } - } else showbytes(data, 3, verbose); - fflush(stdout); -} - - -/**************************************************************************** -* put_pitch -* Inputs: -* int p: pitch number -* Effect: write out the pitch name for a given number -****************************************************************************/ - -private int put_pitch(int p) -{ - char result[8]; - static char *ptos[] = { - "c", "cs", "d", "ef", "e", "f", "fs", "g", - "gs", "a", "bf", "b" }; - /* note octave correction below */ - sprintf(result, "%s%d", ptos[p % 12], (p / 12) - 1); - fputs(result, stdout); - return (int) strlen(result); -} - - -/**************************************************************************** -* showbytes -* Effect: print hex data, precede with newline if asked -****************************************************************************/ - -char nib_to_hex[] = "0123456789ABCDEF"; - -private void showbytes(PmMessage data, int len, boolean newline) -{ - int count = 0; - int i; - -/* if (newline) { - putchar('\n'); - count++; - } */ - for (i = 0; i < len; i++) { - putchar(nib_to_hex[(data >> 4) & 0xF]); - putchar(nib_to_hex[data & 0xF]); - count += 2; - if (count > 72) { - putchar('.'); - putchar('.'); - putchar('.'); - break; - } - data >>= 8; - } - putchar(' '); -} - - - -/**************************************************************************** -* showhelp -* Effect: print help text -****************************************************************************/ - -private void showhelp() -{ - printf("\n"); - printf(" Item Reported Range Item Reported Range\n"); - printf(" ------------- ----- ------------- -----\n"); - printf(" Channels 1 - 16 Programs 1 - 128\n"); - printf(" Controllers 0 - 127 After Touch 0 - 127\n"); - printf(" Loudness 0 - 127 Pitch Bend 0 - 16383, " - "center = 8192\n"); - printf(" Pitches 0 - 127, 60 = c4 = middle C\n"); - printf(" \n"); - printf("n toggles notes"); - showstatus(notes); - printf("t displays noteon count since last t\n"); - printf("b toggles pitch bend, aftertouch"); - showstatus(bender); - printf("c toggles continuous control"); - showstatus(controls); - printf("h toggles program changes"); - showstatus(pgchanges); - printf("x toggles system exclusive"); - showstatus(excldata); - printf("k toggles clock and sense messages, clears counts"); - showstatus(clksencnt); - printf("r toggles other real time messages & SMPTE"); - showstatus(realdata); - printf("s displays clock and sense count since last k\n"); - printf("m toggles channel mode messages"); - showstatus(chmode); - printf("v toggles verbose text"); - showstatus(verbose); - printf("q quits\n"); - printf("\n"); -} - -/**************************************************************************** -* showstatus -* Effect: print status of flag -****************************************************************************/ - -private void showstatus(boolean flag) -{ - printf(", now %s\n", flag ? "ON" : "OFF"); -} -- cgit v1.2.3