#include <libdv/dv_types.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <strings.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/soundcard.h>#include "oss.h"Include dependency graph for oss.c:

Go to the source code of this file.
Functions | |
| kino_sound_t * | kino_sound_new (void) |
| int | kino_sound_init (dv_audio_t *audio, kino_sound_t *sound, char const *device) |
| int | kino_sound_player (kino_sound_t *sound, void *data, int size) |
| int | kino_sound_play (dv_audio_t *audio, kino_sound_t *sound, int16_t **out) |
| void | kino_sound_close (kino_sound_t *sound) |
|
|
Definition at line 400 of file oss.c. Referenced by PageMagick::AudioThread(), and FrameDisplayer::CloseSound(). 00401 {
00402 if ( sound != NULL )
00403 {
00404 if ( sound->fd != -1 )
00405 close( sound->fd );
00406 if ( sound->buffer )
00407 free( sound->buffer );
00408 #ifdef HAVE_ALSA
00409 if ( sound->pcmh )
00410 snd_pcm_close( sound->pcmh );
00411 if ( sound->hwparams )
00412 free( sound->hwparams );
00413 #endif
00414 free( sound );
00415 }
00416 }
|
|
||||||||||||||||
|
Definition at line 63 of file oss.c. References kino_sound_t::buffer, DV_AUDIO_MAX_SAMPLES, and kino_sound_t::fd. Referenced by PageMagick::PlayAudio(), and FrameDisplayer::PutSound(). 00064 {
00065 int rate_request, channels_request, fragment_request;
00066 int used = audio->frequency;
00067
00068 channels_request = audio->num_channels;
00069 rate_request = audio->frequency;
00070 fragment_request = 0x0004000B;
00071 sound->buffer = NULL;
00072
00073 if ( channels_request == 0 || rate_request == 0 )
00074 return FALSE;
00075
00076 if ( !device || !*device )
00077 device = "plughw:0,0";
00078
00079 /* open audio device
00080 Open nonblocking first, to test if available. */
00081 sound->fd = open( device, O_WRONLY | O_NONBLOCK | O_NDELAY );
00082 if ( sound->fd != -1 )
00083 {
00084 close( sound->fd );
00085 sound->fd = open( device, O_WRONLY );
00086 }
00087 if ( sound->fd != -1 )
00088 {
00089 /* OSS */
00090 int format = AFMT_S16_NE;
00091 int error = 0;
00092 if ( ioctl( sound->fd, SNDCTL_DSP_SETFRAGMENT, &fragment_request ) == -1 )
00093 {
00094 perror( "SNDCTL_DSP_SETFMT" );
00095 error = 1;
00096 }
00097 if ( error == 0 && ioctl( sound->fd, SOUND_PCM_WRITE_BITS, &format ) == -1 )
00098 {
00099 perror( "SNDCTL_DSP_SETFMT" );
00100 error = 2;
00101 }
00102 if ( error == 0 && format != AFMT_S16_NE )
00103 {
00104 fprintf( stderr, "soundcard doesn't support format\n" );
00105 error = 3;
00106 }
00107 if ( error == 0 && ioctl( sound->fd, SOUND_PCM_WRITE_CHANNELS, &channels_request ) )
00108 {
00109 fprintf( stderr, "soundcard doesn't support %d channels\n", audio->num_channels );
00110 error = 4;
00111 }
00112 if ( error == 0 && channels_request != audio->num_channels )
00113 {
00114 fprintf( stderr, "soundcard doesn't support %d channels\n", audio->num_channels );
00115 error = 5;
00116 }
00117 if ( error == 0 && ioctl( sound->fd, SOUND_PCM_WRITE_RATE, &rate_request ) == -1 )
00118 {
00119 perror( "SNDCTL_DSP_SPEED" );
00120 error = 6;
00121 }
00122 if ( error == 0 && rate_request != audio->frequency )
00123 {
00124 perror( "SNDCTL_DSP_SPEED" );
00125 error = 7;
00126 }
00127
00128 if ( error == 6 || error == 7 )
00129 {
00130 rate_request = 44100;
00131 used = rate_request;
00132 fprintf( stderr, ">>> audio at %d failed - forcing resample at %dhz\n", audio->frequency, rate_request );
00133 if ( ioctl( sound->fd, SOUND_PCM_WRITE_RATE, &rate_request ) == -1 )
00134 {
00135 perror( "SNDCTL_DSP_SPEED 44.1" );
00136 used = 0;
00137 error = 6;
00138 }
00139 else
00140 {
00141 error = 0;
00142 }
00143 if ( error == 0 && rate_request != 44100 )
00144 {
00145 perror( "SNDCTL_DSP_SPEED" );
00146 error = 7;
00147 used = 0;
00148 }
00149 }
00150
00151 if ( error == 0 )
00152 {
00153 sound->buffer = malloc( DV_AUDIO_MAX_SAMPLES * audio->num_channels * sizeof( int16_t ) );
00154 if ( sound->buffer == NULL )
00155 {
00156 fprintf( stderr, "Unable to allocate memory for the buffer\n" );
00157 error = 8;
00158 }
00159 }
00160
00161 if ( error != 0 )
00162 {
00163 close( sound->fd );
00164 sound->fd = -1;
00165 used = 0;
00166 }
00167 }
00168 #ifdef HAVE_ALSA
00169 else
00170 {
00171 /* ALSA */
00172 int serr;
00173 int error;
00174
00175 sound->hwparams = NULL;
00176 sound->writefail_noted = 0;
00177
00178 if ( channels_request == 0 || rate_request == 0 )
00179 return FALSE;
00180
00181 sound->channels = audio->num_channels;
00182
00183 if ((serr = snd_pcm_open(&sound->pcmh, device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0)
00184 {
00185 fprintf(stderr, "Could not open ALSA device \"%s\": %s\n", device ? device : "(default)", snd_strerror(serr));
00186 return FALSE;
00187 }
00188
00189 snd_pcm_nonblock(sound->pcmh, 0);
00190
00191 error = 0;
00192
00193 if ((serr = snd_pcm_hw_params_malloc(&sound->hwparams)) < 0)
00194 {
00195 fprintf(stderr, "Could not allocate ALSA hardware parameters: %s\n", snd_strerror(serr));
00196 error = 8;
00197 }
00198
00199 if (!error &&
00200 (serr = snd_pcm_hw_params_any(sound->pcmh, sound->hwparams)) < 0)
00201 {
00202 fprintf(stderr, "Could not get ALSA hardware parameters: %s\n", snd_strerror(serr));
00203 error = 1;
00204 }
00205 if (!error &&
00206 (serr = snd_pcm_hw_params_set_access(sound->pcmh, sound->hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
00207 {
00208 fprintf(stderr, "Could not set ALSA interleaved access: %s\n", snd_strerror(serr));
00209 error = 2;
00210 }
00211 if (!error &&
00212 (serr = snd_pcm_hw_params_set_format(sound->pcmh, sound->hwparams, SND_PCM_FORMAT_S16)) < 0)
00213 {
00214 fprintf(stderr, "Could not set ALSA sample format: %s\n", snd_strerror(serr));
00215 error = 2;
00216 }
00217 if (!error &&
00218 (serr = snd_pcm_hw_params_set_channels(sound->pcmh, sound->hwparams, channels_request)) < 0)
00219 {
00220 fprintf(stderr, "Could not set ALSA channels to %d: %s\n", channels_request, snd_strerror(serr));
00221 error = 4;
00222 }
00223 if (!error &&
00224 (serr = snd_pcm_hw_params_set_rate_resample(sound->pcmh, sound->hwparams, 1)) < 0)
00225 {
00226 fprintf(stderr, "Could not set ALSA resampling: %s\n", snd_strerror(serr));
00227 error = 7;
00228 }
00229
00230 if (!error &&
00231 (serr = snd_pcm_hw_params_set_rate_near(sound->pcmh, sound->hwparams, ( unsigned* )&rate_request, 0)) < 0)
00232 {
00233 fprintf(stderr, "Could not set ALSA rate to %d: %s\n", rate_request, snd_strerror(serr));
00234 error = 6;
00235 }
00236
00237 if (!error &&
00238 (serr = snd_pcm_hw_params(sound->pcmh, sound->hwparams)) < 0)
00239 {
00240 fprintf(stderr, "Could not set ALSA Hardware parameters %s\n", snd_strerror(serr));
00241 error = 9;
00242 }
00243
00244 if (!error)
00245 {
00246 sound->buffer = malloc( DV_AUDIO_MAX_SAMPLES * audio->num_channels * sizeof( int16_t ) );
00247 if ( sound->buffer == NULL )
00248 {
00249 fprintf( stderr, "Unable to allocate memory for the buffer\n" );
00250 error = 8;
00251 }
00252 }
00253
00254 if (error)
00255 {
00256 fprintf( stderr, "Unable to open audio device %s\n", device );
00257 snd_pcm_close(sound->pcmh);
00258 if (sound->hwparams)
00259 free(sound->hwparams);
00260 sound->pcmh = 0;
00261 used = 0;
00262 }
00263 }
00264 #endif
00265 return used;
00266 }
|
|
|
Definition at line 45 of file oss.c. References kino_sound_t::fd. Referenced by PageMagick::AudioThread(), and FrameDisplayer::PutSound(). 00046 {
00047 kino_sound_t * result;
00048
00049 result = ( kino_sound_t * ) calloc( 1, sizeof( kino_sound_t ) );
00050 if ( result != NULL )
00051 {
00052 result->fd = -1;
00053 }
00054
00055 return result;
00056 }
|
|
||||||||||||||||
|
Definition at line 322 of file oss.c. References kino_sound_t::arg_audio_file, kino_sound_t::buffer, and kino_sound_t::fd. Referenced by PageMagick::PlayAudio(). 00323 {
00324 int ch, i, j = 0, total, written = 0, result;
00325
00326 /* Interleave the audio into a single buffer */
00327 for ( i = 0; i < audio->samples_this_frame; i++ )
00328 {
00329 for ( ch = 0; ch < audio->num_channels; ch++ )
00330 {
00331 sound->buffer[ j++ ] = out[ ch ][ i ];
00332 }
00333 }
00334
00335 if ( sound->fd > -1 )
00336 {
00337 /* OSS */
00338 total = audio->samples_this_frame * audio->num_channels * sizeof( int16_t );
00339 do
00340 {
00341 result = write( sound->fd, sound->buffer, total );
00342 if ( result != total )
00343 goto write_error;
00344 written += result;
00345 }
00346 while ( total > written );
00347 if ( !sound->arg_audio_file )
00348 {
00349 if ( ioctl( sound->fd, SNDCTL_DSP_POST, NULL ) == -1 )
00350 goto post_ioctl;
00351 } /* if */
00352
00353 return ( TRUE );
00354
00355 write_error:
00356 perror( "write" );
00357 return ( FALSE );
00358
00359 post_ioctl:
00360 perror( "SNDCTL_DSP_POST" );
00361 return ( FALSE );
00362 }
00363 #ifdef HAVE_ALSA
00364 else
00365 {
00366 /* ALSA */
00367 total = audio->samples_this_frame;
00368 do
00369 {
00370 result = snd_pcm_writei( sound->pcmh, sound->buffer + written * audio->num_channels, total - written );
00371 if ( result == -EAGAIN )
00372 {
00373 snd_pcm_wait( sound->pcmh, 1000 );
00374 result = snd_pcm_writei( sound->pcmh, sound->buffer + written * audio->num_channels, total - written );
00375 }
00376 else if ( result == -EPIPE )
00377 {
00378 snd_pcm_prepare( sound->pcmh );
00379 result = snd_pcm_writei( sound->pcmh, sound->buffer + written * audio->num_channels, total - written );
00380 }
00381 if (result < 0)
00382 {
00383 if (!sound->writefail_noted)
00384 {
00385 sound->writefail_noted = 1;
00386 fprintf( stderr, "Could not write to ALSA: %s\n", snd_strerror ( result ) );
00387 }
00388 return FALSE;
00389 }
00390 written += result;
00391 }
00392 while ( total > written );
00393
00394 return ( TRUE );
00395 }
00396 #endif
00397 }
|
|
||||||||||||||||
|
Definition at line 269 of file oss.c. References kino_sound_t::fd. Referenced by FrameDisplayer::PutSound(). 00270 {
00271 if ( sound->fd > -1 )
00272 {
00273 /* OSS */
00274 return write( sound->fd, data, size ) == size;
00275 }
00276 #ifdef HAVE_ALSA
00277 else
00278 {
00279 /* ALSA */
00280 int frames = size / sound->channels / sizeof(int16_t);
00281 int result;
00282 int16_t *framedata = data;
00283
00284 while (frames > 0)
00285 {
00286 result = snd_pcm_writei( sound->pcmh, framedata, frames );
00287 if ( result == -EAGAIN )
00288 {
00289 snd_pcm_wait( sound->pcmh, 1000 );
00290 result = snd_pcm_writei( sound->pcmh, framedata, frames );
00291 }
00292 else if ( result == -EPIPE )
00293 {
00294 snd_pcm_prepare( sound->pcmh );
00295 result = snd_pcm_writei( sound->pcmh, framedata, frames );
00296 }
00297 if (result < 0)
00298 {
00299 if (!sound->writefail_noted)
00300 {
00301 sound->writefail_noted = 1;
00302 fprintf( stderr, "Could not write to ALSA: %s\n", snd_strerror ( result ) );
00303 }
00304 return FALSE;
00305 }
00306 framedata += result * sound->channels;
00307 frames -= result;
00308 }
00309 if ( framedata != ( int16_t* )( (char *) data + size ) )
00310 {
00311 fprintf(stderr, "Misaligned after write to ALSA: should be at %p, but we are at %p\n",
00312 (char *) data + size,
00313 framedata);
00314 }
00315 return TRUE;
00316 }
00317 #endif
00318 return FALSE;
00319 }
|
1.4.2