コード例 #1
0
static int Audio_Available(void)
{
	int available;
	int status;
	snd_pcm_t *handle;

	available = 0;
	status = snd_pcm_open(&handle, get_audio_device(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
	if ( status >= 0 ) {
		available = 1;
        	snd_pcm_close(handle);
	}
	return(available);
}
コード例 #2
0
ファイル: SDL_alsa_audio.c プロジェクト: RDCH106/n64oid
static int Audio_Available(void)
{
	int available;
	int status;
	snd_pcm_t *handle;

	available = 0;
	if (LoadALSALibrary() < 0) {
		return available;
	}
	status = SDL_NAME(snd_pcm_open)(&handle, get_audio_device(2), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
	if ( status >= 0 ) {
		available = 1;
        	SDL_NAME(snd_pcm_close)(handle);
	}
	UnloadALSALibrary();
	return(available);
}
コード例 #3
0
ファイル: SDL_alsa_audio.c プロジェクト: RDCH106/n64oid
static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
	int                  status;
	snd_pcm_hw_params_t *hwparams;
	snd_pcm_sw_params_t *swparams;
	snd_pcm_format_t     format;
	snd_pcm_uframes_t    frames;
	Uint16               test_format;

	/* Open the audio device */
	/* Name of device should depend on # channels in spec */
	status = SDL_NAME(snd_pcm_open)(&pcm_handle, get_audio_device(spec->channels), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);

	if ( status < 0 ) {
		SDL_SetError("Couldn't open audio device: %s", SDL_NAME(snd_strerror)(status));
		return(-1);
	}

	/* Figure out what the hardware is capable of */
	snd_pcm_hw_params_alloca(&hwparams);
	status = SDL_NAME(snd_pcm_hw_params_any)(pcm_handle, hwparams);
	if ( status < 0 ) {
		SDL_SetError("Couldn't get hardware config: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

	/* SDL only uses interleaved sample output */
	status = SDL_NAME(snd_pcm_hw_params_set_access)(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set interleaved access: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

	/* Try for a closest match on audio format */
	status = -1;
	for ( test_format = SDL_FirstAudioFormat(spec->format);
	      test_format && (status < 0); ) {
		switch ( test_format ) {
			case AUDIO_U8:
				format = SND_PCM_FORMAT_U8;
				break;
			case AUDIO_S8:
				format = SND_PCM_FORMAT_S8;
				break;
			case AUDIO_S16LSB:
				format = SND_PCM_FORMAT_S16_LE;
				break;
			case AUDIO_S16MSB:
				format = SND_PCM_FORMAT_S16_BE;
				break;
			case AUDIO_U16LSB:
				format = SND_PCM_FORMAT_U16_LE;
				break;
			case AUDIO_U16MSB:
				format = SND_PCM_FORMAT_U16_BE;
				break;
			default:
				format = 0;
				break;
		}
		if ( format != 0 ) {
			status = SDL_NAME(snd_pcm_hw_params_set_format)(pcm_handle, hwparams, format);
		}
		if ( status < 0 ) {
			test_format = SDL_NextAudioFormat();
		}
	}
	if ( status < 0 ) {
		SDL_SetError("Couldn't find any hardware audio formats");
		ALSA_CloseAudio(this);
		return(-1);
	}
	spec->format = test_format;

	/* Set the number of channels */
	status = SDL_NAME(snd_pcm_hw_params_set_channels)(pcm_handle, hwparams, spec->channels);
	if ( status < 0 ) {
		status = SDL_NAME(snd_pcm_hw_params_get_channels)(hwparams);
		if ( (status <= 0) || (status > 2) ) {
			SDL_SetError("Couldn't set audio channels");
			ALSA_CloseAudio(this);
			return(-1);
		}
		spec->channels = status;
	}

	/* Set the audio rate */
	status = SDL_NAME(snd_pcm_hw_params_set_rate_near)(pcm_handle, hwparams, spec->freq, NULL);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set audio frequency: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}
	spec->freq = status;

	/* Set the buffer size, in samples */
	frames = spec->samples;
	frames = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, hwparams, frames, NULL);
	spec->samples = frames;
	SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, hwparams, 2, NULL);

	/* "set" the hardware with the desired parameters */
	status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, hwparams);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set hardware audio parameters: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

/* This is useful for debugging... */
/*
{ snd_pcm_sframes_t bufsize; int fragments;
   bufsize = SDL_NAME(snd_pcm_hw_params_get_period_size)(hwparams);
   fragments = SDL_NAME(snd_pcm_hw_params_get_periods)(hwparams);

   fprintf(stderr, "ALSA: bufsize = %ld, fragments = %d\n", bufsize, fragments);
}
*/

	/* Set the software parameters */
	snd_pcm_sw_params_alloca(&swparams);
	status = SDL_NAME(snd_pcm_sw_params_current)(pcm_handle, swparams);
	if ( status < 0 ) {
		SDL_SetError("Couldn't get software config: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}
	status = SDL_NAME(snd_pcm_sw_params_set_start_threshold)(pcm_handle, swparams, 0);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set start threshold: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}
	status = SDL_NAME(snd_pcm_sw_params_set_avail_min)(pcm_handle, swparams, frames);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set avail min: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}
	status = SDL_NAME(snd_pcm_sw_params)(pcm_handle, swparams);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set software audio parameters: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

	/* Calculate the final parameters for this audio specification */
	SDL_CalculateAudioSpec(spec);

	/* Allocate mixing buffer */
	mixlen = spec->size;
	mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen);
	if ( mixbuf == NULL ) {
		ALSA_CloseAudio(this);
		return(-1);
	}
	SDL_memset(mixbuf, spec->silence, spec->size);

	/* Get the parent process id (we're the parent of the audio thread) */
	parent = getpid();

	/* Switch to blocking mode for playback */
	SDL_NAME(snd_pcm_nonblock)(pcm_handle, 0);

	/* We're ready to rock and roll. :-) */
	return(0);
}
コード例 #4
0
ファイル: SDL_alsa_audio.c プロジェクト: Cpasjuste/SDL-13
static int
ALSA_OpenDevice(_THIS, const char *devname, int iscapture)
{
    int status = 0;
    snd_pcm_t *pcm_handle = NULL;
    snd_pcm_hw_params_t *hwparams = NULL;
    snd_pcm_sw_params_t *swparams = NULL;
    snd_pcm_format_t format = 0;
    snd_pcm_uframes_t frames = 0;
    SDL_AudioFormat test_format = 0;

    /* 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));

    /* Open the audio device */
    /* Name of device should depend on # channels in spec */
    status = ALSA_snd_pcm_open(&pcm_handle,
                               get_audio_device(this->spec.channels),
                               SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);

    if (status < 0) {
        ALSA_CloseDevice(this);
        SDL_SetError("ALSA: Couldn't open audio device: %s",
                     ALSA_snd_strerror(status));
        return 0;
    }

    this->hidden->pcm_handle = pcm_handle;

    /* Figure out what the hardware is capable of */
    snd_pcm_hw_params_alloca(&hwparams);
    status = ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams);
    if (status < 0) {
        ALSA_CloseDevice(this);
        SDL_SetError("ALSA: Couldn't get hardware config: %s",
                     ALSA_snd_strerror(status));
        return 0;
    }

    /* SDL only uses interleaved sample output */
    status = ALSA_snd_pcm_hw_params_set_access(pcm_handle, hwparams,
                                               SND_PCM_ACCESS_RW_INTERLEAVED);
    if (status < 0) {
        ALSA_CloseDevice(this);
        SDL_SetError("ALSA: Couldn't set interleaved access: %s",
                     ALSA_snd_strerror(status));
        return 0;
    }

    /* Try for a closest match on audio format */
    status = -1;
    for (test_format = SDL_FirstAudioFormat(this->spec.format);
         test_format && (status < 0);) {
        status = 0;             /* if we can't support a format, it'll become -1. */
        switch (test_format) {
        case AUDIO_U8:
            format = SND_PCM_FORMAT_U8;
            break;
        case AUDIO_S8:
            format = SND_PCM_FORMAT_S8;
            break;
        case AUDIO_S16LSB:
            format = SND_PCM_FORMAT_S16_LE;
            break;
        case AUDIO_S16MSB:
            format = SND_PCM_FORMAT_S16_BE;
            break;
        case AUDIO_U16LSB:
            format = SND_PCM_FORMAT_U16_LE;
            break;
        case AUDIO_U16MSB:
            format = SND_PCM_FORMAT_U16_BE;
            break;
        case AUDIO_S32LSB:
            format = SND_PCM_FORMAT_S32_LE;
            break;
        case AUDIO_S32MSB:
            format = SND_PCM_FORMAT_S32_BE;
            break;
        case AUDIO_F32LSB:
            format = SND_PCM_FORMAT_FLOAT_LE;
            break;
        case AUDIO_F32MSB:
            format = SND_PCM_FORMAT_FLOAT_BE;
            break;
        default:
            status = -1;
            break;
        }
        if (status >= 0) {
            status = ALSA_snd_pcm_hw_params_set_format(pcm_handle,
                                                       hwparams, format);
        }
        if (status < 0) {
            test_format = SDL_NextAudioFormat();
        }
    }
    if (status < 0) {
        ALSA_CloseDevice(this);
        SDL_SetError("ALSA: Couldn't find any hardware audio formats");
        return 0;
    }
    this->spec.format = test_format;

    /* Set the number of channels */
    status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams,
                                                 this->spec.channels);
    if (status < 0) {
        status = ALSA_snd_pcm_hw_params_get_channels(hwparams);
        if ((status <= 0) || (status > 2)) {
            ALSA_CloseDevice(this);
            SDL_SetError("ALSA: Couldn't set audio channels");
            return 0;
        }
        this->spec.channels = status;
    }

    /* Set the audio rate */
    status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
                                                  this->spec.freq, NULL);
    if (status < 0) {
        ALSA_CloseDevice(this);
        SDL_SetError("ALSA: Couldn't set audio frequency: %s",
                     ALSA_snd_strerror(status));
        return 0;
    }
    this->spec.freq = status;

    /* Set the buffer size, in samples */
    frames = this->spec.samples;
    frames = ALSA_snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams,
                                                         frames, NULL);
    this->spec.samples = frames;
    ALSA_snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, 2, NULL);

    /* "set" the hardware with the desired parameters */
    status = ALSA_snd_pcm_hw_params(pcm_handle, hwparams);
    if (status < 0) {
        ALSA_CloseDevice(this);
        SDL_SetError("ALSA: Couldn't set hardware audio parameters: %s",
                     ALSA_snd_strerror(status));
        return 0;
    }
