sbp
Posts: 128
Joined: Wed Sep 26, 2012 7:54 pm

192 kHz audio via HDMI - almost working as it should

Sun Jul 28, 2013 6:22 am

Hi
I have been modifying the /sound/arm/bcm2835-pcm.c file and compiled the kernel and modules, and now the raspberry can play audio files up to 192/24.

Part of the original file I manipulated:

Code: Select all

<linux/interrupt.h>
#include <linux/slab.h>

#include "bcm2835.h"

/* hardware definition */
static struct snd_pcm_hardware snd_bcm2835_playback_hw = {
	.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
		 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
	.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
	.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
	.rate_min = 8000,
	.rate_max = 48000,
	.channels_min = 1,
	.channels_max = 2,
	.buffer_bytes_max = 128 * 1024,
	.period_bytes_min =   1 * 1024,
	.period_bytes_max = 128 * 1024,
	.periods_min = 1,
	.periods_max = 128,
};
I changed it to:

Code: Select all

#include <linux/slab.h>

#include "bcm2835.h"

/* hardware definition */
static struct snd_pcm_hardware snd_bcm2835_playback_hw = {
	.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
		 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
	.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE  | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
	.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
	.rate_min = 8000,
	.rate_max = 1920000,
	.channels_min = 1,
	.channels_max = 2,
	.buffer_bytes_max = 256 * 1024,
	.period_bytes_min =   1 * 1024,
	.period_bytes_max = 256 * 1024,
	.periods_min = 1,
	.periods_max = 256,
};
The only problem is that no matter what file we are playing (44.1/16 or 192/24) it will be played with the correct sample rate that is 44100 and 192000, but all are played with 32 bit depth. So it seems that it only uses the last format mentioned on the .format line - so now it always use SNDRV_PCM_FMTBIT_S32_LE

All the 24 bit files 88.1 96 qnd 192 plays fine, whereas the lower resolution files 16 bit at 44.1 and 48 kHz plays, but with some distortion.

If I change this line to: .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE it plays everything at 16 bit
If I change this line to .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE it only produces noise
If I change this line to .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_3LE it only produces noise

So there seems to be a couple of questions:
1. why does it only use the the last option in the .formats line?
2. why can't it use the 24 bits format?
3. The change from 16 and 24 bit to 32 bit when playing will it negatively affect the sound quality. I cant hear any difference, but my equipment is not so good.

Steen

Here is the output when playing a 44.1/16 flac file
cat /proc/asound/card0/pcm0p/sub0/hw_params
access: RW_INTERLEAVED
format: S32_LE
subformat: STD
channels: 2
rate: 44100 (44100/1)
period_size: 442
buffer_size: 1768

here when 192/24 bit flac is played:
cat /proc/asound/card0/pcm0p/sub0/hw_params
access: RW_INTERLEAVED
format: S32_LE
subformat: STD
channels: 2
rate: 192000 (192000/1)
period_size: 1920
buffer_size: 7680

PS: I'm using microcore linux
piCorePlayer webpage: https://sites.google.com/site/picoreplayer/home

Return to “Advanced users”