1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-09 16:13:41 +02:00
Files
.github
autotools
cmake-proxies
dox2-src
help
images
include
lib-src
FileDialog
expat
ffmpeg
header-substitutes
lame
lib-widget-extra
libflac
libid3tag
libmad
libnyquist
autotools
nyquist
cmt
cext.c
cext.h
cleanup.c
cleanup.h
cmdline.c
cmdline.h
cmtcmd.c
cmtcmd.h
cmtio.c
cmtio.h
hash.h
hashrout.h
mem.c
mem.h
mfmidi.h
midibuff.h
midicode.h
midierr.h
midifile.c
midifile.h
midifns.c
midifns.h
midimgr.c
midimgr.h
moxc.c
moxc.h
musiprog.h
pitch.h
record.c
record.h
seq.c
seq.h
seqdecls.h
seqmread.c
seqmread.h
seqmwrite.c
seqmwrite.h
seqread.c
seqread.h
seqwrite.c
seqwrite.h
swlogic.h
tempomap.c
tempomap.h
timebase.c
timebase.h
userio.c
userio.h
ffts
nyqsrc
nyqstk
sys
tran
xlisp
Readme.txt
license.txt
LICENSE.txt
Makefile.am
Makefile.in
README.txt
configure
configure.ac
nyquist.patch
nyx.c
nyx.h
revert-convolve.patch
sound.patch
xlextstart.c
xlisp.patch
libogg
libscorealign
libsndfile
libsoxr
libvamp
libvorbis
lv2
mod-null
mod-nyq-bench
mod-script-pipe
mod-track-panel
portaudio-v19
portburn
portmidi
portmixer
portsmf
sbsms
soundtouch
twolame
CMakeLists.txt
Makefile.am
Makefile.in
audacity-patches.txt
dist-libsoxr.mk
dist-libvamp.mk
dist-portaudio.mk
locale
m4
mac
nyq-po
nyquist
plug-ins
presets
qa
scripts
src
tests
win
.gitattributes
.gitignore
.travis.yml
ABOUT-NLS
CHANGELOG.txt
CMakeLists.txt
CODE_OF_CONDUCT.md
CONTRIBUTING.md
INSTALL
LICENSE.txt
Makefile.am
Makefile.in
PULL_REQUEST_TEMPLATE.md
README.txt
appveyor.yml
audacity.dox
configure
configure.ac
todo.txt
audacity/lib-src/libnyquist/nyquist/cmt/timebase.c
2010-01-24 09:19:39 +00:00

