Ejemplo n.º 1
0
static int Mac_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
    SndDoubleBufferHeader2 audio_dbh;
    int i;
    long initOptions;
    int sample_bits;
    SndDoubleBackUPP doubleBackProc;

    /* Check to make sure double-buffered audio is available */
    if ( ! DoubleBufferAudio_Available() ) {
        SDL_SetError("Sound manager doesn't support double-buffering");
        return(-1);
    }

    /* 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 the double-back header */
    memset(&audio_dbh, 0, sizeof(audio_dbh));
    doubleBackProc = NewSndDoubleBackProc (sndDoubleBackProc);
    sample_bits = spec->size / spec->samples / spec->channels * 8;
    
    audio_dbh.dbhNumChannels = spec->channels;
    audio_dbh.dbhSampleSize    = sample_bits;
    audio_dbh.dbhCompressionID = 0;
    audio_dbh.dbhPacketSize    = 0;
    audio_dbh.dbhSampleRate    = spec->freq << 16;
    audio_dbh.dbhDoubleBack    = doubleBackProc;
    audio_dbh.dbhFormat    = 0;

    /* Note that we install the 16bitLittleEndian Converter if needed. */
    if ( spec->format == 0x8010 ) {
        audio_dbh.dbhCompressionID = fixedCompression;
        audio_dbh.dbhFormat = k16BitLittleEndianFormat;
    }

    /* allocate the 2 double-back buffers */
    for ( i=0; i<2; ++i ) {
        audio_buf[i] = calloc(1, sizeof(SndDoubleBuffer)+spec->size);
        if ( audio_buf[i] == NULL ) {
            SDL_OutOfMemory();
            return(-1);
        }
        audio_buf[i]->dbNumFrames = spec->samples;
        audio_buf[i]->dbFlags = dbBufferReady;
        audio_buf[i]->dbUserInfo[0] = (long)this;
        audio_dbh.dbhBufferPtr[i] = audio_buf[i];
    }

    /* 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 = 0;
    channel->qLength = 128;
    if ( SndNewChannel(&channel, sampledSynth, initOptions, 0L) != noErr ) {
        SDL_SetError("Unable to create audio channel");
        free(channel);
        channel = NULL;
        return(-1);
    }
 
    /* Start playback */
    if ( SndPlayDoubleBuffer(channel, (SndDoubleBufferHeaderPtr)&audio_dbh)
                                != noErr ) {
        SDL_SetError("Unable to play double buffered audio");
        return(-1);
    }
    
    return 1;
}
Ejemplo n.º 2
0
OSErr open_network_speaker()
{
  short block_size = kBlockSize;
  short connection_threshold = kConnectionThreshhold;
  OSErr error;

  assert(!speaker);
  assert(block_size>0&&block_size<=MAXIMUM_DOUBLE_BUFFER_SIZE);
  assert(connection_threshold>1&&connection_threshold<16);

  /* install our atexit cleanup procedure and build a routine descriptor */
  {
    static bool initialization= true;

    if (initialization) {
// ZZZ: Sorry, it looks like the CarbonSndPlayDoubleBuffer stuff really wants a plain C function
// pointer, sitting in the structure typed as a SndDoubleBackUPP.  (Don't ask me!)
#if defined(TARGET_API_MAC_CARBON)
      doubleback_routine_descriptor=
        (SndDoubleBackUPP)network_speaker_doubleback_procedure;
#else
      // Thomas Herzog fix
                        #if UNIVERSAL_INTERFACES_VERSION < 0x0340
      doubleback_routine_descriptor= NewSndDoubleBackProc(
        (ProcPtr)network_speaker_doubleback_procedure);
                        #else
      doubleback_routine_descriptor= NewSndDoubleBackUPP(
        network_speaker_doubleback_procedure);
                        #endif
      // doubleback_routine_descriptor= NewSndDoubleBackProc((ProcPtr)network_speaker_doubleback_procedure);
#endif
      assert(doubleback_routine_descriptor);

      atexit(close_network_speaker);
    }
  }

  speaker=
    (struct speaker_definition *) NewPtr(sizeof(struct speaker_definition));
  if ((error= MemError())==noErr) {
    speaker->random_seed= 1;
    speaker->block_size= block_size;
    speaker->connection_threshold= connection_threshold;

    speaker->channel= (SndChannelPtr) NewPtrClear(sizeof(SndChannel));
    speaker->header=
      (SndDoubleBufferHeaderPtr) NewPtrClear(sizeof(SndDoubleBufferHeader));
    speaker->queue= NewPtr(sizeof(byte)*MAXIMUM_QUEUE_SIZE);
    if ((error= MemError())==noErr) {
      SndDoubleBufferHeaderPtr header= speaker->header;

      header->dbhNumChannels= 1;
      header->dbhSampleSize= 8;
      header->dbhCompressionID= 0;
      header->dbhPacketSize= 0;
      header->dbhSampleRate= rate11025hz;
      header->dbhDoubleBack= doubleback_routine_descriptor;
      header->dbhBufferPtr[0]=
        (SndDoubleBufferPtr) NewPtrClear(
          sizeof(SndDoubleBuffer)+MAXIMUM_DOUBLE_BUFFER_SIZE);
      header->dbhBufferPtr[1]=
        (SndDoubleBufferPtr) NewPtrClear(
          sizeof(SndDoubleBuffer)+MAXIMUM_DOUBLE_BUFFER_SIZE);

      if ((error= MemError())==noErr) {
        speaker->channel->qLength= stdQLength;
#ifdef env68k
        speaker->channel->userInfo= (long) get_a5();
#endif

        error=
          SndNewChannel(&speaker->channel, sampledSynth, initMono|initMACE6,
                        NULL);
        if (error==noErr) {
          quiet_network_speaker();                               /* to set defaults */
        }
      }
    }
  }

#ifdef SPEEX
  init_speex_decoder();
#endif

  /* if something went wrong, zero the speaker definition (without freeing any of our memory
          like we should) */
  if (error!=noErr) {
    speaker= (struct speaker_definition *) NULL;
  }

  return error;
}
Ejemplo n.º 3
0
/*
 * generic new : returns error
 */
