static int Audio_Available(void) { int fd; int available; available = 0; fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); if ( fd >= 0 ) { available = 1; close(fd); } return(available); }
static int Audio_Available(void) { int available; int fd; available = 0; fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); if ( fd >= 0 ) { int caps; struct audio_buf_info info; if ( (ioctl(fd, SNDCTL_DSP_GETCAPS, &caps) == 0) && (caps & DSP_CAP_TRIGGER) && (caps & DSP_CAP_MMAP) && (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) == 0) ) { available = 1; } close(fd); } return(available); }
static int DMA_OpenAudio(_THIS, SDL_AudioSpec *spec) { char audiodev[1024]; int format; int stereo; int value; Uint16 test_format; struct audio_buf_info info; /* Reset the timer synchronization flag */ frame_ticks = 0.0; /* Open the audio device */ audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); if ( audio_fd < 0 ) { SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); return(-1); } dma_buf = NULL; ioctl(audio_fd, SNDCTL_DSP_RESET, 0); /* Get a list of supported hardware formats */ if ( ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0 ) { SDL_SetError("Couldn't get audio format list"); return(-1); } /* Try for a closest match on audio format */ format = 0; for ( test_format = SDL_FirstAudioFormat(spec->format); ! format && test_format; ) { #ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format); #endif switch ( test_format ) { case AUDIO_U8: if ( value & AFMT_U8 ) { format = AFMT_U8; } break; case AUDIO_S8: if ( value & AFMT_S8 ) { format = AFMT_S8; } break; case AUDIO_S16LSB: if ( value & AFMT_S16_LE ) { format = AFMT_S16_LE; } break; case AUDIO_S16MSB: if ( value & AFMT_S16_BE ) { format = AFMT_S16_BE; } break; case AUDIO_U16LSB: if ( value & AFMT_U16_LE ) { format = AFMT_U16_LE; } break; case AUDIO_U16MSB: if ( value & AFMT_U16_BE ) { format = AFMT_U16_BE; } break; default: format = 0; break; } if ( ! format ) { test_format = SDL_NextAudioFormat(); } } if ( format == 0 ) { SDL_SetError("Couldn't find any hardware audio formats"); return(-1); } spec->format = test_format; /* Set the audio format */ value = format; if ( (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format) ) { SDL_SetError("Couldn't set audio format"); return(-1); } /* Set mono or stereo audio (currently only two channels supported) */ stereo = (spec->channels > 1); ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo); if ( stereo ) { spec->channels = 2; } else { spec->channels = 1; } /* Because some drivers don't allow setting the buffer size after setting the format, we must re-open the audio device once we know what format and channels are supported */ if ( DMA_ReopenAudio(this, audiodev, format, stereo, spec) < 0 ) { /* Error is set by DMA_ReopenAudio() */ return(-1); } /* Memory map the audio buffer */ if ( ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) < 0 ) { SDL_SetError("Couldn't get OSPACE parameters"); return(-1); } spec->size = info.fragsize; spec->samples = spec->size / ((spec->format & 0xFF) / 8); spec->samples /= spec->channels; num_buffers = info.fragstotal; dma_len = num_buffers*spec->size; dma_buf = (Uint8 *)mmap(NULL, dma_len, PROT_WRITE, MAP_SHARED, audio_fd, 0); if ( dma_buf == MAP_FAILED ) { SDL_SetError("DMA memory map failed"); dma_buf = NULL; return(-1); } SDL_memset(dma_buf, spec->silence, dma_len); /* Check to see if we need to use select() workaround */ { char *workaround; workaround = SDL_getenv("SDL_DSP_NOSELECT"); if ( workaround ) { frame_ticks = (float)(spec->samples*1000)/spec->freq; next_frame = SDL_GetTicks()+frame_ticks; } } /* Trigger audio playback */ value = 0; ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value); value = PCM_ENABLE_OUTPUT; if ( ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value) < 0 ) { SDL_SetError("Couldn't trigger audio output"); return(-1); } /* Get the parent process id (we're the parent of the audio thread) */ parent = getpid(); /* We're ready to rock and roll. :-) */ return(0); }
static int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec) { char audiodev[1024]; int format; int value; Uint16 test_format; /* Reset the timer synchronization flag */ frame_ticks = 0.0; /* Open the audio device */ audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); if ( audio_fd < 0 ) { SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); return(-1); } mixbuf = NULL; #ifdef USE_BLOCKING_WRITES /* Make the file descriptor use blocking writes with fcntl() */ { long flags; flags = fcntl(audio_fd, F_GETFL); flags &= ~O_NONBLOCK; if ( fcntl(audio_fd, F_SETFL, flags) < 0 ) { SDL_SetError("Couldn't set audio blocking mode"); return(-1); } } #endif /* Get a list of supported hardware formats */ if ( ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0 ) { SDL_SetError("Couldn't get audio format list"); return(-1); } /* Try for a closest match on audio format */ format = 0; for ( test_format = SDL_FirstAudioFormat(spec->format); ! format && test_format; ) { #ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format); #endif switch ( test_format ) { case AUDIO_U8: if ( value & AFMT_U8 ) { format = AFMT_U8; } break; case AUDIO_S8: if ( value & AFMT_S8 ) { format = AFMT_S8; } break; case AUDIO_S16LSB: if ( value & AFMT_S16_LE ) { format = AFMT_S16_LE; } break; case AUDIO_S16MSB: if ( value & AFMT_S16_BE ) { format = AFMT_S16_BE; } break; case AUDIO_U16LSB: if ( value & AFMT_U16_LE ) { format = AFMT_U16_LE; } break; case AUDIO_U16MSB: if ( value & AFMT_U16_BE ) { format = AFMT_U16_BE; } break; default: format = 0; break; } if ( ! format ) { test_format = SDL_NextAudioFormat(); } } if ( format == 0 ) { SDL_SetError("Couldn't find any hardware audio formats"); return(-1); } spec->format = test_format; /* Set the audio format */ value = format; if ( (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format) ) { SDL_SetError("Couldn't set audio format"); return(-1); } /* Set the number of channels of output */ value = spec->channels; #ifdef SNDCTL_DSP_CHANNELS if ( ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0 ) { #endif value = (spec->channels > 1); ioctl(audio_fd, SNDCTL_DSP_STEREO, &value); value = (value ? 2 : 1); #ifdef SNDCTL_DSP_CHANNELS } #endif spec->channels = value; /* Because some drivers don't allow setting the buffer size after setting the format, we must re-open the audio device once we know what format and channels are supported */ if ( DSP_ReopenAudio(this, audiodev, format, spec) < 0 ) { /* Error is set by DSP_ReopenAudio() */ return(-1); } /* Allocate mixing buffer */ mixlen = spec->size; mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); if ( mixbuf == NULL ) { return(-1); } memset(mixbuf, spec->silence, spec->size); #ifndef USE_BLOCKING_WRITES /* Check to see if we need to use select() workaround */ { char *workaround; workaround = getenv("SDL_DSP_NOSELECT"); if ( workaround ) { frame_ticks = (float)(spec->samples*1000)/spec->freq; next_frame = SDL_GetTicks()+frame_ticks; } } #endif /* !USE_BLOCKING_WRITES */ /* Get the parent process id (we're the parent of the audio thread) */ parent = getpid(); /* We're ready to rock and roll. :-) */ return(0); }
int DSP_OpenAudio(_THIS, SDL_AudioSpec * spec) { char audiodev[1024]; #ifdef AUDIO_SETINFO int enc; #endif int desired_freq = spec->freq; /* Initialize our freeable variables, in case we fail */ audio_fd = -1; mixbuf = NULL; ulaw_buf = NULL; /* Determine the audio parameters from the AudioSpec */ switch (SDL_AUDIO_BITSIZE(spec->format)) { case 8: { /* Unsigned 8 bit audio data */ spec->format = AUDIO_U8; #ifdef AUDIO_SETINFO enc = AUDIO_ENCODING_LINEAR8; #endif } break; case 16: { /* Signed 16 bit audio data */ spec->format = AUDIO_S16SYS; #ifdef AUDIO_SETINFO enc = AUDIO_ENCODING_LINEAR; #endif } break; default: { /* !!! FIXME: fallback to conversion on unsupported types! */ SDL_SetError("Unsupported audio format"); return (-1); } } audio_fmt = spec->format; /* Open the audio device */ audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 1); if (audio_fd < 0) { SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); return (-1); } ulaw_only = 0; /* modern Suns do support linear audio */ #ifdef AUDIO_SETINFO for (;;) { audio_info_t info; AUDIO_INITINFO(&info); /* init all fields to "no change" */ /* Try to set the requested settings */ info.play.sample_rate = spec->freq; info.play.channels = spec->channels; info.play.precision = (enc == AUDIO_ENCODING_ULAW) ? 8 : spec->format & 0xff; info.play.encoding = enc; if (ioctl(audio_fd, AUDIO_SETINFO, &info) == 0) { /* Check to be sure we got what we wanted */ if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { SDL_SetError("Error getting audio parameters: %s", strerror(errno)); return -1; } if (info.play.encoding == enc && info.play.precision == (spec->format & 0xff) && info.play.channels == spec->channels) { /* Yow! All seems to be well! */ spec->freq = info.play.sample_rate; break; } } switch (enc) { case AUDIO_ENCODING_LINEAR8: /* unsigned 8bit apparently not supported here */ enc = AUDIO_ENCODING_LINEAR; spec->format = AUDIO_S16SYS; break; /* try again */ case AUDIO_ENCODING_LINEAR: /* linear 16bit didn't work either, resort to µ-law */ enc = AUDIO_ENCODING_ULAW; spec->channels = 1; spec->freq = 8000; spec->format = AUDIO_U8; ulaw_only = 1; break; default: /* oh well... */ SDL_SetError("Error setting audio parameters: %s", strerror(errno)); return -1; } } #endif /* AUDIO_SETINFO */ written = 0; /* We can actually convert on-the-fly to U-Law */ if (ulaw_only) { spec->freq = desired_freq; fragsize = (spec->samples * 1000) / (spec->freq / 8); frequency = 8; ulaw_buf = (Uint8 *) SDL_malloc(fragsize); if (ulaw_buf == NULL) { SDL_OutOfMemory(); return (-1); } spec->channels = 1; } else { fragsize = spec->samples; frequency = spec->freq / 1000; } #ifdef DEBUG_AUDIO fprintf(stderr, "Audio device %s U-Law only\n", ulaw_only ? "is" : "is not"); fprintf(stderr, "format=0x%x chan=%d freq=%d\n", spec->format, spec->channels, spec->freq); #endif /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(spec); /* Allocate mixing buffer */ mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size); if (mixbuf == NULL) { SDL_OutOfMemory(); return (-1); } SDL_memset(mixbuf, spec->silence, spec->size); /* We're ready to rock and roll. :-) */ return (0); }
static int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec) { char audiodev[1024]; int format; int value; int frag_spec; Uint16 test_format; /* Open the audio device */ audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); if ( audio_fd < 0 ) { SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); return(-1); } mixbuf = NULL; /* Make the file descriptor use blocking writes with fcntl() */ { long flags; flags = fcntl(audio_fd, F_GETFL); flags &= ~O_NONBLOCK; if ( fcntl(audio_fd, F_SETFL, flags) < 0 ) { SDL_SetError("Couldn't set audio blocking mode"); return(-1); } } /* Get a list of supported hardware formats */ if ( ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0 ) { perror("SNDCTL_DSP_GETFMTS"); SDL_SetError("Couldn't get audio format list"); return(-1); } /* Try for a closest match on audio format */ format = 0; for ( test_format = SDL_FirstAudioFormat(spec->format); ! format && test_format; ) { #ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format); #endif switch ( test_format ) { case AUDIO_U8: if ( value & AFMT_U8 ) { format = AFMT_U8; } break; case AUDIO_S16LSB: if ( value & AFMT_S16_LE ) { format = AFMT_S16_LE; } break; case AUDIO_S16MSB: if ( value & AFMT_S16_BE ) { format = AFMT_S16_BE; } break; #if 0 /* * These formats are not used by any real life systems so they are not * needed here. */ case AUDIO_S8: if ( value & AFMT_S8 ) { format = AFMT_S8; } break; case AUDIO_U16LSB: if ( value & AFMT_U16_LE ) { format = AFMT_U16_LE; } break; case AUDIO_U16MSB: if ( value & AFMT_U16_BE ) { format = AFMT_U16_BE; } break; #endif default: format = 0; break; } if ( ! format ) { test_format = SDL_NextAudioFormat(); } } if ( format == 0 ) { SDL_SetError("Couldn't find any hardware audio formats"); return(-1); } spec->format = test_format; /* Set the audio format */ value = format; if ( (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format) ) { perror("SNDCTL_DSP_SETFMT"); SDL_SetError("Couldn't set audio format"); return(-1); } /* Set the number of channels of output */ value = spec->channels; if ( ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0 ) { perror("SNDCTL_DSP_CHANNELS"); SDL_SetError("Cannot set the number of channels"); return(-1); } spec->channels = value; /* Set the DSP frequency */ value = spec->freq; if ( ioctl(audio_fd, SNDCTL_DSP_SPEED, &value) < 0 ) { perror("SNDCTL_DSP_SPEED"); SDL_SetError("Couldn't set audio frequency"); return(-1); } spec->freq = value; /* Calculate the final parameters for this audio specification */ SDL_CalculateAudioSpec(spec); /* Determine the power of two of the fragment size */ for ( frag_spec = 0; (0x01<<frag_spec) < spec->size; ++frag_spec ); if ( (0x01<<frag_spec) != spec->size ) { SDL_SetError("Fragment size must be a power of two"); return(-1); } frag_spec |= 0x00020000; /* two fragments, for low latency */ /* Set the audio buffering parameters */ #ifdef DEBUG_AUDIO fprintf(stderr, "Requesting %d fragments of size %d\n", (frag_spec >> 16), 1<<(frag_spec&0xFFFF)); #endif if ( ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0 ) { perror("SNDCTL_DSP_SETFRAGMENT"); fprintf(stderr, "Warning: Couldn't set audio fragment size\n"); } #ifdef DEBUG_AUDIO { audio_buf_info info; ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info); fprintf(stderr, "fragments = %d\n", info.fragments); fprintf(stderr, "fragstotal = %d\n", info.fragstotal); fprintf(stderr, "fragsize = %d\n", info.fragsize); fprintf(stderr, "bytes = %d\n", info.bytes); } #endif /* Allocate mixing buffer */ mixlen = spec->size; mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); if ( mixbuf == NULL ) { return(-1); } memset(mixbuf, spec->silence, spec->size); /* Get the parent process id (we're the parent of the audio thread) */ parent = getpid(); /* We're ready to rock and roll. :-) */ return(0); }
static int Paud_OpenAudio(_THIS, SDL_AudioSpec *spec) { char audiodev[1024]; int format; int bytes_per_sample; Uint16 test_format; audio_init paud_init; audio_buffer paud_bufinfo; audio_status paud_status; audio_control paud_control; audio_change paud_change; /* Reset the timer synchronization flag */ frame_ticks = 0.0; /* Open the audio device */ audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); if ( audio_fd < 0 ) { SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); return -1; } /* * We can't set the buffer size - just ask the device for the maximum * that we can have. */ if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 ) { SDL_SetError("Couldn't get audio buffer information"); return -1; } mixbuf = NULL; if ( spec->channels > 1 ) spec->channels = 2; else spec->channels = 1; /* * Fields in the audio_init structure: * * Ignored by us: * * paud.loadpath[LOAD_PATH]; * DSP code to load, MWave chip only? * paud.slot_number; * slot number of the adapter * paud.device_id; * adapter identification number * * Input: * * paud.srate; * the sampling rate in Hz * paud.bits_per_sample; * 8, 16, 32, ... * paud.bsize; * block size for this rate * paud.mode; * ADPCM, PCM, MU_LAW, A_LAW, SOURCE_MIX * paud.channels; * 1=mono, 2=stereo * paud.flags; * FIXED - fixed length data * * LEFT_ALIGNED, RIGHT_ALIGNED (var len only) * * TWOS_COMPLEMENT - 2's complement data * * SIGNED - signed? comment seems wrong in sys/audio.h * * BIG_ENDIAN * paud.operation; * PLAY, RECORD * * Output: * * paud.flags; * PITCH - pitch is supported * * INPUT - input is supported * * OUTPUT - output is supported * * MONITOR - monitor is supported * * VOLUME - volume is supported * * VOLUME_DELAY - volume delay is supported * * BALANCE - balance is supported * * BALANCE_DELAY - balance delay is supported * * TREBLE - treble control is supported * * BASS - bass control is supported * * BESTFIT_PROVIDED - best fit returned * * LOAD_CODE - DSP load needed * paud.rc; * NO_PLAY - DSP code can't do play requests * * NO_RECORD - DSP code can't do record requests * * INVALID_REQUEST - request was invalid * * CONFLICT - conflict with open's flags * * OVERLOADED - out of DSP MIPS or memory * paud.position_resolution; * smallest increment for position */ paud_init.srate = spec->freq; paud_init.mode = PCM; paud_init.operation = PLAY; paud_init.channels = spec->channels; /* Try for a closest match on audio format */ format = 0; for ( test_format = SDL_FirstAudioFormat(spec->format); ! format && test_format; ) { #ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format); #endif switch ( test_format ) { case AUDIO_U8: bytes_per_sample = 1; paud_init.bits_per_sample = 8; paud_init.flags = TWOS_COMPLEMENT | FIXED; format = 1; break; case AUDIO_S8: bytes_per_sample = 1; paud_init.bits_per_sample = 8; paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED; format = 1; break; case AUDIO_S16LSB: bytes_per_sample = 2; paud_init.bits_per_sample = 16; paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED; format = 1; break; case AUDIO_S16MSB: bytes_per_sample = 2; paud_init.bits_per_sample = 16; paud_init.flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED; format = 1; break; case AUDIO_U16LSB: bytes_per_sample = 2; paud_init.bits_per_sample = 16; paud_init.flags = TWOS_COMPLEMENT | FIXED; format = 1; break; case AUDIO_U16MSB: bytes_per_sample = 2; paud_init.bits_per_sample = 16; paud_init.flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED; format = 1; break; default: break; } if ( ! format ) { test_format = SDL_NextAudioFormat(); } } if ( format == 0 ) { #ifdef DEBUG_AUDIO fprintf(stderr, "Couldn't find any hardware audio formats\n"); #endif SDL_SetError("Couldn't find any hardware audio formats"); return -1; } spec->format = test_format; /* * We know the buffer size and the max number of subsequent writes * that can be pending. If more than one can pend, allow the application * to do something like double buffering between our write buffer and * the device's own buffer that we are filling with write() anyway. * * We calculate spec->samples like this because SDL_CalculateAudioSpec() * will give put paud_bufinfo.write_buf_cap (or paud_bufinfo.write_buf_cap/2) * into spec->size in return. */ if ( paud_bufinfo.request_buf_cap == 1 ) { spec->samples = paud_bufinfo.write_buf_cap / bytes_per_sample / spec->channels; } else { spec->samples = paud_bufinfo.write_buf_cap / bytes_per_sample / spec->channels / 2; } paud_init.bsize = bytes_per_sample * spec->channels; SDL_CalculateAudioSpec(spec); /* * The AIX paud device init can't modify the values of the audio_init * structure that we pass to it. So we don't need any recalculation * of this stuff and no reinit call as in linux dsp and dma code. * * /dev/paud supports all of the encoding formats, so we don't need * to do anything like reopening the device, either. */ if ( ioctl(audio_fd, AUDIO_INIT, &paud_init) < 0 ) { switch ( paud_init.rc ) { case 1 : SDL_SetError("Couldn't set audio format: DSP can't do play requests"); return -1; break; case 2 : SDL_SetError("Couldn't set audio format: DSP can't do record requests"); return -1; break; case 4 : SDL_SetError("Couldn't set audio format: request was invalid"); return -1; break; case 5 : SDL_SetError("Couldn't set audio format: conflict with open's flags"); return -1; break; case 6 : SDL_SetError("Couldn't set audio format: out of DSP MIPS or memory"); return -1; break; default : SDL_SetError("Couldn't set audio format: not documented in sys/audio.h"); return -1; break; } } /* Allocate mixing buffer */ mixlen = spec->size; mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); if ( mixbuf == NULL ) { return -1; } SDL_memset(mixbuf, spec->silence, spec->size); /* * Set some paramters: full volume, first speaker that we can find. * Ignore the other settings for now. */ paud_change.input = AUDIO_IGNORE; /* the new input source */ paud_change.output = OUTPUT_1; /* EXTERNAL_SPEAKER,INTERNAL_SPEAKER,OUTPUT_1 */ paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */ paud_change.volume = 0x7fffffff; /* volume level [0-0x7fffffff] */ paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */ paud_change.balance = 0x3fffffff; /* the new balance */ paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */ paud_change.treble = AUDIO_IGNORE; /* the new treble state */ paud_change.bass = AUDIO_IGNORE; /* the new bass state */ paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */ paud_control.ioctl_request = AUDIO_CHANGE; paud_control.request_info = (char*)&paud_change; if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 ) { #ifdef DEBUG_AUDIO fprintf(stderr, "Can't change audio display settings\n" ); #endif } /* * Tell the device to expect data. Actual start will wait for * the first write() call. */ paud_control.ioctl_request = AUDIO_START; paud_control.position = 0; if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 ) { #ifdef DEBUG_AUDIO fprintf(stderr, "Can't start audio play\n" ); #endif SDL_SetError("Can't start audio play"); return -1; } /* Check to see if we need to use select() workaround */ { char *workaround; workaround = SDL_getenv("SDL_DSP_NOSELECT"); if ( workaround ) { frame_ticks = (float)(spec->samples*1000)/spec->freq; next_frame = SDL_GetTicks()+frame_ticks; } } /* Get the parent process id (we're the parent of the audio thread) */ parent = getpid(); /* We're ready to rock and roll. :-) */ return 0; }
static int OBSD_OpenAudio(_THIS, SDL_AudioSpec *spec) { char audiodev[64]; Uint16 format; audio_info_t info; AUDIO_INITINFO(&info); SDL_CalculateAudioSpec(spec); #ifdef USE_TIMER_SYNC frame_ticks = 0.0; #endif audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); if(audio_fd < 0) { SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); return(-1); } info.mode = AUMODE_PLAY; if(ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) { SDL_SetError("Couldn't put device into play mode"); return(-1); } mixbuf = NULL; AUDIO_INITINFO(&info); for (format = SDL_FirstAudioFormat(spec->format); format; format = SDL_NextAudioFormat()) { switch(format) { case AUDIO_U8: info.play.encoding = AUDIO_ENCODING_ULINEAR; info.play.precision = 8; break; case AUDIO_S8: info.play.encoding = AUDIO_ENCODING_SLINEAR; info.play.precision = 8; break; case AUDIO_S16LSB: info.play.encoding = AUDIO_ENCODING_SLINEAR_LE; info.play.precision = 16; break; case AUDIO_S16MSB: info.play.encoding = AUDIO_ENCODING_SLINEAR_BE; info.play.precision = 16; break; case AUDIO_U16LSB: info.play.encoding = AUDIO_ENCODING_ULINEAR_LE; info.play.precision = 16; break; case AUDIO_U16MSB: info.play.encoding = AUDIO_ENCODING_ULINEAR_BE; info.play.precision = 16; break; default: continue; } if (ioctl(audio_fd, AUDIO_SETINFO, &info) == 0) break; } if(!format) { SDL_SetError("No supported encoding for 0x%x", spec->format); return(-1); } spec->format = format; AUDIO_INITINFO(&info); info.play.channels = spec->channels; if (ioctl(audio_fd, AUDIO_SETINFO, &info) == -1) spec->channels = 1; AUDIO_INITINFO(&info); info.play.sample_rate = spec->freq; info.blocksize = spec->size; info.hiwat = 5; info.lowat = 3; (void)ioctl(audio_fd, AUDIO_SETINFO, &info); (void)ioctl(audio_fd, AUDIO_GETINFO, &info); spec->freq = info.play.sample_rate; mixlen = spec->size; mixbuf = (Uint8*)SDL_AllocAudioMem(mixlen); if(mixbuf == NULL) { return(-1); } SDL_memset(mixbuf, spec->silence, spec->size); parent = getpid(); #ifdef DEBUG_AUDIO OBSD_Status(this); #endif return(0); }