#if AUDIO_DEBUG
    {
        snd_pcm_sframes_t bufsize;
        int fragments;
        bufsize = ALSA_snd_pcm_hw_params_get_period_size(hwparams);
        fragments = ALSA_snd_pcm_hw_params_get_periods(hwparams);
        fprintf(stderr, "ALSA: bufsize = %ld, fragments = %d\n", bufsize,
                fragments);
    }
#endif

    /* Set the software parameters */
    snd_pcm_sw_params_alloca(&swparams);
    status = ALSA_snd_pcm_sw_params_current(pcm_handle, swparams);
    if (status < 0) {
        ALSA_CloseDevice(this);
        SDL_SetError("ALSA: Couldn't get software config: %s",
                     ALSA_snd_strerror(status));
        return 0;
    }
    status =
        ALSA_snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, 0);
    if (status < 0) {
        ALSA_CloseDevice(this);
        SDL_SetError("ALSA: Couldn't set start threshold: %s",
                     ALSA_snd_strerror(status));
        return 0;
    }
    status =
        ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, frames);
    if (status < 0) {
        ALSA_CloseDevice(this);
        SDL_SetError("Couldn't set avail min: %s", ALSA_snd_strerror(status));
        return 0;
    }
    status = ALSA_snd_pcm_sw_params(pcm_handle, swparams);
    if (status < 0) {
        ALSA_CloseDevice(this);
        SDL_SetError("Couldn't set software audio parameters: %s",
                     ALSA_snd_strerror(status));
        return 0;
    }

    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);

    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        ALSA_CloseDevice(this);
        SDL_OutOfMemory();
        return 0;
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);

    /* Get the parent process id (we're the parent of the audio thread) */
    this->hidden->parent = getpid();

    /* Switch to blocking mode for playback */
    ALSA_snd_pcm_nonblock(pcm_handle, 0);

    /* We're ready to rock and roll. :-) */
    return 1;
}