diff --git a/cfg-mplayer.h b/cfg-mplayer.h index 0ce55ab9e9..74dab8c60b 100644 --- a/cfg-mplayer.h +++ b/cfg-mplayer.h @@ -74,6 +74,9 @@ extern int pl_delay_len; /* from libvo/aspect.c */ extern float monitor_aspect; +/* from dec_audio, currently used for ac3surround decoder only */ +extern int audio_output_channels; + /* * CONF_TYPE_FUNC_FULL : * allows own implemtations for passing the params @@ -103,6 +106,7 @@ struct config conf[]={ {"dsp", "Use -ao oss:dsp_path!\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0}, {"mixer", &mixer_device, CONF_TYPE_STRING, 0, 0, 0}, {"master", &mixer_usemaster, CONF_TYPE_FLAG, 0, 0, 1}, + {"channels", &audio_output_channels, CONF_TYPE_INT, CONF_RANGE, 2, 6}, #ifdef HAVE_X11 {"display", &mDisplayName, CONF_TYPE_STRING, 0, 0, 0}, #endif diff --git a/dec_audio.c b/dec_audio.c index c13c2880ab..52de2bebf2 100644 --- a/dec_audio.c +++ b/dec_audio.c @@ -83,6 +83,9 @@ static struct mad_stream mad_stream; static struct mad_frame mad_frame; static struct mad_synth mad_synth; +/* used for ac3surround decoder - set using -channels option */ +int audio_output_channels = 2; + // ensure buffer is filled with some data static void mad_prepare_buffer(sh_audio_t* sh_audio, struct mad_stream* ms, int length) @@ -228,7 +231,8 @@ case AFM_ALAW: break; case AFM_AC3: // Dolby AC3 audio: - sh_audio->audio_out_minsize=4*256*6; + // however many channels, 2 bytes in a word, 256 samples in a block, 6 blocks in a frame + sh_audio->audio_out_minsize=audio_output_channels*2*256*6; break; case AFM_HWAC3: // Dolby AC3 audio: @@ -329,7 +333,7 @@ case AFM_AC3: { // Dolby AC3 audio: dec_audio_sh=sh_audio; // save sh_audio for the callback: ac3_config.fill_buffer_callback = ac3_fill_buffer; - ac3_config.num_output_ch = 2; + ac3_config.num_output_ch = audio_output_channels; ac3_config.flags = 0; if(gCpuCaps.hasMMX){ ac3_config.flags |= AC3_MMX_ENABLE; @@ -342,7 +346,7 @@ if(gCpuCaps.has3DNow){ if(sh_audio->ac3_frame){ ac3_frame_t* fr=(ac3_frame_t*)sh_audio->ac3_frame; sh_audio->samplerate=fr->sampling_rate; - sh_audio->channels=2; + sh_audio->channels=ac3_config.num_output_ch; // 1 frame: 6*256 samples 1 sec: sh_audio->samplerate samples //sh_audio->i_bps=fr->frame_size*fr->sampling_rate/(6*256); sh_audio->i_bps=fr->bit_rate*(1000/8); diff --git a/help_mp-en.h b/help_mp-en.h index 776179e01a..577123a85a 100644 --- a/help_mp-en.h +++ b/help_mp-en.h @@ -33,6 +33,7 @@ static char help_text[]= #ifdef USE_FAKE_MONO " -stereo select MPEG1 stereo output (0:stereo 1:left 2:right)\n" #endif +" -channels target number of audio output channels\n" " -fs -vm -zoom fullscreen playing options (fullscr,vidmode chg,softw.scale)\n" " -x -y scale image to * resolution [if -vo driver supports!]\n" " -sub specify subtitle file to use (see also -subfps, -subdelay)\n" diff --git a/libao2/ao_oss.c b/libao2/ao_oss.c index 82da0df89e..aad1c943d6 100644 --- a/libao2/ao_oss.c +++ b/libao2/ao_oss.c @@ -26,6 +26,8 @@ static ao_info_t info = "" }; +/* Support for >2 output channels added 2001-11-25 - Steve Davies */ + LIBAO_EXTERN(oss) static char *dsp="/dev/dsp"; @@ -95,8 +97,8 @@ static int control(int cmd,int arg){ // return: 1=success 0=fail static int init(int rate,int channels,int format,int flags){ -// printf("ao2: %d Hz %d chans %s\n",rate,channels, -// audio_out_format_name(format)); + printf("ao2: %d Hz %d chans %s\n",rate,channels, + audio_out_format_name(format)); if (ao_subdevice) dsp = ao_subdevice; @@ -124,13 +126,26 @@ static int init(int rate,int channels,int format,int flags){ audio_out_format_name(ao_data.format), audio_out_format_name(format)); if(format != AFMT_AC3) { - ao_data.channels=channels-1; - ioctl (audio_fd, SNDCTL_DSP_STEREO, &ao_data.channels); - - // set rate - ao_data.samplerate=rate; - ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); - printf("audio_setup: using %d Hz samplerate (requested: %d)\n",ao_data.samplerate,rate); + // We only use SNDCTL_DSP_CHANNELS for >2 channels, in case some drivers don't have it + ao_data.channels = channels; + if (ao_data.channels > 2) { + if (ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &ao_data.channels) == -1) { + printf("audio_setup: Failed to set audio device to %d channels\n", ao_data.channels); + return 0; + } + } + else { + int c = ao_data.channels-1; + if (ioctl (audio_fd, SNDCTL_DSP_STEREO, &c) == -1) { + printf("audio_setup: Failed to set audio device to %d channels\n", ao_data.channels); + return 0; + } + } + printf("audio_setup: using %d channels (requested: %d)\n", ao_data.channels, ao_data.channels); + // set rate + ao_data.samplerate=rate; + ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); + printf("audio_setup: using %d Hz samplerate (requested: %d)\n",ao_data.samplerate,rate); } if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)==-1){ @@ -195,8 +210,13 @@ static void reset(){ ioctl (audio_fd, SNDCTL_DSP_SETFMT, &ao_data.format); if(ao_data.format != AFMT_AC3) { - ioctl (audio_fd, SNDCTL_DSP_STEREO, &ao_data.channels); - ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); + if (ao_data.channels > 2) + ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &ao_data.channels); + else { + int c = ao_data.channels-1; + ioctl (audio_fd, SNDCTL_DSP_STEREO, &c); + } + ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate); } } @@ -267,7 +287,3 @@ static float get_delay(){ } return ((float)ao_data.buffersize)/(float)ao_data.bps; } - - - -