Пример #1
0
/*
===============
S_Callback
===============
*/
void S_Callback( SndChannel *sc, SndCommand *cmd ) {
	SndCommand		mySndCmd;
	SndCommand		mySndCmd2;
	int				offset;
	
	offset = ( s_chunkCount * SUBMISSION_CHUNK ) & (MAX_MIXED_SAMPLES-1);
	
	// queue up another sound buffer
	memset( &s_sndHeader, 0, sizeof( s_sndHeader ) );
	s_sndHeader.samplePtr = (void *)(s_mixedSamples + offset);
	s_sndHeader.numChannels = 2;
	s_sndHeader.sampleRate = rate22khz;
	s_sndHeader.loopStart = 0;
	s_sndHeader.loopEnd = 0;
	s_sndHeader.encode = extSH;
	s_sndHeader.baseFrequency = 1;
	s_sndHeader.numFrames = SUBMISSION_CHUNK / 2;
	s_sndHeader.markerChunk = NULL;
	s_sndHeader.instrumentChunks = NULL;
	s_sndHeader.AESRecording = NULL;
	s_sndHeader.sampleSize = 16;
	
	mySndCmd.cmd = bufferCmd;
	mySndCmd.param1 = 0;
	mySndCmd.param2 = (int)&s_sndHeader;
	SndDoCommand( sc, &mySndCmd, true );
	
	// and another callback
	mySndCmd2.cmd = callBackCmd;
	mySndCmd2.param1 = 0;
	mySndCmd2.param2 = 0;
	SndDoCommand( sc, &mySndCmd2, true );

	s_chunkCount++;		// this is the next buffer we will submit
}
Пример #2
0
static void fill_sound (SndChannel *chan, SndCommand *cmd_passed)
{
	UINT32 fill_me, play_me;
	SndCommand cmd;

	fill_me = cmd_passed->param2;
	play_me = !fill_me;

	header.samplePtr = (Ptr)buffer[play_me];
	cmd.cmd = bufferCmd;
	cmd.param1 = 0;
	cmd.param2 = (long) &header;

	SndDoCommand (chan, &cmd, 0);

	memset (buffer[fill_me], 0, BUFFER_SIZE << 1);

	play_sound();
	mix_sound();
	
	memcpy (buffer[fill_me], sarienbuf, BUFFER_SIZE << 1);

	cmd.cmd = callBackCmd;
	cmd.param1 = 0;
	cmd.param2 = play_me;

	SndDoCommand (chan, &cmd, 0);	
}
Пример #3
0
pascal void playbackCallback(SndChannelPtr channel, SndCommand *theCallBackCmd)
{
  buffer_state *data = (buffer_state *)(theCallBackCmd->param2);
  
  if (data->busy) {
    SndDoCommand(channel, &data->callCmd, true);
    return;
  }
  
  data->busy = 1;

  // If there's data in the second buffer, copy it into the playback buffer
  // and mark the second buffer as empty again.

  if (data->curBuffer == 1 && data->curSize>0) {
    int bytes = data->curSize;

    if (bytes > data->bufferSize)
      bytes = data->bufferSize;

    BlockMove((Ptr)data->nextBuffer, (Ptr)data->buffer, bytes); 
    if (bytes != data->curSize)
      BlockMove((Ptr)&data->nextBuffer[bytes], (Ptr)data->nextBuffer, data->curSize - bytes);
       
    data->header.numFrames = bytes / data->frameSize;
    
    data->curSize -= bytes;
  }
  else {
  
    // Otherwise, either we're finished playing or we're stalling
  
    if (!data->flushing) {
      // Send some silence through the speaker while we wait for
      // the program to catch up
      
      int waittime = 4096;
      int i;
      
      if (waittime > data->bufferSize)
        waittime = data->bufferSize;
      
      for(i=0; i<waittime / 2; i++)
          ((short *)data->buffer)[i] = 0;
      data->header.numFrames = waittime / data->frameSize;
    }
  }
  
  data->busy = 0;

  if (!data->flushing) {
    SndDoCommand(channel, &data->playCmd, true);
    SndDoCommand(channel, &data->callCmd, true);
  }
}
Пример #4
0
static BOOL SoundBuffer_Init(UINT rate, UINT samples) {

	QSOUND			qs;
	double			drate;
	extended80		extFreq;
	UINT			buffersize;
	int				i;
	ExtSoundHeader	*buf;

	qs = &QSound;
	qs->rate = rate;
	qs->samples = samples;
	buffersize = samples * 4;
	qs->buffersize = buffersize;
	drate = rate;
	dtox80(&drate, &extFreq);

#if !defined(SOUND_CRITICAL)
	qs->extendbuffer = (SINT16 *)_MALLOC(buffersize, "Extend buffer");
	if (qs->extendbuffer == NULL) {
		goto sbinit_err;
	}
#endif

	buffersize += sizeof(ExtSoundHeader);
	for (i=0; i<SOUNDBUFFERS; i++) {
		buf = (ExtSoundHeader *)_MALLOC(buffersize, "ExtSoundHeader");
		qs->buf[i] = buf;
		if (buf == NULL) {
			goto sbinit_err;
		}
		ZeroMemory(buf, buffersize);
		buf->numChannels = 2;
		buf->sampleRate = (UInt32)rate << 16;
		buf->encode = extSH;
		buf->numFrames = samples;
		buf->AIFFSampleRate = extFreq;
		buf->sampleSize = 16;

		qs->cmd[i].cmd = bufferCmd;
		qs->cmd[i].param2 = (SInt32)buf;
		qs->cbcmd[i].cmd = callBackCmd;
		qs->cbcmd[i].param1 = (i + 1) % SOUNDBUFFERS;
	}

	QS_Avail = TRUE;
	SndDoCommand(qs->hdl, &qs->cmd[0], TRUE);
	SndDoCommand(qs->hdl, &qs->cbcmd[0], TRUE);
	return(SUCCESS);

sbinit_err:
	return(FAILURE);
}
Пример #5
0
static pascal void MyDoubleBackProc(SndChannelPtr chan,SndCommand *doubleBuffer)
{
	char *myPtr;			
	MADDriverRec *intDriver;
	SndCommand mySndCmd;
	
#if _DEBUG && defined(__POWERPC__) && !_SHAREDLIB
	SLEnterInterrupt();
#endif

	intDriver = (MADDriverRec*) chan->userInfo;

	/********************/
	/**   Read Notes   **/
	/********************/
	
	myPtr = intDriver->IntDataPtr;		/* Save the pointer */
	intDriver->IntDataPtr = (char*) intDriver->SndBuffer;
	
	NoteAnalyse(intDriver);				/* Decompress */
	intDriver->IntDataPtr = myPtr;		/* Restore the pointer */

	intDriver->SndHeader.samplePtr = (char *)intDriver->SndBuffer;
	intDriver->SndHeader.numChannels = 2;
	intDriver->SndHeader.sampleRate = intDriver->DriverSettings.outPutRate;
	intDriver->SndHeader.loopStart = 0;
	intDriver->SndHeader.loopEnd = 0;
	intDriver->SndHeader.encode = extSH;
	intDriver->SndHeader.baseFrequency = 0;
	intDriver->SndHeader.numFrames = intDriver->ASCBUFFER;
	intDriver->SndHeader.markerChunk = NULL;
	intDriver->SndHeader.instrumentChunks = NULL;
	intDriver->SndHeader.AESRecording = NULL;
	intDriver->SndHeader.sampleSize = intDriver->DriverSettings.outPutBits;

	mySndCmd.cmd = bufferCmd;
	mySndCmd.param1 = 0;
	mySndCmd.param2 = (int)&intDriver->SndHeader;
	SndDoCommand(chan,&mySndCmd,TRUE);
	
	// and another callback
	mySndCmd.cmd = callBackCmd;
	mySndCmd.param1 = 0;
	mySndCmd.param2 = 0;
	SndDoCommand(chan,&mySndCmd,TRUE);

#if _DEBUG && defined(__POWERPC__)  && !_SHAREDLIB
	SLLeaveInterrupt();
#endif
}
Пример #6
0
static
int soundcmd(enum mode mode, unsigned short cmd, short param1, long param2)
{
  SndCommand command;

  command.cmd    = cmd;
  command.param1 = param1;
  command.param2 = param2;

  switch (mode) {
  case IMMEDIATE:
    if (SndDoImmediate(channel, &command) != noErr) {
      audio_error = _("SndDoImmediate() failed");
      return -1;
    }
    break;

  case QUEUE:
    if (SndDoCommand(channel, &command, FALSE) != noErr) {
      audio_error = _("SndDoCommand() failed");
      return -1;
    }
    break;
  }

  return 0;
}
Пример #7
0
static pascal void SMCallBackFunc(SndChannelPtr chan, SndCommand *cmd)
{
	ExtSoundHeader *theHeader = NULL;
	NAudioUnit* pAPU = (NAudioUnit*)cmd->param2;

	// check if we should stop
	if(!pAPU->IsRunning())
	{
		SndCommand flush = {flushCmd, 0, 0};
		SndDoImmediate(chan, &flush);

		SndCommand quiet   = {quietCmd, 0, 0};
		SndDoImmediate(chan, &quiet);

		return;
	}

	// render audio, update sound header
	pAPU->RenderFrame();
	theHeader = pAPU->GetNextSoundHeaderPtr();

	// issue next set of commands
	SndCommand buffer   = {bufferCmd, 0, (long)theHeader};
	SndDoImmediate(chan, &buffer);

	SndCommand callback = {callBackCmd, 0, (long)pAPU};
	SndDoCommand(chan, &callback, true);
}
Пример #8
0
void NAudioUnit::Start()
{
	if(!_bInitialized)
		return;

	_bRunning = true;

	SndCommand callback = { callBackCmd, 0, (NSInt32)this };
	SndDoCommand(_sndChannel, &callback, true);
}
Пример #9
0
static void
callBackProc(SndChannel * chan, SndCommand * cmd_passed)
{
    UInt32 play_me;
    SndCommand cmd;
    SDL_AudioDevice *audio = (SDL_AudioDevice *) chan->userInfo;

    IncrementAtomic((SInt32 *) & need_to_mix);

    fill_me = cmd_passed->param2;       /* buffer that has just finished playing, so fill it */
    play_me = !fill_me;         /* filled buffer to play _now_ */

    if (!audio->enabled) {
        return;
    }

    /* queue previously mixed buffer for playback. */
    header.samplePtr = (Ptr) buffer[play_me];
    cmd.cmd = bufferCmd;
    cmd.param1 = 0;
    cmd.param2 = (long) &header;
    SndDoCommand(chan, &cmd, 0);

    SDL_memset(buffer[fill_me], 0, audio->spec.size);

    /*
     * if audio device isn't locked, mix the next buffer to be queued in
     *  the memory block that just finished playing.
     */
    if (!BitAndAtomic(0xFFFFFFFF, (UInt32 *) & audio_is_locked)) {
        mix_buffer(audio, buffer[fill_me]);
    }

    /* set this callback to run again when current buffer drains. */
    if (running) {
        cmd.cmd = callBackCmd;
        cmd.param1 = 0;
        cmd.param2 = play_me;

        SndDoCommand(chan, &cmd, 0);
    }
}
Пример #10
0
static pascal void QSoundCallback(SndChannelPtr inCh, SndCommand *inCmd) {

	QSOUND		qs;
	int			nextbuf;
	void		*dst;
#if defined(SOUND_CRITICAL)
const SINT32	*src;
#endif

	if (QS_Avail) {
		qs = &QSound;
		nextbuf = inCmd->param1;
		dst = qs->buf[nextbuf]->sampleArea;
#if !defined(SOUND_CRITICAL)
		if (qs->indata) {
			CopyMemory((SINT16 *)dst, qs->indata, qs->buffersize);
			qs->indata = NULL;
		}
#else
		src = NULL;
		if (QSound_Playing) {
			src = sound_pcmlock();
		}
		if (src) {
			satuation_s16((SINT16 *)dst, src, qs->buffersize);
			sound_pcmunlock(src);
		}
#endif
		else {
			ZeroMemory(dst, qs->buffersize);
		}
		SndDoCommand(qs->hdl, &qs->cmd[nextbuf], TRUE);
		SndDoCommand(qs->hdl, &qs->cbcmd[nextbuf], TRUE);
	}
	(void)inCh;
}
Пример #11
0
static PyObject *SndCh_SndDoCommand(SndChannelObject *_self, PyObject *_args)
{
	PyObject *_res = NULL;
	OSErr _err;
	SndCommand cmd;
	Boolean noWait;
	if (!PyArg_ParseTuple(_args, "O&b",
	                      SndCmd_Convert, &cmd,
	                      &noWait))
		return NULL;
	_err = SndDoCommand(_self->ob_itself,
	                    &cmd,
	                    noWait);
	if (_err != noErr) return PyMac_Error(_err);
	Py_INCREF(Py_None);
	_res = Py_None;
	return _res;
}
Пример #12
0
void
mac_snd_callback(SndChannelPtr snd_chan_ptr, SndCommand *in_sndcmd)
{
	OSStatus err;
	int	samps;

	// This is an interrupt routine--no printf, etc!

	samps = g_macsnd_rebuf_ptr - g_macsnd_rebuf_cur;
	if(samps < 0) {
		samps += MACSND_REBUF_SIZE;
	}

	samps = samps & -(MACSND_QUANTA);	// quantize to 1024 samples
	if(g_macsnd_rebuf_cur + samps > &(g_macsnd_rebuf[MACSND_REBUF_SIZE])) {
		samps = &(g_macsnd_rebuf[MACSND_REBUF_SIZE]) -
							g_macsnd_rebuf_cur;
	}
	if(samps > 0) {
		g_macsnd_playing = 1;
		g_snd_hdr.numFrames = samps;
		g_snd_hdr.loopEnd = samps;
		g_snd_hdr.samplePtr = (byte *)g_macsnd_rebuf_cur;

		g_snd_cmd.cmd = bufferCmd;
		g_snd_cmd.param1 = 0;
		g_snd_cmd.param2 = (long) &g_snd_hdr;

		g_macsnd_rebuf_cur += samps;
		if(g_macsnd_rebuf_cur >= &(g_macsnd_rebuf[MACSND_REBUF_SIZE])) {
			g_macsnd_rebuf_cur -= MACSND_REBUF_SIZE;
		}

		err = SndDoImmediate(g_snd_channel_ptr, &g_snd_cmd);

		// And set-up callback
		g_snd_cmd.cmd = callBackCmd;
		g_snd_cmd.param1 = 0;
		g_snd_cmd.param2 = 0;
		err = SndDoCommand(g_snd_channel_ptr, &g_snd_cmd, TRUE);
	} else {
		g_macsnd_playing = 0;
	}
}
Пример #13
0
static int macos_init_sound (SINT16 *b)
{
	SndCallBackUPP cb;
	SndCommand cmd;

	report ("sound_macos: written by [email protected]\n");

	sarienbuf = b;

	header.numChannels = 1;
	header.sampleSize = 16;
	header.sampleRate = rate22khz;
	header.numFrames = BUFFER_SIZE;
	header.encode = cmpSH;

	buffer[0] = malloc (BUFFER_SIZE << 1);
	buffer[1] = malloc (BUFFER_SIZE << 1);
	if (!buffer[0] || !buffer[1]) {
		report ("sound_macos: Out of memory allocating %d bytes\n",
			BUFFER_SIZE << 1);
		return -1;
	}
 
	cb = NewSndCallBackUPP (fill_sound);

	if (SndNewChannel (&channel, sampledSynth, initMono, cb) != noErr) {
		report ("sound_macos: Unable to create channel");
		return -1;
	}

	cmd.cmd = callBackCmd;
	cmd.param2 = 0;
	SndDoCommand (channel, &cmd, 0);

	return 0;
}
Пример #14
0
void
mac_speaker (struct obj *instr, char *melody) {
	SndChannelPtr theChannel = (SndChannelPtr) 0;
	SndCommand theCmd;
	Handle theSound;
	unsigned char theName [32];
	char *n = (char *) &theName [1];
	int typ = instr->otyp;
	const char *actualn = OBJ_NAME (objects [typ]);

	/*
	 * First: are we in the library ?
	 */
	if (flags.silent) {
		return;
	}

	/*
	 * Is this a known instrument ?
	 */
	strcpy (n, actualn);
	theName [0] = strlen (n);
	theSound = GetNamedResource ('snd ', theName);
	if (! theSound) {
		return;
	}
	HLock (theSound);

	/*
	 * Set up the synth
	 */
	if (SndNewChannel(&theChannel, sampledSynth, initMono +
		initNoInterp, (void *) 0) == noErr) {
		char midi_note [] = {57, 59, 60, 62, 64, 65, 67};

		short err;
		short snd_len = SND_LEN (theSound) / 18;

		theCmd.cmd = soundCmd;
		theCmd.param1 = 0;
		theCmd.param2 = (long) SND_BUFFER (theSound);
		err = SndDoCommand (theChannel, &theCmd, false);

	/*
	 * We rack 'em up all in a row
	 * The mac will play them correctly and then end, since
	 * we do a sync close below.
	 *
	 */
		while (*melody && ! err) {
			while (*melody > 'G') {
				*melody -= 8;
			}
			while (*melody < 'A') {
				*melody += 8;
			}
			theCmd.cmd = freqDurationCmd;
			theCmd.param1 = snd_len;
			theCmd.param2 = midi_note [*melody - 'A'];
			err = SndDoCommand (theChannel, &theCmd, false);
			melody ++;
		}
		SndDisposeChannel (theChannel, false);	/* Sync wait for completion */
		ReleaseResource (theSound);
	}
}
Пример #15
0
static int
SNDMGR_OpenDevice(_THIS, const char *devname, int iscapture)
{
    SDL_AudioSpec *spec = &this->spec;
    SndChannelPtr channel = NULL;
    SndCallBackUPP callback;
    int sample_bits;
    int i;
    long initOptions;

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        SDL_OutOfMemory();
        return 0;
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));

    /* !!! FIXME: iterate through format matrix... */
    /* Very few conversions are required, but... */
    switch (spec->format) {
    case AUDIO_S8:
        spec->format = AUDIO_U8;
        break;
    case AUDIO_U16LSB:
        spec->format = AUDIO_S16LSB;
        break;
    case AUDIO_U16MSB:
        spec->format = AUDIO_S16MSB;
        break;
    case AUDIO_F32LSB:
        spec->format = AUDIO_F32MSB;
        break;
    }
    SDL_CalculateAudioSpec(&this->spec);

    /* initialize bufferCmd header */
    SDL_memset(&header, 0, sizeof(header));
    callback = (SndCallBackUPP) NewSndCallBackUPP(callBackProc);
    sample_bits = spec->size / spec->samples / spec->channels * 8;

