Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ALSA bcm2835 8kHZ sample rate doesn't work #2176

Closed
flatmax opened this issue Aug 25, 2017 · 10 comments
Closed

ALSA bcm2835 8kHZ sample rate doesn't work #2176

flatmax opened this issue Aug 25, 2017 · 10 comments

Comments

@flatmax
Copy link
Contributor

@flatmax flatmax commented Aug 25, 2017

Hi there,

For some reason in these latest round of kernels, 8 kHz abd 16 kHz doesn't work when recording (and possibly playback).

If however if I roll back to 4.9.14 I can record again at 8 kHz ... for example :
sudo rpi-update b30461d2621e71eb9b8845b38738af177b9181ed
When I try to record at either 8 kHZ or 16 kHZ,

pi@raspberrypi:~ $ arecord  -c2 -r8000 -fS32_LE /tmp/test.wav
Recording WAVE '/tmp/test.wav' : Signed 32 bit Little Endian, Rate 8000 Hz, Stereo
arecord: set_params:1297: Unable to install hw params:

The card I am testing with is specifically enabled for 8 kHz and 16 kHZ and is clock master :

static const unsigned int bcm2835_rates_12000000[] = {
	8000, 16000, 32000, 44100, 48000, 96000, 88200,
};

static struct snd_pcm_hw_constraint_list bcm2835_constraints_12000000 = {
	.list = bcm2835_rates_12000000,
	.count = ARRAY_SIZE(bcm2835_rates_12000000),
};

The bcm i2s driver has continuous rates set :
.rates = SNDRV_PCM_RATE_CONTINUOUS,

Not sure why the system is blocking ?

Matt

@flatmax

This comment has been minimized.

Copy link
Contributor Author

@flatmax flatmax commented Aug 25, 2017

@HiassofT @pelwell any ideas ?

@pelwell

This comment has been minimized.

Copy link
Contributor

@pelwell pelwell commented Aug 25, 2017

Is Hexxeh/rpi-firmware@b30461d the newest working kernel? It would help to find the first failing kernel.

@pelwell

This comment has been minimized.

Copy link
Contributor

@pelwell pelwell commented Aug 25, 2017

There were three changes to the I2S driver on July 28th, which first appeared in firmware release Hexxeh/rpi-firmware@3202f1b - you should probably try that one first.

@HiassofT

This comment has been minimized.

Copy link
Contributor

@HiassofT HiassofT commented Aug 25, 2017

8kHz playback and record is working fine here with the rpi-cirrus card (which is also a clock master) on current rpi-update firmware 62a68c3f63d5359e9155c2eefed512cf6753d6ae

@HiassofT

This comment has been minimized.

Copy link
Contributor

@HiassofT HiassofT commented Aug 25, 2017

@flatmax what soundcard and/or bclk ratio are you using?

Looking at the audioinjector-pi driver you are using an illegal bclk ratio for 8kHz:
https://github.com/raspberrypi/linux/blob/rpi-4.9.y/sound/soc/bcm/audioinjector-pi-soundcard.c#L57-L58

    case 8000:
        return snd_soc_dai_set_bclk_ratio(cpu_dai, 1);

This will be rejected by bcm2835-i2s because it's smaller than the width (eg 32*2=64 for S32_LE)
https://github.com/raspberrypi/linux/blob/rpi-4.9.y/sound/soc/bcm/bcm2835-i2s.c#L389-L391

/* Check if data fits into slots */
if (data_length > slot_width)
    return -EINVAL;
@flatmax

This comment has been minimized.

Copy link
Contributor Author

@flatmax flatmax commented Aug 25, 2017

OK - strange thing is there is nothing blocking those sample rates in my machine driver - they should just work. I am also on the 4.9.44 version.