int
start_fluid_sndmgr_audio_driver(fluid_settings_t* settings,
				fluid_sndmgr_audio_driver_t* dev,
				int buffer_size)
{
  int i;
  SndDoubleBufferHeader2* doubleHeader = NULL;
  SndDoubleBufferPtr doubleBuffer = NULL;
  OSErr err;
  SndChannelPtr channel = NULL;
  double sample_rate;

  fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);

  dev->doubleCallbackProc = NewSndDoubleBackProc(fluid_sndmgr_callback);

  /* the channel */
  FLUID_LOG(FLUID_DBG, "FLUID-SndManager@2");
  err = SndNewChannel(&channel, sampledSynth, initStereo, NULL);
  if ((err != noErr) || (channel == NULL)) {
    FLUID_LOG(FLUID_ERR, "Failed to allocate a sound channel (error %i)", err);
    return err;
  }

  /* the double buffer struct */
  FLUID_LOG(FLUID_DBG, "FLUID-SndManager@3");
  doubleHeader = FLUID_NEW(SndDoubleBufferHeader2);
  if (doubleHeader == NULL) {
    FLUID_LOG(FLUID_PANIC, "Out of memory");
    return -1;
  }
  doubleHeader->dbhBufferPtr[0] = NULL;
  doubleHeader->dbhBufferPtr[1] = NULL;
  doubleHeader->dbhNumChannels = 2;
  doubleHeader->dbhSampleSize = 16;
  doubleHeader->dbhCompressionID = 0;
  doubleHeader->dbhPacketSize = 0;
  doubleHeader->dbhSampleRate = fluid_sndmgr_double_to_fix((long double) sample_rate);
  doubleHeader->dbhDoubleBack = dev->doubleCallbackProc;
  doubleHeader->dbhFormat = 0;

  /* prepare dev */
  FLUID_LOG(FLUID_DBG, "FLUID-SndManager@4");
  dev->doubleHeader = doubleHeader;
  dev->channel = channel;
  dev->bufferFrameSize = buffer_size;
  dev->bufferByteSize = buffer_size * 2 * 2;

  /* the 2 doublebuffers */
  FLUID_LOG(FLUID_DBG, "FLUID-SndManager@5");
  for (i = 0; i < 2; i++) {
    doubleBuffer = (SndDoubleBufferPtr) FLUID_MALLOC(sizeof(SndDoubleBuffer)
						     + dev->bufferByteSize);
    if (doubleBuffer == NULL) {
      FLUID_LOG(FLUID_PANIC, "Out of memory");
      return -1;
    }
    doubleBuffer->dbNumFrames = 0;
    doubleBuffer->dbFlags = 0;
    doubleBuffer->dbUserInfo[0] = (long) dev;
    doubleHeader->dbhBufferPtr[i] = doubleBuffer;
    CallSndDoubleBackProc(doubleHeader->dbhDoubleBack, channel, doubleBuffer);
  }

  /* start */
  FLUID_LOG(FLUID_DBG, "FLUID-SndManager@6");

  err = SndPlayDoubleBuffer(channel, (SndDoubleBufferHeader *)doubleHeader);
  if (err != noErr) {
    FLUID_LOG(FLUID_ERR, "Failed to start the sound driver (error %i)", err);
    return err;
  }

  FLUID_LOG(FLUID_DBG, "FLUID-SndManager@7");
  return 0;
}