mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-10 08:33:36 +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:
@@ -1,7 +1,7 @@
|
||||
/* pmutil.c -- some helpful utilities for building midi
|
||||
applications that use PortMidi
|
||||
*/
|
||||
//#include <stdlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "portmidi.h"
|
||||
@@ -17,42 +17,37 @@
|
||||
#include "stdio.h"
|
||||
#endif
|
||||
|
||||
/* code is based on 4-byte words -- it should work on a 64-bit machine
|
||||
as long as a "long" has 4 bytes. This code could be generalized to
|
||||
be independent of the size of "long" */
|
||||
|
||||
typedef long int32;
|
||||
|
||||
typedef struct {
|
||||
long head;
|
||||
long tail;
|
||||
long len;
|
||||
long msg_size; /* number of int32 in a message including extra word */
|
||||
long overflow;
|
||||
long peek_overflow;
|
||||
int32 *buffer;
|
||||
int32 *peek;
|
||||
int peek_flag;
|
||||
int32_t msg_size; /* number of int32_t in a message including extra word */
|
||||
int32_t peek_overflow;
|
||||
int32_t *buffer;
|
||||
int32_t *peek;
|
||||
int32_t peek_flag;
|
||||
} PmQueueRep;
|
||||
|
||||
|
||||
PmQueue *Pm_QueueCreate(long num_msgs, long bytes_per_msg)
|
||||
PMEXPORT PmQueue *Pm_QueueCreate(long num_msgs, int32_t bytes_per_msg)
|
||||
{
|
||||
int int32s_per_msg = ((bytes_per_msg + sizeof(int32) - 1) &
|
||||
~(sizeof(int32) - 1)) / sizeof(int32);
|
||||
int32_t int32s_per_msg =
|
||||
(int32_t) (((bytes_per_msg + sizeof(int32_t) - 1) &
|
||||
~(sizeof(int32_t) - 1)) / sizeof(int32_t));
|
||||
PmQueueRep *queue = (PmQueueRep *) pm_alloc(sizeof(PmQueueRep));
|
||||
if (!queue) /* memory allocation failed */
|
||||
return NULL;
|
||||
|
||||
/* need extra word per message for non-zero encoding */
|
||||
queue->len = num_msgs * (int32s_per_msg + 1);
|
||||
queue->buffer = (int32 *) pm_alloc(queue->len * sizeof(int32));
|
||||
bzero(queue->buffer, queue->len * sizeof(int32));
|
||||
queue->buffer = (int32_t *) pm_alloc(queue->len * sizeof(int32_t));
|
||||
bzero(queue->buffer, queue->len * sizeof(int32_t));
|
||||
if (!queue->buffer) {
|
||||
pm_free(queue);
|
||||
return NULL;
|
||||
} else { /* allocate the "peek" buffer */
|
||||
queue->peek = (int32 *) pm_alloc(int32s_per_msg * sizeof(int32));
|
||||
queue->peek = (int32_t *) pm_alloc(int32s_per_msg * sizeof(int32_t));
|
||||
if (!queue->peek) {
|
||||
/* free everything allocated so far and return */
|
||||
pm_free(queue->buffer);
|
||||
@@ -60,7 +55,7 @@ PmQueue *Pm_QueueCreate(long num_msgs, long bytes_per_msg)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
bzero(queue->buffer, queue->len * sizeof(int32));
|
||||
bzero(queue->buffer, queue->len * sizeof(int32_t));
|
||||
queue->head = 0;
|
||||
queue->tail = 0;
|
||||
/* msg_size is in words */
|
||||
@@ -72,7 +67,7 @@ PmQueue *Pm_QueueCreate(long num_msgs, long bytes_per_msg)
|
||||
}
|
||||
|
||||
|
||||
PmError Pm_QueueDestroy(PmQueue *q)
|
||||
PMEXPORT PmError Pm_QueueDestroy(PmQueue *q)
|
||||
{
|
||||
PmQueueRep *queue = (PmQueueRep *) q;
|
||||
|
||||
@@ -87,12 +82,12 @@ PmError Pm_QueueDestroy(PmQueue *q)
|
||||
}
|
||||
|
||||
|
||||
PmError Pm_Dequeue(PmQueue *q, void *msg)
|
||||
PMEXPORT PmError Pm_Dequeue(PmQueue *q, void *msg)
|
||||
{
|
||||
long head;
|
||||
PmQueueRep *queue = (PmQueueRep *) q;
|
||||
int i;
|
||||
int32 *msg_as_int32 = (int32 *) msg;
|
||||
int32_t *msg_as_int32 = (int32_t *) msg;
|
||||
|
||||
/* arg checking */
|
||||
if (!queue)
|
||||
@@ -106,7 +101,7 @@ PmError Pm_Dequeue(PmQueue *q, void *msg)
|
||||
return pmBufferOverflow;
|
||||
}
|
||||
if (queue->peek_flag) {
|
||||
memcpy(msg, queue->peek, (queue->msg_size - 1) * sizeof(int32));
|
||||
memcpy(msg, queue->peek, (queue->msg_size - 1) * sizeof(int32_t));
|
||||
queue->peek_flag = FALSE;
|
||||
return pmGotData;
|
||||
}
|
||||
@@ -144,18 +139,18 @@ PmError Pm_Dequeue(PmQueue *q, void *msg)
|
||||
}
|
||||
}
|
||||
memcpy(msg, (char *) &queue->buffer[head + 1],
|
||||
sizeof(int32) * (queue->msg_size - 1));
|
||||
sizeof(int32_t) * (queue->msg_size - 1));
|
||||
/* fix up zeros */
|
||||
i = queue->buffer[head];
|
||||
while (i < queue->msg_size) {
|
||||
int32 j;
|
||||
int32_t j;
|
||||
i--; /* msg does not have extra word so shift down */
|
||||
j = msg_as_int32[i];
|
||||
msg_as_int32[i] = 0;
|
||||
i = j;
|
||||
}
|
||||
/* signal that data has been removed by zeroing: */
|
||||
bzero((char *) &queue->buffer[head], sizeof(int32) * queue->msg_size);
|
||||
bzero((char *) &queue->buffer[head], sizeof(int32_t) * queue->msg_size);
|
||||
|
||||
/* update head */
|
||||
head += queue->msg_size;
|
||||
@@ -166,7 +161,7 @@ PmError Pm_Dequeue(PmQueue *q, void *msg)
|
||||
|
||||
|
||||
|
||||
PmError Pm_SetOverflow(PmQueue *q)
|
||||
PMEXPORT PmError Pm_SetOverflow(PmQueue *q)
|
||||
{
|
||||
PmQueueRep *queue = (PmQueueRep *) q;
|
||||
long tail;
|
||||
@@ -181,14 +176,14 @@ PmError Pm_SetOverflow(PmQueue *q)
|
||||
}
|
||||
|
||||
|
||||
PmError Pm_Enqueue(PmQueue *q, void *msg)
|
||||
PMEXPORT PmError Pm_Enqueue(PmQueue *q, void *msg)
|
||||
{
|
||||
PmQueueRep *queue = (PmQueueRep *) q;
|
||||
long tail;
|
||||
int i;
|
||||
int32 *src = (int32 *) msg;
|
||||
int32 *ptr;
|
||||
int32 *dest;
|
||||
int32_t *src = (int32_t *) msg;
|
||||
int32_t *ptr;
|
||||
int32_t *dest;
|
||||
int rslt;
|
||||
if (!queue)
|
||||
return pmBadPtr;
|
||||
@@ -206,7 +201,7 @@ PmError Pm_Enqueue(PmQueue *q, void *msg)
|
||||
ptr = &queue->buffer[tail];
|
||||
dest = ptr + 1;
|
||||
for (i = 1; i < queue->msg_size; i++) {
|
||||
int32 j = src[i - 1];
|
||||
int32_t j = src[i - 1];
|
||||
if (!j) {
|
||||
*ptr = i;
|
||||
ptr = dest;
|
||||
@@ -223,7 +218,7 @@ PmError Pm_Enqueue(PmQueue *q, void *msg)
|
||||
}
|
||||
|
||||
|
||||
int Pm_QueueEmpty(PmQueue *q)
|
||||
PMEXPORT int Pm_QueueEmpty(PmQueue *q)
|
||||
{
|
||||
PmQueueRep *queue = (PmQueueRep *) q;
|
||||
return (!queue) || /* null pointer -> return "empty" */
|
||||
@@ -231,9 +226,9 @@ int Pm_QueueEmpty(PmQueue *q)
|
||||
}
|
||||
|
||||
|
||||
int Pm_QueueFull(PmQueue *q)
|
||||
PMEXPORT int Pm_QueueFull(PmQueue *q)
|
||||
{
|
||||
int tail;
|
||||
long tail;
|
||||
int i;
|
||||
PmQueueRep *queue = (PmQueueRep *) q;
|
||||
/* arg checking */
|
||||
@@ -250,10 +245,10 @@ int Pm_QueueFull(PmQueue *q)
|
||||
}
|
||||
|
||||
|
||||
void *Pm_QueuePeek(PmQueue *q)
|
||||
PMEXPORT void *Pm_QueuePeek(PmQueue *q)
|
||||
{
|
||||
PmError rslt;
|
||||
long temp;
|
||||
int32_t temp;
|
||||
PmQueueRep *queue = (PmQueueRep *) q;
|
||||
/* arg checking */
|
||||
if (!queue)
|
||||
|
Reference in New Issue
Block a user