1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-10 16:43:33 +02:00

Extensive changes to improve NoteTrack display and (some) editing, NoteTrack playback via MIDI, and Midi-to-Audio alignment.

This commit is contained in:
rbdannenberg
2010-09-18 21:02:36 +00:00
parent f6327602e8
commit a1f0e5ed5b
96 changed files with 5679 additions and 3566 deletions

View File

@@ -93,9 +93,9 @@ PtTimestamp previous_callback_time = 0;
int period; /* milliseconds per callback */
long histogram[HIST_LEN];
long max_latency = 0; /* worst latency observed */
long out_of_range = 0; /* how many points outside of HIST_LEN? */
int histogram[HIST_LEN];
int max_latency = 0; /* worst latency observed */
int out_of_range = 0; /* how many points outside of HIST_LEN? */
int test_in, test_out; /* test MIDI in and/or out? */
int output_period; /* output MIDI every __ iterations if test_out true */
@@ -199,7 +199,7 @@ int main()
i,
NULL,
INPUT_BUFFER_SIZE,
(long (*)(void *)) Pt_Time,
(PmTimestamp (*)(void *)) Pt_Time,
NULL);
/* turn on filtering; otherwise, input might overflow in the
5-second period before timer callback starts reading midi */
@@ -212,7 +212,7 @@ int main()
i,
NULL,
OUTPUT_BUFFER_SIZE,
(long (*)(void *)) Pt_Time,
(PmTimestamp (*)(void *)) Pt_Time,
NULL,
0); /* no latency scheduling */
@@ -252,11 +252,11 @@ int main()
/* avoid printing beyond last non-zero histogram entry */
len = min(HIST_LEN, max_latency + 1);
for (i = 0; i < len; i++) {
printf("%2d %10ld\n", i, histogram[i]);
printf("%2d %10d\n", i, histogram[i]);
}
printf("Number of points greater than %dms: %ld\n",
printf("Number of points greater than %dms: %d\n",
HIST_LEN - 1, out_of_range);
printf("Maximum latency: %ld milliseconds\n", max_latency);
printf("Maximum latency: %d milliseconds\n", max_latency);
printf("\nNote that due to rounding, actual latency can be 1ms higher\n");
printf("than the numbers reported here.\n");
printf("Type return to exit...");

View File

@@ -2,10 +2,11 @@
#include "portmidi.h"
#include "porttime.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "assert.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#ifndef false
#define false 0
@@ -23,7 +24,7 @@ typedef int boolean;
#define OUTPUT_BUFFER_SIZE 0
#define DRIVER_INFO NULL
#define TIME_PROC ((long (*)(void *)) Pt_Time)
#define TIME_PROC ((int32_t (*)(void *)) Pt_Time)
#define TIME_INFO NULL
#define LATENCY 0
#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
@@ -63,7 +64,7 @@ float tempo = 60.0F;
void timer_poll(PtTimestamp timestamp, void *userData)
{
static int callback_owns_portmidi = false;
static long clock_start_time = 0;
static PmTimestamp clock_start_time = 0;
static double next_clock_time = 0;
/* SMPTE time */
static int frames = 0;
@@ -103,7 +104,7 @@ void timer_poll(PtTimestamp timestamp, void *userData)
}
}
if (time_code_running) {
int data;
int data = 0; // initialization avoids compiler warning
if ((timestamp - smpte_start_time) < next_smpte_time)
return;
switch (mtc_count) {
@@ -212,9 +213,9 @@ private void doascii(char c)
int input_tempo = get_number("Enter new tempo (bpm): ");
if (input_tempo >= 1 && input_tempo <= 300) {
printf("Changing tempo to %d\n", input_tempo);
tempo = input_tempo;
tempo = (float) input_tempo;
} else {
printf("Tempo range is 1 to 300, current tempo is %d bpm\n",
printf("Tempo range is 1 to 300, current tempo is %g bpm\n",
tempo);
}
} else {

View File

@@ -73,7 +73,7 @@ int active = FALSE;
int monitor = FALSE;
int midi_thru = TRUE;
long transpose;
int transpose;
PmStream *midi_in;
PmStream *midi_out;
@@ -94,7 +94,7 @@ void process_midi(PtTimestamp timestamp, void *userData)
{
PmError result;
PmEvent buffer; /* just one message at a time */
long msg;
int32_t msg;
/* do nothing until initialization completes */
if (!active)
@@ -127,7 +127,7 @@ void process_midi(PtTimestamp timestamp, void *userData)
do {
result = Pm_Poll(midi_in);
if (result) {
long status, data1, data2;
int status, data1, data2;
if (Pm_Read(midi_in, &buffer, 1) == pmBufferOverflow)
continue;
if (midi_thru)
@@ -173,7 +173,7 @@ void exit_with_message(char *msg)
int main()
{
int id;
long n;
int32_t n;
const PmDeviceInfo *info;
char line[STRING_MAX];
int spin;
@@ -190,12 +190,12 @@ int main()
/* make the message queues */
/* messages can be of any size and any type, but all messages in
* a given queue must have the same size. We'll just use long's
* a given queue must have the same size. We'll just use int32_t's
* for our messages in this simple example
*/
midi_to_main = Pm_QueueCreate(32, sizeof(long));
midi_to_main = Pm_QueueCreate(32, sizeof(int32_t));
assert(midi_to_main != NULL);
main_to_midi = Pm_QueueCreate(32, sizeof(long));
main_to_midi = Pm_QueueCreate(32, sizeof(int32_t));
assert(main_to_midi != NULL);
/* a little test of enqueue and dequeue operations. Ordinarily,
@@ -263,7 +263,8 @@ int main()
"Must terminate with [ENTER]");
while (!done) {
long msg;
int32_t msg;
int input;
int len;
fgets(line, STRING_MAX, stdin);
/* remove the newline: */
@@ -284,7 +285,8 @@ int main()
do {
spin = Pm_Dequeue(midi_to_main, &msg);
} while (spin == 0); /* spin */ ;
printf("... pitch is %ld\n", msg);
// convert int32_t to long for safe printing
printf("... pitch is %ld\n", (long) msg);
} else if (strcmp(line, "t") == 0) {
/* reading midi_thru asynchronously could give incorrect results,
e.g. if you type "t" twice before the midi thread responds to
@@ -294,10 +296,11 @@ int main()
printf("Setting THRU %s\n", (midi_thru ? "off" : "on"));
msg = THRU_MSG;
Pm_Enqueue(main_to_midi, &msg);
} else if (sscanf(line, "%ld", &msg) == 1) {
if (msg >= -127 && msg <= 127) {
/* send transposition value */
printf("Transposing by %ld\n", msg);
} else if (sscanf(line, "%d", &input) == 1) {
if (input >= -127 && input <= 127) {
/* send transposition value, make sur */
printf("Transposing by %d\n", input);
msg = (int32_t) input;
Pm_Enqueue(main_to_midi, &msg);
} else {
printf("Transposition must be within -127...127\n");

View File

@@ -99,7 +99,7 @@ PmTimestamp last_timestamp = 0;
/* time proc parameter for Pm_MidiOpen */
long midithru_time_proc(void *info)
PmTimestamp midithru_time_proc(void *info)
{
return current_timestamp;
}
@@ -132,7 +132,7 @@ void process_midi(PtTimestamp timestamp, void *userData)
do {
result = Pm_Poll(midi_in);
if (result) {
long status;
int status;
PmError rslt = Pm_Read(midi_in, &buffer, 1);
if (rslt == pmBufferOverflow)
continue;
@@ -189,7 +189,7 @@ void process_midi(PtTimestamp timestamp, void *userData)
assert(next); /* must be non-null because queue is not empty */
if (next->timestamp <= current_timestamp) {
/* time to send a message, first make sure it's not blocked */
long status = Pm_MessageStatus(next->message);
int status = Pm_MessageStatus(next->message);
if ((status & 0xF8) == 0xF8) {
; /* real-time messages are not blocked */
} else if (thru_sysex_in_progress) {

View File

@@ -83,12 +83,12 @@ boolean chmode = true; /* show channel mode messages */
boolean pgchanges = true; /* show program changes */
boolean flush = false; /* flush all pending MIDI data */
long filter = 0; /* remember state of midi filter */
uint32_t filter = 0; /* remember state of midi filter */
long clockcount = 0; /* count of clocks */
long actsensecount = 0; /* cout of active sensing bytes */
long notescount = 0; /* #notes since last request */
long notestotal = 0; /* total #notes */
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";
@@ -102,11 +102,11 @@ extern int abort_flag;
* Routines local to this module
*****************************************************************************/
private void mmexit();
private void mmexit(int code);
private void output(PmMessage data);
private int put_pitch(int p);
private void showhelp();
private void showbytes(long data, int len, boolean newline);
private void showbytes(PmMessage data, int len, boolean newline);
private void showstatus(boolean flag);
private void doascii(char c);
private int get_number(char *prompt);
@@ -133,7 +133,7 @@ void receive_poll(PtTimestamp timestamp, void *userData)
PmEvent event;
int count;
if (!active) return;
while (count = Pm_Read(midi_in, &event, 1)) {
while ((count = Pm_Read(midi_in, &event, 1))) {
if (count == 1) output(event.message);
else printf(Pm_GetErrorText(count));
}
@@ -169,7 +169,7 @@ int main(int argc, char **argv)
if (err) {
printf(Pm_GetErrorText(err));
Pt_Stop();
exit(1);
mmexit(1);
}
Pm_SetFilter(midi_in, filter);
inited = true; /* now can document changes, set filter */
@@ -185,7 +185,8 @@ int main(int argc, char **argv)
Pm_Close(midi_in);
Pt_Stop();
Pm_Terminate();
exit(0);
mmexit(0);
return 0; // make the compiler happy be returning a value
}
@@ -240,7 +241,7 @@ private void doascii(char c)
if (clksencnt) {
if (inited)
printf("Clock Count %ld\nActive Sense Count %ld\n",
clockcount, actsensecount);
(long) clockcount, (long) actsensecount);
} else if (inited) {
printf("Clock Counting not on\n");
}
@@ -248,7 +249,7 @@ private void doascii(char c)
notestotal+=notescount;
if (inited)
printf("This Note Count %ld\nTotal Note Count %ld\n",
notescount, notestotal);
(long) notescount, (long) notestotal);
notescount=0;
} else if (c == 'v') {
verbose = !verbose;
@@ -272,12 +273,12 @@ private void doascii(char c)
private void mmexit()
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(1);
exit(code);
}
@@ -304,7 +305,7 @@ private void output(PmMessage data)
if (in_sysex || Pm_MessageStatus(data) == MIDI_SYSEX) {
#define sysex_max 16
int i;
long data_copy = data;
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
@@ -491,7 +492,7 @@ private int put_pitch(int p)
char nib_to_hex[] = "0123456789ABCDEF";
private void showbytes(long data, int len, boolean newline)
private void showbytes(PmMessage data, int len, boolean newline)
{
int count = 0;
int i;

View File

@@ -22,7 +22,7 @@ void print_msg(long msg[], int n)
{
int i;
for (i = 0; i < n; i++) {
printf(" %d", msg[i]);
printf(" %li", msg[i]);
}
}

View File

@@ -17,6 +17,7 @@
// need to get declaration for Sleep()
#include "windows.h"
#else
#include <unistd.h>
#define Sleep(n) usleep(n * 1000)
#endif
@@ -58,7 +59,7 @@ void loopback_test()
PmStream *midi_out;
unsigned char msg[1024];
char line[80];
long len;
int32_t len;
int i;
int data;
PmEvent event;
@@ -88,10 +89,10 @@ void loopback_test()
while (1) {
PmError count;
long start_time;
long error_position = -1; /* 0; -1; -1 for continuous */
long expected = 0;
long actual = 0;
int32_t start_time;
int error_position = -1; /* 0; -1; -1 for continuous */
int expected = 0;
int actual = 0;
/* this modification will run until an error is detected */
/* set error_position above to 0 for interactive, -1 for */
/* continuous */
@@ -124,7 +125,7 @@ void loopback_test()
}
/* send the message */
printf("Sending %ld byte sysex message.\n", len + 2);
printf("Sending %d byte sysex message.\n", len + 2);
Pm_WriteSysEx(midi_out, 0, msg);
/* receive the message and compare to msg[] */
@@ -156,7 +157,7 @@ void loopback_test()
}
}
if (error_position >= 0) {
printf("Error at byte %ld: sent %lx recd %lx\n", error_position,
printf("Error at byte %d: sent %x recd %x\n", error_position,
expected, actual);
} else if (i != len + 2) {
printf("Error: byte %d not received\n", i);
@@ -228,11 +229,11 @@ void send_multiple_test()
#define MAX_MSG_LEN 1024
static unsigned char receive_msg[MAX_MSG_LEN];
static long receive_msg_index;
static long receive_msg_length;
static long receive_msg_count;
static long receive_msg_error;
static long receive_msg_messages;
static int receive_msg_index;
static int receive_msg_length;
static int receive_msg_count;
static int receive_msg_error;
static int receive_msg_messages;
static PmStream *receive_msg_midi_in;
static int receive_poll_running;
@@ -316,7 +317,7 @@ void receive_multiple_test()
/* Important: start PortTime first -- if it is not started first, it will
be started by PortMidi, and then our attempt to open again will fail */
receive_poll_running = false;
if (err = Pt_Start(1, receive_poll, 0)) {
if ((err = Pt_Start(1, receive_poll, 0))) {
printf("PortTime error code: %d\n", err);
goto cleanup;
}

View File

@@ -8,13 +8,13 @@
#define INPUT_BUFFER_SIZE 100
#define OUTPUT_BUFFER_SIZE 0
#define DRIVER_INFO NULL
#define TIME_PROC ((long (*)(void *)) Pt_Time)
#define TIME_PROC ((int32_t (*)(void *)) Pt_Time)
#define TIME_INFO NULL
#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */
#define STRING_MAX 80 /* used for console input */
long latency = 0;
int32_t latency = 0;
/* crash the program to test whether midi ports are closed */
/**/
@@ -87,10 +87,10 @@ void main_test_input(unsigned int somethingStupid) {
if (length > 0) {
printf("Got message %d: time %ld, %2lx %2lx %2lx\n",
i,
buffer[0].timestamp,
Pm_MessageStatus(buffer[0].message),
Pm_MessageData1(buffer[0].message),
Pm_MessageData2(buffer[0].message));
(long) buffer[0].timestamp,
(long) Pm_MessageStatus(buffer[0].message),
(long) Pm_MessageData1(buffer[0].message),
(long) Pm_MessageData2(buffer[0].message));
i++;
} else {
assert(0);
@@ -116,7 +116,7 @@ void main_test_input(unsigned int somethingStupid) {
void main_test_output() {
PmStream * midi;
char line[80];
long off_time;
int32_t off_time;
int chord[] = { 60, 67, 76, 83, 90 };
#define chord_size 5
PmEvent buffer[chord_size];
@@ -139,7 +139,7 @@ void main_test_output() {
(latency == 0 ? NULL : TIME_PROC),
(latency == 0 ? NULL : TIME_INFO),
latency);
printf("Midi Output opened with %ld ms latency.\n", latency);
printf("Midi Output opened with %ld ms latency.\n", (long) latency);
/* output note on/off w/latency offset; hold until user prompts */
printf("ready to send program 1 change... (type RETURN):");
@@ -230,7 +230,7 @@ void main_test_both()
TIME_PROC,
TIME_INFO,
latency);
printf("Midi Output opened with %ld ms latency.\n", latency);
printf("Midi Output opened with %ld ms latency.\n", (long) latency);
/* open input device */
Pm_OpenInput(&midi,
in,
@@ -253,11 +253,11 @@ void main_test_both()
if (length > 0) {
Pm_Write(midiOut, buffer, 1);
printf("Got message %d: time %ld, %2lx %2lx %2lx\n",
i,
buffer[0].timestamp,
Pm_MessageStatus(buffer[0].message),
Pm_MessageData1(buffer[0].message),
Pm_MessageData2(buffer[0].message));
i,
(long) buffer[0].timestamp,
(long) Pm_MessageStatus(buffer[0].message),
(long) Pm_MessageData1(buffer[0].message),
(long) Pm_MessageData2(buffer[0].message));
i++;
} else {
assert(0);
@@ -301,7 +301,7 @@ void main_test_stream() {
TIME_PROC,
TIME_INFO,
latency);
printf("Midi Output opened with %ld ms latency.\n", latency);
printf("Midi Output opened with %ld ms latency.\n", (long) latency);
/* output note on/off w/latency offset; hold until user prompts */
printf("ready to send output... (type RETURN):");
@@ -386,25 +386,32 @@ int main(int argc, char *argv[])
int stream_test = 0;
int latency_valid = FALSE;
if (sizeof(void *) == 8)
printf("Apparently this is a 64-bit machine.\n");
else if (sizeof(void *) == 4)
printf ("Apparently this is a 32-bit machine.\n");
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0) {
show_usage();
} else if (strcmp(argv[i], "-l") == 0 && (i + 1 < argc)) {
i = i + 1;
latency = atoi(argv[i]);
printf("Latency will be %ld\n", latency);
latency_valid = TRUE;
printf("Latency will be %ld\n", (long) latency);
latency_valid = TRUE;
} else {
show_usage();
}
}
while (!latency_valid) {
printf("Latency in ms: ");
if (scanf("%ld", &latency) == 1) {
latency_valid = TRUE;
}
}
while (!latency_valid) {
int lat; // declared int to match "%d"
printf("Latency in ms: ");
if (scanf("%d", &lat) == 1) {
latency = (int32_t) lat; // coerce from "%d" to known size
latency_valid = TRUE;
}
}
/* determine what type of test to run */
printf("begin portMidi test...\n");
@@ -413,7 +420,7 @@ int main(int argc, char *argv[])
" 2: test input (fail w/assert)\n",
" 3: test input (fail w/NULL assign)\n",
" 4: test output\n 5: test both\n",
" 6: stream test\n");
" 6: stream test\n");
while (n != 1) {
n = scanf("%d", &i);
fgets(line, STRING_MAX, stdin);