323 lines
9.6 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* timebase.c -- management of calls, time bases and heaps for moxc */
/*****************************************************************************
* Change Log
* Date | Change
*-----------+-----------------------------------------------------------------
* 2-Apr-91 | JDW : further changes
* 21-Mar-92 | GWL : abort recovery
* 28-Apr-03 | DM : true->TRUE
*****************************************************************************/
#include "stdio.h"
#include "cext.h"
#include "userio.h"
#include "midifns.h"
#include "timebase.h"
#include "moxc.h"
timebase_type timebase_queue = NULL; /* waiting to run timebase queue */
call_type callfree = NULL; /* free list */
private void fatal();
/****************************************************************************
* timebase_create
* Inputs:
* maxsize is the initial size of the heap
* Outputs:
* returns an initialized timebase_type
****************************************************************************/
timebase_type timebase_create(maxsize)
int maxsize;
{
static char *error_msg = "Out of memory in timebase_create()";
timebase_type base = (timebase_type) memget(sizeof(timebase_node));
if (!base) fatal(error_msg);
base->next = NULL;
base->next_time = MAXTIME;
base->virt_base = 0L;
base->real_base = 0L;
base->rate = 256L;
base->heap_size = 0;
base->heap_max = maxsize;
base->heap = (call_type *) memget(sizeof(call_type) * maxsize);
if (!base->heap) fatal(error_msg);
return base;
}
/****************************************************************************
* callinsert
* Inputs:
* timebase_type base: the time base and heap
* call_type call: the call to insert in heap
* Outputs:
none
* Implementation:
* linear insertion; to be changed to heap
****************************************************************************/
void callinsert(base, call)
timebase_type base;
call_type call;
{
int i;
register call_type *heap = base->heap;
/* handle overflow -- this should never be executed if the user
* gives the right initial heap size
*/
base->heap_size++;
if (base->heap_size >= base->heap_max) {
call_type *new_heap = (call_type *)
memget((base->heap_max << 1) * sizeof(call_type));
int i;
call_type *oldptr;
call_type *newptr;
if (!new_heap) {
gprintf(TRANS, "Out of space, can't allocate new heap\n");
EXIT(1);
}
oldptr = base->heap;
newptr = new_heap;
for (i = base->heap_max; i > 0; i--) *newptr++ = *oldptr++;
memfree((char *) heap, base->heap_max * sizeof(call_type));
base->heap = heap = new_heap;
base->heap_max = (base->heap_max << 1);
}
/* now do the heap insert */
i = base->heap_size;
while (i > 1) {
int parent = i >> 1;
if (heap[parent]->u.e.time < call->u.e.time ||
(heap[parent]->u.e.time == call->u.e.time &&
heap[parent]->u.e.priority <= call->u.e.priority)) break;
heap[i] = heap[parent];
i = parent;
}
heap[i] = call;
/* if next_time might change, reinsert base into queue */
if (heap[1] == call) {
remove_base(base);
insert_base(base);
}
}
/****************************************************************************
* callshow
* Inputs:
* calltype call: the call to show
* Effect:
* prints a description of call
* Assumes:
* call is not null
****************************************************************************/
void callshow(call)
call_type call;
{
int i;
gprintf(TRANS,"address: %lx\n", (ulong)call);
gprintf(TRANS,"time: %ld\n", call->u.e.time);
gprintf(TRANS,"routine: %lx\n", (ulong)call->u.e.routine);
gprintf(TRANS,"parameters:");
for (i = 0; i < MAX_CALL_ARGS; i++) {
gprintf(TRANS, " %d", call->u.e.p.arg[i]);
}
gprintf(TRANS, "\n");
}
/***************************************************************
* fatal
*
* Input : msg: a message to be displayed
* Effect: print message and exit program
***************************************************************/
private void fatal(msg)
char *msg;
{
gprintf(FATAL, msg);
EXIT(1);
}
/***************************************************************
* timebase_free
*
* Input : a time base
* Effect: deallocate the time base
***************************************************************/
void timebase_free(timebase)
timebase_type timebase;
{
remove_base(timebase);
if (timebase->heap) {
memfree((char *) timebase->heap,
(timebase->heap_max * sizeof(call_type)));
}
memfree((char *) timebase, sizeof(timebase_node));
}
/***************************************************************
* insert_base
*
* Input : a time base not in the list
* Effect: insert timebase at the appropriate spot in the list
* computes the next_time field from the top of the heap
***************************************************************/
void insert_base(timebase)
timebase_type timebase;
{
register timebase_type *ptr = &timebase_queue;
register time_type next_time = MAXTIME;
/* compute next_time */
if (timebase->heap_size != 0) {
register call_type call = timebase->heap[1];
/* virt to real calculation */
next_time = (virt_to_real_256(timebase, call->u.e.time) &
0xFFFFFF00) + call->u.e.priority;
/* gprintf(TRANS,
"insert next_time is %ld, vt %ld, rb %ld, vb %ld rt %ld\n",
next_time, timebase->heap[1]->u.e.time,
timebase->real_base, timebase->virt_base, timebase->rate);
*/
}
timebase->next_time = next_time;
if (next_time != MAXTIME) {
/* insert into the list */
while (TRUE) {
if (! *ptr) {
*ptr = timebase;
timebase->next = NULL;
return;
} else if ((*ptr)->next_time >= next_time) {
timebase->next = *ptr;
*ptr = timebase;
return;
} else ptr = &((*ptr)->next);
}
}
}
/***************************************************************
* remove_base
*
* Input : timebase
* Effect: if timebase is in the queue, remove it
***************************************************************/
void remove_base(timebase)
timebase_type timebase;
{
timebase_type *ptr = &timebase_queue;
while (*ptr) {
if (*ptr == timebase) {
*ptr = timebase->next;
return;
} else ptr = &((*ptr)->next);
}
}
/***************************************************************
* remove_call
*
* Input : a timebase -- passed as a global
* Assumes: a_timebase->heap_size > 0
* Returns: the earliest call in the queue
* Effect: removes the earliest call in the queue
***************************************************************/
call_type remove_call(timebase_type a_timebase)
{
register call_type *heap = a_timebase->heap;
call_type result = heap[1];
register call_type large;
int i = 1;
int child = i << 1;;
large = heap[a_timebase->heap_size--];
while (child <= a_timebase->heap_size) {
if (child + 1 <= a_timebase->heap_size) {
if (heap[child + 1]->u.e.time < heap[child]->u.e.time ||
(heap[child + 1]->u.e.time == heap[child]->u.e.time &&
heap[child + 1]->u.e.priority < heap[child]->u.e.priority))
child++;
}
/* child is now the index of the least child */
if (large->u.e.time < heap[child]->u.e.time ||
(large->u.e.time == heap[child]->u.e.time &&
large->u.e.priority <= heap[child]->u.e.priority)) break;
/* swap */
heap[i] = heap[child];
i = child;
child = i << 1;
}
heap[i] = large;
return result;
}
/***************************************************************
* set_rate
*
* Input : timebase and new rate
* Effect: makes the current rate of timebase be rate
***************************************************************/
void set_rate(base, rate)
timebase_type base;
time_type rate;
{
if (base == timebase) base->virt_base = virttime;
else base->virt_base = real_to_virt(base, eventtime);
base->real_base = eventtime;
base->rate = rate;
/* gprintf(TRANS, "new real_base %ld virt_base %ld\n",
base->real_base, base->virt_base);
*/
remove_base(base);
insert_base(base);
}
/***************************************************************
* set_virttime
*
* Input : virtual time
* Effect: makes the current virtual time of timebase be vtime
***************************************************************/
void set_virttime(base, vtime)
timebase_type base;
time_type vtime;
{
base->real_base = eventtime;
base->virt_base = vtime;
if (base == timebase) virttime = vtime;
remove_base(base);
insert_base(base);
}
/***************************************************************
* timebase_use
*
* Input : a timebase to use for scheduling
* Effect: sets up globals: timebase, virttime
***************************************************************/
void timebase_use(base)
register timebase_type base;
{
if (timebase != base) {
timebase = base;
virttime = real_to_virt(base, eventtime);
}
}