blob: f3582a42cf7bfd1a5245e7a8afb004497b8e5e44 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
/* pmutil.c -- some helpful utilities for building midi
applications that use PortMidi
*/
#include "stdlib.h"
#include "memory.h"
#include "portmidi.h"
#include "pmutil.h"
#include "pminternal.h"
PmQueue *Pm_QueueCreate(long num_msgs, long bytes_per_msg)
{
PmQueueRep *queue = (PmQueueRep *) malloc(sizeof(PmQueueRep));
if (!queue) return NULL;
queue->len = num_msgs * bytes_per_msg;
queue->buffer = malloc(queue->len);
if (!queue->buffer) {
free(queue);
return NULL;
}
queue->head = 0;
queue->tail = 0;
queue->msg_size = bytes_per_msg;
queue->overflow = FALSE;
return queue;
}
PmError Pm_QueueDestroy(PmQueue *q)
{
PmQueueRep *queue = (PmQueueRep *) q;
if (!queue || !queue->buffer) return pmBadPtr;
free(queue->buffer);
free(queue);
return pmNoError;
}
PmError Pm_Dequeue(PmQueue *q, void *msg)
{
long head;
PmQueueRep *queue = (PmQueueRep *) q;
if (queue->overflow) {
queue->overflow = FALSE;
return pmBufferOverflow;
}
head = queue->head; /* make sure this is written after access */
if (head == queue->tail) return 0;
memcpy(msg, queue->buffer + head, queue->msg_size);
head += queue->msg_size;
if (head == queue->len) head = 0;
queue->head = head;
return 1; /* success */
}
/* source should not enqueue data if overflow is set */
/**/
PmError Pm_Enqueue(PmQueue *q, void *msg)
{
PmQueueRep *queue = (PmQueueRep *) q;
long tail = queue->tail;
memcpy(queue->buffer + tail, msg, queue->msg_size);
tail += queue->msg_size;
if (tail == queue->len) tail = 0;
if (tail == queue->head) {
queue->overflow = TRUE;
/* do not update tail, so message is lost */
return pmBufferOverflow;
}
queue->tail = tail;
return pmNoError;
}
int Pm_QueueFull(PmQueue *q)
{
PmQueueRep *queue = (PmQueueRep *) q;
long tail = queue->tail;
tail += queue->msg_size;
if (tail == queue->len) {
tail = 0;
}
return (tail == queue->head);
}
|