filename | src/drivers/audio_alsa.c |
changeset | 643:653b0a70f173 |
next | 669:ab344e42bca9 |
author | nkeynes |
date | Sat Apr 19 00:36:36 2008 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Move glsl setup out of the drivers Move pvr2 setup call up to video_gtk (probably needs to go higher really) |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/src/drivers/audio_alsa.c Sat Apr 19 00:36:36 2008 +00001.3 @@ -0,0 +1,203 @@1.4 +/**1.5 + * $Id: audio_esd.c 602 2008-01-15 20:50:23Z nkeynes $1.6 + *1.7 + * The asla audio driver1.8 + *1.9 + * Copyright (c) 2008 Jonathan Muller1.10 + *1.11 + * This program is free software; you can redistribute it and/or modify1.12 + * it under the terms of the GNU General Public License as published by1.13 + * the Free Software Foundation; either version 2 of the License, or1.14 + * (at your option) any later version.1.15 + *1.16 + * This program is distributed in the hope that it will be useful,1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.19 + * GNU General Public License for more details.1.20 + */1.21 +#include <stdio.h>1.22 +#include <unistd.h>1.23 +1.24 +/* Use the newer ALSA API */1.25 +#define ALSA_PCM_NEW_HW_PARAMS_API1.26 +1.27 +#include <alsa/asoundlib.h>1.28 +#include "config.h"1.29 +#include "aica/audio.h"1.30 +#include "dream.h"1.31 +1.32 +1.33 +static snd_pcm_t *_soundDevice = NULL;1.34 +static int frames;1.35 +static int frame_bytes;1.36 +1.37 +1.38 +struct lxdream_config_entry alsa_config[] = {1.39 + {"device", CONFIG_TYPE_FILE, "default"},1.40 + {NULL, CONFIG_TYPE_NONE}1.41 +};1.42 +1.43 +1.44 +gboolean audio_alsa_init( )1.45 +{1.46 + int err;1.47 +1.48 + return TRUE;1.49 +}1.50 +1.51 +1.52 +gboolean audio_alsa_set_format( uint32_t rate, uint32_t format )1.53 +{1.54 + int i;1.55 + int err;1.56 + snd_pcm_hw_params_t *hw_params;1.57 + snd_pcm_sw_params_t *sw_params;1.58 + snd_pcm_uframes_t frames;1.59 + unsigned int resample = 1;1.60 + unsigned int actualRate = rate;1.61 + snd_pcm_uframes_t bufferSize;1.62 + int dir;1.63 +1.64 +1.65 + // Open the device we were told to open.1.66 + err = snd_pcm_open( &_soundDevice, alsa_config[0].value,1.67 + SND_PCM_STREAM_PLAYBACK, 0 );1.68 +1.69 + // Check for error on open.1.70 + if ( err < 0 ) {1.71 + ERROR( "Init: cannot open audio device %s (%s)\n",1.72 + alsa_config[0].value, snd_strerror( err ) );1.73 + return FALSE;1.74 + } else {1.75 + DEBUG( "Audio device opened successfully." );1.76 + }1.77 +1.78 + frame_bytes = ( 2 * ( snd_pcm_format_width( SND_PCM_FORMAT_S16_LE ) / 8 ) );1.79 +1.80 +1.81 + //snd_pcm_hw_params_alloca (&hw_params);1.82 + // Allocate the hardware parameter structure.1.83 + if ( ( err = snd_pcm_hw_params_malloc( &hw_params ) ) < 0 ) {1.84 + ERROR( "Init: cannot allocate hardware parameter structure (%s)\n",1.85 + snd_strerror( err ) );1.86 + return FALSE;1.87 + }1.88 +1.89 + if ( ( err = snd_pcm_hw_params_any( _soundDevice, hw_params ) ) < 0 ) {1.90 + ERROR( "Init: cannot allocate hardware parameter structure (%s)\n",1.91 + snd_strerror( err ) );1.92 + return FALSE;1.93 + }1.94 + // Set access to RW interleaved.1.95 + if ( ( err = snd_pcm_hw_params_set_access( _soundDevice, hw_params,1.96 + SND_PCM_ACCESS_RW_INTERLEAVED ) )1.97 + < 0 ) {1.98 + ERROR( " Init: cannot set access type (%s)\n", snd_strerror( err ) );1.99 + return FALSE;1.100 + }1.101 +1.102 + if ( ( err = snd_pcm_hw_params_set_format( _soundDevice, hw_params,1.103 + SND_PCM_FORMAT_S16_LE ) ) <1.104 + 0 ) {1.105 + ERROR( "Init: cannot set sample format (%s)\n", snd_strerror( err ) );1.106 + return FALSE;1.107 + }1.108 +1.109 + err = snd_pcm_hw_params_set_rate_near( _soundDevice, hw_params, &rate, 0 );1.110 + if ( err < 0 ) {1.111 + ERROR( "Init: Resampling setup failed for playback: %s\n",1.112 + snd_strerror( err ) );1.113 + return err;1.114 + }1.115 + // Set channels to stereo (2).1.116 + err = snd_pcm_hw_params_set_channels( _soundDevice, hw_params, 2 );1.117 + if ( err < 0 ) {1.118 + ERROR( "Init: cannot set channel count (%s)\n", snd_strerror( err ) );1.119 + return FALSE;1.120 + }1.121 +1.122 + // frames = 4410;1.123 + // snd_pcm_hw_params_set_period_size_near( _soundDevice, hw_params, &frames,1.124 + // &dir );1.125 +1.126 + // Apply the hardware parameters that we've set.1.127 + err = snd_pcm_hw_params( _soundDevice, hw_params );1.128 + if ( err < 0 ) {1.129 + DEBUG( "Init: cannot set parameters (%s)\n", snd_strerror( err ) );1.130 + return FALSE;1.131 + } else {1.132 + DEBUG( "Audio device parameters have been set successfully." );1.133 + }1.134 +1.135 + snd_pcm_hw_params_get_period_size( hw_params, &frames, &dir );1.136 + DEBUG( "period size = %d\n", frames );1.137 +1.138 + // Get the buffer size.1.139 + snd_pcm_hw_params_get_buffer_size( hw_params, &bufferSize );1.140 + DEBUG("Buffer Size = %d\n", bufferSize);1.141 +1.142 + // If we were going to do more with our sound device we would want to store1.143 + // the buffer size so we know how much data we will need to fill it with.1.144 +1.145 + //cout << "Init: Buffer size = " << bufferSize << " frames." << endl;1.146 +1.147 + // Display the bit size of samples.1.148 + //cout << "Init: Significant bits for linear samples = " << snd_pcm_hw_params_get_sbits(hw_params) << endl;1.149 +1.150 + // Free the hardware parameters now that we're done with them.1.151 + snd_pcm_hw_params_free( hw_params );1.152 +1.153 + // Set the start threshold to reduce inter-buffer gaps1.154 + snd_pcm_sw_params_alloca( &sw_params );1.155 + snd_pcm_sw_params_current( _soundDevice, sw_params );1.156 + snd_pcm_sw_params_set_start_threshold( _soundDevice, sw_params, bufferSize/2 );1.157 + err = snd_pcm_sw_params( _soundDevice, sw_params );1.158 + if( err < 0 ) {1.159 + ERROR("Unable to set sw params for alsa driver: %s\n", snd_strerror(err));1.160 + return FALSE;1.161 + }1.162 +1.163 + err = snd_pcm_prepare( _soundDevice );1.164 + if ( err < 0 ) {1.165 + ERROR( "Init: cannot prepare audio interface for use (%s)\n",1.166 + snd_strerror( err ) );1.167 + return FALSE;1.168 + }1.169 + return TRUE;1.170 +}1.171 +1.172 +gboolean audio_alsa_process_buffer( audio_buffer_t buffer )1.173 +{1.174 + int err;1.175 + int length;1.176 +1.177 +1.178 + length = buffer->length / frame_bytes;1.179 +1.180 + err = snd_pcm_writei( _soundDevice, buffer->data, length );1.181 + if( err == -EPIPE ) {1.182 + snd_pcm_prepare( _soundDevice );1.183 + } else if( err == -ESTRPIPE ) {1.184 + snd_pcm_resume( _soundDevice );1.185 + }1.186 +1.187 + return TRUE;1.188 +}1.189 +1.190 +1.191 +gboolean audio_alsa_close( )1.192 +{1.193 + int err;1.194 +1.195 + return TRUE;1.196 +}1.197 +1.198 +1.199 +1.200 +struct audio_driver audio_alsa_driver = {1.201 + "alsa",1.202 + audio_alsa_init,1.203 + audio_alsa_set_format,1.204 + audio_alsa_process_buffer,1.205 + audio_alsa_close1.206 +};
.