#ifdef DEBUG_AUDIO
    fprintf(stderr,
            "Audio format 0x%x, channels = %d, sample_bits = %d, frequency = %d\n",
            spec->format, spec->channels, sample_bits, spec->freq);
#endif /* DEBUG_AUDIO */

    header.numChannels = spec->channels;
    header.sampleSize = sample_bits;
    header.sampleRate = spec->freq << 16;
    header.numFrames = spec->samples;
    header.encode = cmpSH;

    /* Note that we install the 16bitLittleEndian Converter if needed. */
    if (spec->format == AUDIO_S16LSB) {
        header.compressionID = fixedCompression;
        header.format = k16BitLittleEndianFormat;
    } else if (spec->format == AUDIO_S32MSB) {
        header.compressionID = fixedCompression;
        header.format = k32BitFormat;
    } else if (spec->format == AUDIO_S32LSB) {
        header.compressionID = fixedCompression;
        header.format = k32BitLittleEndianFormat;
    } else if (spec->format == AUDIO_F32MSB) {
        header.compressionID = fixedCompression;
        header.format = kFloat32Format;
    }

    /* allocate 2 buffers */
    for (i = 0; i < 2; i++) {
        buffer[i] = (UInt8 *) SDL_malloc(sizeof(UInt8) * spec->size);
        if (buffer[i] == NULL) {
            SNDMGR_CloseDevice(this);
            SDL_OutOfMemory();
            return 0;
        }
        SDL_memset(buffer[i], 0, spec->size);
    }

    /* Create the sound manager channel */
    channel = (SndChannelPtr) SDL_malloc(sizeof(*channel));
    if (channel == NULL) {
        SNDMGR_CloseDevice(this);
        SDL_OutOfMemory();
        return 0;
    }
    this->hidden->channel = channel;
    if (spec->channels >= 2) {
        initOptions = initStereo;
    } else {
        initOptions = initMono;
    }
    channel->userInfo = (long) this;
    channel->qLength = 128;
    if (SndNewChannel(&channel, sampledSynth, initOptions, callback) != noErr) {
        SNDMGR_CloseDevice(this);
        SDL_SetError("Unable to create audio channel");
        return 0;
    }

    /* start playback */
    {
        SndCommand cmd;
        cmd.cmd = callBackCmd;
        cmd.param2 = 0;
        running = 1;
        SndDoCommand(channel, &cmd, 0);
    }

    return 1;
}
Пример #16
0
long audio_write(snd_node *n, void *buffer, long length)
{
  buffer_state *data = (buffer_state *)n->u.audio.descriptor;

  while(data->busy)
    ;
  
  data->busy = 1;

  long written = 0;
  long block;
  
  if (data->curBuffer==0 && length>0) {
    block = min(length, data->bufferSize - data->curSize);
    
    if (block>0) {
    
      Ptr dest = (Ptr)&data->buffer[data->curSize];
      BlockMove((Ptr)buffer, dest, block);
      
      length -= block;
      written += block;
      data->curSize += block;
      buffer = &((char *)buffer)[block];
      
      if (data->curSize == data->bufferSize) {
        data->curSize = 0;
        data->curBuffer = 1;
      }
    }
  }
  
  // Copy into the second buffer (the one we don't pass to the Sound Manager directly)

  if (data->curBuffer == 1 && length>0) {
    block = min(length, data->nextBufferSize - data->curSize);
    
    if (block > 0) {
    
      Ptr dest = (Ptr)&data->nextBuffer[data->curSize];
      BlockMove((Ptr)buffer, dest, block);
      
      length -= block;
      written += block;
      data->curSize += block;
    }
  }

  // start playback immediately

  if (data->firstTime) {
    data->firstTime = 0;
    
    if (data->curBuffer==1) {
      data->header.numFrames = data->bufferSize / data->frameSize;
    }
    else {
      data->header.numFrames = data->curSize / data->frameSize;
      data->curBuffer = 1;
      data->curSize = 0;
    }
    
    data->busy = 0;

    SndDoCommand(data->chan, &data->playCmd, true);
    SndDoCommand(data->chan, &data->callCmd, true);    
  }
  
  data->busy = 0;
  
  return written;
}
Пример #17
0
static int Mac_OpenAudio(_THIS, SDL_AudioSpec *spec) {

   SndCallBackUPP callback;
   int sample_bits;
   int i;
   long initOptions;
      
   /* Very few conversions are required, but... */
    switch (spec->format) {
        case AUDIO_S8:
        spec->format = AUDIO_U8;
        break;
        case AUDIO_U16LSB:
        spec->format = AUDIO_S16LSB;
        break;
        case AUDIO_U16MSB:
        spec->format = AUDIO_S16MSB;
        break;
    }
    SDL_CalculateAudioSpec(spec);
    
    /* initialize bufferCmd header */
    memset (&header, 0, sizeof(header));
    callback = NewSndCallBackUPP (callBackProc);
    sample_bits = spec->size / spec->samples / spec->channels * 8;

#ifdef DEBUG_AUDIO
    fprintf(stderr,
	"Audio format 0x%x, channels = %d, sample_bits = %d, frequency = %d\n",
	spec->format, spec->channels, sample_bits, spec->freq);
#endif /* DEBUG_AUDIO */
    
    header.numChannels = spec->channels;
    header.sampleSize  = sample_bits;
    header.sampleRate  = spec->freq << 16;
    header.numFrames   = spec->samples;
    header.encode      = cmpSH;
    
    /* Note that we install the 16bitLittleEndian Converter if needed. */
    if ( spec->format == 0x8010 ) {
        header.compressionID = fixedCompression;
        header.format = k16BitLittleEndianFormat;
    }
    
    /* allocate 2 buffers */
    for (i=0; i<2; i++) {
       buffer[i] = (UInt8*)malloc (sizeof(UInt8) * spec->size);
      if (buffer[i] == NULL) {
         SDL_OutOfMemory();
         return (-1);
      }
     memset (buffer[i], 0, spec->size);
   }
   
   /* Create the sound manager channel */
    channel = (SndChannelPtr)malloc(sizeof(*channel));
    if ( channel == NULL ) {
        SDL_OutOfMemory();
        return(-1);
    }
    if ( spec->channels >= 2 ) {
        initOptions = initStereo;
    } else {
        initOptions = initMono;
    }
    channel->userInfo = (long)this;
    channel->qLength = 128;
    if ( SndNewChannel(&channel, sampledSynth, initOptions, callback) != noErr ) {
        SDL_SetError("Unable to create audio channel");
        free(channel);
        channel = NULL;
        return(-1);
    }
   
   /* start playback */
   {
      SndCommand cmd;
      cmd.cmd = callBackCmd;
      cmd.param2 = 0;
      running = 1;
      SndDoCommand (channel, &cmd, 0);
   }
   
   return 1;
}
Пример #18
0
void play_sound(short which, short how_many_times) { // if < 0, play asynch
#if defined(__APPLE__)
	Handle sndhandle;
	unsigned long dummy;
	OSErr err;
	SndCommand theCommand;
	if (!play_sounds || how_many_times == 0) return;
	
	if (abs(which) > NUM_SOUNDS) {
		//char msg[50];
		/*s*/printf(/*msg,*/"Error: Sound #%i does not exist.\n",abs(which));
		//give_error(msg,"",0);
		return;
	}
	
	channel++;
	
	if (channel > numchannel) channel = 0;
	
	if (!sound_going(abs(which)) && load_when_play[abs(which)]) 
		sndhandle = GetResource('snd ',20000 + abs(which));
	else sndhandle = sound_handles[abs(which)];
	
	if (which > 0)
 		if (always_asynch[which])
			which *= -1;
	
 	if (sndhandle != NULL)
	{
		HLock(sndhandle);
		
		if (which < 0) err = SndPlay(chan[channel],(SndListHandle) sndhandle,true); // Normal SndPlay
		else {
			err = SndPlay(chan[channel],(SndListHandle) sndhandle,false);
		}
		if (err != 0) {
			printf("Sound error.\n");
			//add_string_to_buf("Sound Error. Error codes:");
			//print_nums(channel,which,err);
			//add_string_to_buf("Your system could not play a sound.");
			//add_string_to_buf("Make sure editor isn't running.");
			//add_string_to_buf("Turn off sounds if necessary.");
		}
		HUnlock(sndhandle);
		snd_played[channel] = abs(which);
		theCommand.cmd = callBackCmd;
		theCommand.param1 = 0;
#ifndef EXILE_BIG_GUNS
		theCommand.param2 = SetCurrentA5();
#endif
#ifdef EXILE_BIG_GUNS
		theCommand.param2 = 0;
#endif
		SndDoCommand(chan[channel],&theCommand,true);
	}
	else SysBeep(20);
	if (which < 0)
		Delay(sound_delay[-1 * which],&dummy);
	if(how_many_times > 1)
		play_sound(which, how_many_times - 1);
#elif defined(WIN32)
	short i,num_fails = 0;
	char snd_name[30];
	bool asyn = false,a_sound_did_get_played = false;
	bool not_asyn = false,check_sound;
	HRSRC h;
	if ((sounds_missing) || (!play_sounds) || (how_many_times == 0))
		return;
	
	if (which < 0) {
		asyn = true;
		which = which * -1;
		}
	if (which >= 1000) {
		which -= 1000;
		not_asyn = true;
		}

	if (which >= 100)
		return;

	if ((always_asynch[which] == true) &&
	((can_ignore[which] == 1) || (can_ignore[which] >= 3)))
		asyn = true;
	if ((can_ignore[which] > 0) && (can_ignore[which] < 5) && (party.stuff_done[305][5] == 1))
		return;
	if ((can_ignore[which] != 1) && (can_ignore[which] < 3))
		asyn = false;
	if ((party.stuff_done[305][5] == 1) && (can_ignore[which] < 5))
		asyn = false;
	if (not_asyn == true)
		asyn = false;

	if ((load_when_play[which] == true) && (sound_handles[which] == NULL)) {
			asyn = false;
		sprintf((char *)snd_name,"#%d",which + 1);
		h = FindResource(hModule,snd_name,"#100");

		sound_handles[which] = LoadResource(hModule,h);
		snds[which] = (char *) LockResource(sound_handles[which]);

		}

	if (store_last_sound_played == 6)
		sndPlaySound(NULL,0);

	if (asyn == true) {
		if (can_ignore[which] >= 4)
			check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY | SND_NOSTOP);
			else check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY);

		while (check_sound == false) {

			if (can_ignore[store_last_sound_played] == 4) {// then sound goes away
				return;
				}


			num_fails++;
			if (num_fails < 40)
				sound_pause(25);
				else {
					MessageBox(mainPtr,"Cannot play sounds - Sounds stuck error a. Game can still be played, but quietly. Check to make sure your sound drivers are up to date and not corrupted.",
					  "Sound Error",MB_OK | MB_ICONEXCLAMATION);
					print_nums(111,which,num_fails);
					sounds_fucked = true;
					return;
					}
			sndPlaySound(NULL,0);

			if (can_ignore[which] >= 4)
				check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY | SND_NOSTOP);
				else check_sound = sndPlaySound(snds[which],SND_ASYNC | SND_MEMORY);
			}
	  a_sound_did_get_played = true;
	  }
		else {
		if (can_ignore[which] >= 4)
			check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY | SND_NOSTOP);
			else check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY);
		while (check_sound == false) {
			if (can_ignore[store_last_sound_played] == 4) {// then sound goes away
				return;
				}


			num_fails++;
			if (num_fails < 40)
				sound_pause(25);
				else {
					MessageBox(mainPtr,"Cannot play sounds - Sounds stuck error b. Game can still be played, but quietly. Check to make sure your sound drivers are up to date and not corrupted.",
					 "Sound Error",MB_OK | MB_ICONEXCLAMATION);
					print_nums(222,which,num_fails);
					sounds_fucked = true;
					return;
					}
			sndPlaySound(NULL,0);

			if (can_ignore[which] >= 4)
				check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY | SND_NOSTOP);
				else check_sound = sndPlaySound(snds[which],SND_SYNC | SND_MEMORY);
			}
		a_sound_did_get_played = true;
	  }

	store_last_sound_played = which;

	if ((load_when_play[which] == true) && (asyn == false)) 
		sound_handles[which] = NULL;
		
	for (i = 0; i < NUM_SOUNDS; i++)
		if ((load_when_play[which] == true) && (sound_handles[which] != NULL)
			&& (a_sound_did_get_played == true) && (i != which))
		{
			sound_handles[i] = NULL;
		}
#endif
}