[alsa-devel] sbxfi - What works/doesn't summary

The Source thesourcehim at gmail.com
Wed Oct 29 17:12:29 CET 2008


Takashi Iwai пишет:
> At Wed, 29 Oct 2008 08:15:04 +0300,
> The Source wrote:
>   
>> Ok, was able to get hw_params:
>> access: MMAP_INTERLEAVED
>> format: S16_LE
>> subformat: STD
>> channels: 2
>> rate: 48000 (48000/1)
>> period_size: 1088
>> buffer_size: 4352
>>
>> Why so weird values?
>>     
>
> Maybe related with the default sample rate 44.1kHz?  Who knows...
>
> Does the patch below have any influence?
> This restricts the period/buffer size aligned to 1024 bytes.
> Also, it may fix the PCM pointer calculation somehow.
>
>
> Takashi
>
> ---
> diff --git a/sound/pci/sbxfi/sbxfi.c b/sound/pci/sbxfi/sbxfi.c
> index e67f768..a2d908e 100644
> --- a/sound/pci/sbxfi/sbxfi.c
> +++ b/sound/pci/sbxfi/sbxfi.c
> @@ -122,6 +122,9 @@ struct sbxfi_port {
>  	/* TLB entry */
>  	int tlb_index;
>  	unsigned int tlb_pages;
> +	/* buffer pointers */
> +	unsigned int start_addr;
> +	unsigned int buffer_bytes;
>  	/* status */
>  	int state;
>  	int need_update;
> @@ -527,8 +530,8 @@ static void sbxfi_playback_start(struct sbxfi *chip, struct sbxfi_port *port)
>  	if (port->tlb_index < 0)
>  		return;
>  	runtime = port->substream->runtime;
> -	start = port->tlb_index * SBXFI_PAGE_SIZE;
> -	loop = start + frames_to_bytes(runtime, runtime->buffer_size);
> +	start = port->start_addr;
> +	loop = start + port->buffer_bytes;
>  
>  	switch (runtime->rate) {
>  	case 48000:
> @@ -579,8 +582,8 @@ static void sbxfi_capture_start(struct sbxfi *chip, struct sbxfi_port *port)
>  	if (port->tlb_index < 0)
>  		return;
>  	runtime = port->substream->runtime;
> -	start = port->tlb_index * SBXFI_PAGE_SIZE;
> -	loop = start + frames_to_bytes(runtime, runtime->buffer_size);
> +	start = port->start_addr;
> +	loop = start + port->buffer_bytes;
>  
>  	switch (runtime->rate) {
>  	case 48000:
> @@ -1320,9 +1323,9 @@ static int sbxfi_playback_open(struct snd_pcm_substream *substream)
>  	set_rate_limit(chip, runtime);
>  	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
>  	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
> -				   128);
> +				   1024 /*128*/);
>  	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
> -				   128);
> +				   1024 /*128*/);
>  	return 0;
>  }
>  
> @@ -1349,9 +1352,9 @@ static int sbxfi_capture_open(struct snd_pcm_substream *substream)
>  	set_rate_limit(chip, runtime);
>  	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
>  	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
> -				   128);
> +				   1024 /*128*/);
>  	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
> -				   128);
> +				   1024 /*128*/);
>  	return 0;
>  }
>  
> @@ -1399,6 +1402,9 @@ static int sbxfi_playback_prepare(struct snd_pcm_substream *substream)
>  	port->frag_count = runtime->period_size;
>  	port->need_update = 0;
>  
> +	port->start_addr = port->tlb_index * SBXFI_PAGE_SIZE;
> +	port->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size);
> +
>  	sbxfi_setup_play_pitch(chip, port);
>  	sbxfi_setup_play_mixer(chip, port);
>  	sbxfi_setup_play_mapper(chip, port);
> @@ -1417,6 +1423,9 @@ static int sbxfi_capture_prepare(struct snd_pcm_substream *substream)
>  	port->frag_count = runtime->period_size;
>  	port->need_update = 0;
>  
> +	port->start_addr = port->tlb_index * SBXFI_PAGE_SIZE;
> +	port->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size);
> +
>  	sbxfi_init_adc(chip, chip->capsrc, chip->micboost);
>  
>  	sbxfi_setup_capture_mapper(chip, port);
> @@ -1477,10 +1486,12 @@ sbxfi_pcm_pointer(struct snd_pcm_substream *substream)
>  	unsigned int pos;
>  
>  	pos = sbxfi_read(chip, SRCCA(port->src[0])) & 0x03ffffff;
> -	pos -= port->tlb_index * SBXFI_PAGE_SIZE;
> +	pos -= port->start_addr;
>  	/* The pointer is always 128 bytes ahead */
>  	if (pos >= CA_OFFSET)
>  		pos -= CA_OFFSET;
> +	else
> +		pos = pos + port->buffer_bytes - CA_OFFSET;
>  	pos = bytes_to_frames(runtime, pos);
>  	pos %= runtime->buffer_size;
>  	LOG(2, "POINTER = 0x%x\n", pos);
>
>   
Patch doesn't help. Though it really makes period and buffer to be 
aligned to 1024.
I have discovered however that sound only gets corrupted if wine tries 
to use alsa directly.
If it uses pulseaudio (it's eSound emulation), sound is fine. Other apps 
(including MPlayer) with pulseaudio work just fine.
dmesg output with debug=2 for the case when wine uses alsa directly is 
attached.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dmesg.out.bz2
Type: application/x-bzip
Size: 1725 bytes
Desc: not available
Url : http://mailman.alsa-project.org/pipermail/alsa-devel/attachments/20081029/f962abad/attachment-0001.bz2 


More information about the Alsa-devel mailing list