Can you please send in your HW/SW parameteres for a working 8 kHZ record ?
I get the following :
pi@raspberrypi:~ $ arecord -c2 -r8000 -fS32_LE /tmp/test.wav
Recording WAVE '/tmp/test.wav' : Signed 32 bit Little Endian, Rate 8000 Hz, Stereo
arecord: set_params:1297: Unable to install hw params:
ACCESS: RW_INTERLEAVED
FORMAT: S32_LE
SUBFORMAT: STD
SAMPLE_BITS: 32
FRAME_BITS: 64
CHANNELS: 2
RATE: 8000
PERIOD_TIME: 125000
PERIOD_SIZE: 1000
PERIOD_BYTES: 8000
PERIODS: 4
BUFFER_TIME: 500000
BUFFER_SIZE: 4000
BUFFER_BYTES: 32000
TICK_TIME: 0

@HiassofT

This comment has been minimized.

Copy link
Contributor

@HiassofT HiassofT commented Aug 26, 2017

recording at 8kHz:

pi@rpi3:~ $ arecord -v -r 8000 -c 2 -f S32_LE /tmp/rec.wav
Recording WAVE '/tmp/rec.wav' : Signed 32 bit Little Endian, Rate 8000 Hz, Stereo
Plug PCM: Hardware PCM card 0 'RPi-Cirrus' device 0 subdevice 0
Its setup is:
  stream       : CAPTURE
  access       : RW_INTERLEAVED
  format       : S32_LE
  subformat    : STD
  channels     : 2
  rate         : 8000
  exact rate   : 8000 (8000/1)
  msbits       : 32
  buffer_size  : 4000
  period_size  : 1000
  period_time  : 125000
  tstamp_mode  : NONE
  period_step  : 1
  avail_min    : 1000
  period_event : 0
  start_threshold  : 1
  stop_threshold   : 4000
  silence_threshold: 0
  silence_size : 0
  boundary     : 2097152000
  appl_ptr     : 0
  hw_ptr       : 0

I just did a quick test, used invalid bclk ratio of 1 for 8kHz and then I get the same error as you. plus a line in dmesg telling that hw_params in bcm2835-i2s failed:

[  699.857847] bcm2835-i2s 3f203000.i2s: ASoC: can't set 3f203000.i2s hw params: -22

In AScC all involved parties (card driver, cpu dai, codec) have to "agree" to a config, if one of these fails, you'll get an error.

@flatmax

This comment has been minimized.

Copy link
Contributor Author

@flatmax flatmax commented Aug 26, 2017

Oh @HiassofT I just saw the comment about (data_length > slot_width) ... hmmm ...
I am confused about the purpose of that line.

Previously bclk_ratio set the first bit of the second word in the incoming bit stream. The start of this bit stream was set by the LR_CLK initial indicator (rise in the clock line). Previously by setting bclk_ratio = 1 I could get both L and R words to overlap.

Is there a way to do this with the new i2s driver ?

The reason why the need to overlap is that there is 1500 bits before the start of the second word for the wm8731 chip with a 12 MHz master clock. This number is too large for the bcm2835 register to handle ... consequently the only way to get 8 kHz sample rates working is to have a left stream on both channel 1 and 2.

@HiassofT

This comment has been minimized.

Copy link
Contributor

@HiassofT HiassofT commented Aug 27, 2017

Configurations that would lead to overlapping channels aren't allowed in general. This should already be obvious by applying common sense and the bcm2835 datasheet even mentions that explicitly:

Each channel can be between 8 and 32 bits wide and can be positioned anywhere within the frame as long as the two channels don’t overlap.

I've added the sanity check for 2 reasons: to easily detect invalid configurations (typically driver bugs) and to protect the following code that calculates channel positions (in right justified mode it'd underflow if the slot width is smaller than data length). Looks like this worked :)

The solution is simple: as the required bclk ratio of 1500 can't be supported on bcm2835-i2s (maximum frame length is 1024) just remove 8000 from the list of supported sample rates. Alsa (more specifically the default plughw plugin) can then configure the hw device to 16000Hz and apply software resampling if a program/user requests 8000Hz.

@flatmax

This comment has been minimized.

Copy link
Contributor Author

@flatmax flatmax commented Oct 14, 2017

I now have a kernel hack for getting 8 kHZ monot sound to work again on the Audio Injector support forum :
http://forum.audioinjector.net/viewtopic.php?f=5&t=3108

Closing this issue.
Matt

@flatmax flatmax closed this Oct 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.