home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
MM1
/
SOUNDUTILS
/
tracker.4.6.lzh
/
TRACKER4.6
/
Nextstep
/
audio.c
Wrap
Text File
|
1994-11-24
|
6KB
|
287 lines
/* Nextstep/audio.c crufted together by Frank Siegert */
/* derived from the linux source */
#include "defs.h"
#ifdef MALLOC_NOT_IN_STDLIB
#include <malloc.h> /* there is no malloc.h in NS */
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "extern.h"
/* Start NeXT defines */
#include <sound/sound.h>
#include <sys/resource.h>
#import <mach/cthreads.h>
#import <mach/mach.h>
#import <mach/message.h>
mutex_t waitMutex;
condition_t waitCondition;
#define MAXSOUND 4 /* number of independent
sound frames */
#define MAXSAMPLE 16*1024 /* size of a frame 16kByte*/
#define MARKEDFREE 0 /* marker for unused frame */
#define MARKEDBUSY 1 /* marker for used frame */
SNDSoundStruct *blubber[MAXSOUND]; /* array of sound frames */
char *fillSound; /* current fill point */
int fillCount; /* fill frame counter */
int actualSample=0; /* frame to be filled up */
int played=0;
int lastFreed; /* last sample freed */
/* End NeXT defines */
/*********************************************************************
********/
/* soundEnd is called by the soundplayer when a sound finished
playing */
/*********************************************************************
********/
int soundEnd(SNDSoundStruct *s, int tag, int err)
{
mutex_lock(waitMutex);
lastFreed=tag-1;
s->info[0]=MARKEDFREE;
played--;
mutex_unlock(waitMutex);
condition_signal(waitCondition);
return (0);
}
/*********************************************************************
********/
/* play is called by nextSample to put the current frame to the sound
queue */
/*********************************************************************
********/
void play(SNDSoundStruct *theSound, int SoundTag)
{
int err;
theSound ->info[0]=MARKEDBUSY;
played++;
err =
SNDStartPlaying(theSound,SoundTag+1,63,0,0,(SNDNotificationFun)soundEn
d);
if (err) {
exit(0);
}
return;
}
/*********************************************************************
********/
/* nextSample plays the current Sample and tries to get a unused one,
*/
/* it waits until a frame is avaiable
*/
/*********************************************************************
********/
char *nextSample()
{
play(blubber[actualSample],actualSample); /* play
current */
actualSample++; /* next frame
*/
if (actualSample>=MAXSOUND) { /* reached
end of frames */
actualSample=0; /* back to
the beginning */
}
mutex_lock(waitMutex);
while (blubber[actualSample]->info[0]==MARKEDBUSY) {
condition_wait(waitCondition, waitMutex);
}
mutex_unlock(waitMutex);
/* wait for free */
return (char
*)((int)blubber[actualSample]+sizeof(SNDSoundStruct));
}
ID("$Id: audio.c,v 4.0 1994/01/11 17:59:57 espie Exp espie $")
LOCAL unsigned char *buffer; /* buffer for ready-to-play
samples */
LOCAL unsigned short *buffer16; /* Sure this isn't unsigned
short ? */
LOCAL int buf_index; /* index conflicts with
index(3) */
LOCAL int buf_max;
LOCAL int audio; /* /dev/dsp */
LOCAL int stereo; /* are we
playing stereo or not ? */
/* 256th of primary/secondary source for that side. */
LOCAL int primary=512, secondary=0;
LOCAL int dsp_samplesize = 16; /* must be 8 or 16 */
void set_mix(percent)
int percent;
{
percent *= 256; /* NS not used yet */
percent /= 100;
primary = percent;
secondary = 512 - percent;
}
int open_audio(f, s)
int f;
int s;
{
int loop;
waitMutex=mutex_alloc();
waitCondition=condition_alloc();
/********************************************************************
***/
/* create some Sound structures in mem big enougth to hold a
*/
/* a significant amount of sound data
*/
for (loop=0;loop<MAXSOUND;loop++) {
blubber[loop]=(SNDSoundStruct*)
calloc(sizeof(SNDSoundStruct)+(MAXSAMPLE*2)+16,1); /* must be more
than MAXSAMPLE */
blubber[loop]->magic=SND_MAGIC;
blubber[loop]->dataLocation=sizeof(SNDSoundStruct);
blubber[loop]->dataSize=0;
blubber[loop]->dataFormat=SND_FORMAT_LINEAR_16; /* 8
bit linear */
blubber[loop]->samplingRate=SND_RATE_HIGH; /* 44
kHz */
blubber[loop]->channelCount=2;
if (!s) blubber[loop]->channelCount=1;
blubber[loop]->info[0]=MARKEDFREE;
}
fillCount=0;
actualSample=0;
lastFreed=0;
fillSound=(char
*)((int)blubber[actualSample]+sizeof(SNDSoundStruct)); /* start of
data area */
task_priority(task_self(), 18, TRUE); /*
set our priority to high */
SNDSetFilter(0); /*
low pass filter ON */
stereo = s;
dsp_samplesize=16;
f = 44100;
buf_max=MAXSAMPLE*2;
buffer = fillSound;
buffer16 = (short *)buffer;
buf_index = 0;
return f;
}
LOCAL void actually_flush_buffer()
{
int l,i;
l = sizeof(*buffer) * buf_index;
if (dsp_samplesize !=8) l *= 2;
blubber[actualSample]->dataSize=l;
buffer16=buffer=nextSample();
buf_index = 0;
}
void output_samples(left, right)
int left, right;
{
if (dsp_samplesize != 8) /* Cool! 16 bits/sample */
{
if (stereo)
{
if (buf_index * 2 >= buf_max - 1)
actually_flush_buffer();
buffer16[buf_index++] =
left>>8; /* YAKK! I have not
figured
out why I need
this shift
Without it sounds
like a
hoard of crazy
daemons */
buffer16[buf_index++] =
right>>8;
}
else
{
if (buf_index * 2 >= buf_max)
actually_flush_buffer();
buffer16[buf_index++] = (left + right)>>8;
}
}
else
{
if (stereo)
{
if (buf_index >= buf_max - 1)
actually_flush_buffer();
buffer[buf_index++] =
left>>8;
buffer[buf_index++] =
right>>8;
}
else
{
if (buf_index >= buf_max)
actually_flush_buffer();
buffer[buf_index++] = ((left + right) >> 8);
}
}
}
void flush_buffer()
{ /* Dummy version */
}
void close_audio()
{
actually_flush_buffer();
free(buffer);
}
void set_synchro(s)
{
}
int update_frequency()
{
return 0;
}
void discard_buffer()
{
}