Skip to content

bcm2835-i2s: Changes for allowing asymmetric sample formats. (#1783) #1803

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

Closed
wants to merge 1 commit into from
Closed

bcm2835-i2s: Changes for allowing asymmetric sample formats. (#1783) #1803

wants to merge 1 commit into from

Conversation

gtrainavicius
Copy link
Contributor

Hey, this is the update code for asymmetric sample formats, addressing the issue found by @HiassofT #1799

The new changes are mainly introducing previous_txon_rxon to remember which streams were enabled previously, then both TXON and RXON get temporarily disabled (according to peripherals documentation, most of register bits can't be changed while either one of them is enabled), clearing only the FIFO of requested direction.

I noticed that starting the stream in the other direction while there was an already active stream produces a short glitch in the other stream, but the same thing happens in unmodified code, I've tried disabling all register accesses, even not starting one of the streams if requested, and the glitch was still happening, so it must be someplace else than this driver...

This is achieved by making changes only to the requested
stream direction format, keeping the other stream direction
configuration intact.

Signed-off-by: Giedrius Trainavicius <[email protected]>
@HiassofT
Copy link
Contributor

HiassofT commented Jan 18, 2017 via email

@gtrainavicius
Copy link
Contributor Author

gtrainavicius commented Jan 18, 2017

The alternative would be to return errors and not changing the stream configurations at all, which would prevent user completely from doing what he intended... https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835/BCM2835-ARM-Peripherals.pdf says about most of registers "This register cannot be changed whilst the PCM is running." and the condition of running seems to be "EN && (TXON || RXON)", so in order to change the stream configuration, it seems TXON and RXON must briefly be disabled and restored.

Maybe you have access to Broadcom support and can ask them what is the suggested way to reconfigure the streams during playback? This isn't discussed anywhere in the documentation.

About the glitches - I've tried preventing all register access when configuring the new stream by inserting early returns for that stream, so even without the code touching any of the registers, the glitch still occurs, so I think this indicates it's at some other level of ALSA. To reproduce - play some relatively long audio file using aplay, and start recording with same format to another file using arecord. Everytime you restart arecord, you can hear the glitch occur, it's a short click / pop.

@HiassofT
Copy link
Contributor

HiassofT commented Jan 18, 2017 via email

@gtrainavicius
Copy link
Contributor Author

In my testing, switching TXON and RXON to off during reconfiguration seemed to work fine. As I said in the previous pull request, I tried symmetric_samplebits set as 1, but Audacity fails to work this way, it still tries to request 16 bits for recording and 32 bits for output.

Does the glitch always occur for the same amount of samples? Does my patch increase the sample affected count?

@HiassofT
Copy link
Contributor

The length of the glitch varies, from about 64 to 82 stereo-samples (on a RPi3 with kernel 4.9.4). I did some testing but so far nothing stuck out. ATM I'm not even sure if the BCM I2S dai or one of the codecs (wm5102/wm8804) is responsible for that.

I tried overdub in audacity and it worked just fine. The wm5102 codec has symmetric_samplebits set and using aplay/arecord I can verify that the symmetric feature works.

First play a file and let aplay output the allowed hw params. Note the all 3 sample formats and both 16 and 32 bit are allowed:

pi@rpi3:~ $ aplay --dump-hw-params -Dhw:0 audiotest/440hz-44100-stereo.wav
Playing WAVE 'audiotest/440hz-44100-stereo.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
HW Params of device "hw:0":
--------------------
ACCESS:  MMAP_INTERLEAVED RW_INTERLEAVED
FORMAT:  S16_LE S24_LE S32_LE
SUBFORMAT:  STD
SAMPLE_BITS: [16 32]
FRAME_BITS: [32 64]
CHANNELS: 2
RATE: [32000 192000]
PERIOD_TIME: (166 2048000]
PERIOD_SIZE: [32 65536]
PERIOD_BYTES: [256 524288]
PERIODS: [2 4096]
BUFFER_TIME: (333 4096000]
BUFFER_SIZE: [64 131072]
BUFFER_BYTES: [256 524288]
TICK_TIME: ALL

Then, why aplay is running run arecord, again dumping the allowed hw params. Only S16_LE format is allowed now:

pi@rpi3:~ $ arecord -f cd --dump-hw-params -Dhw:0 /tmp/rec.wav
ACCESS:  MMAP_INTERLEAVED RW_INTERLEAVED
FORMAT:  S16_LE
SUBFORMAT:  STD
SAMPLE_BITS: 16
FRAME_BITS: 32
CHANNELS: 2
RATE: 44100
PERIOD_TIME: (1451 1486078)
PERIOD_SIZE: [64 65536]
PERIOD_BYTES: [256 262144]
PERIODS: [2 2048]
BUFFER_TIME: (2902 2972155)
BUFFER_SIZE: [128 131072]
BUFFER_BYTES: [512 524288]
TICK_TIME: ALL

Trying to record with S32_LE also gives an error.

I haven't tried your patch yet. IMO you are barking up the wrong tree. We can't safely support asymmetric sample modes, changing the setup while a stream is running is not possible. And I don't consider stopping the other stream an acceptable solution.

@gtrainavicius
Copy link
Contributor Author

What settings did Audacity have in your tests, and which modes were requested in hw_params?

In my case, I tried setting recording quality to 16 bits, so it was requesting recording using 16 bits, but for playback, it was still requesting 32 bits. With symmetric sample bits enabled, it was failing.

I think Audacity chooses the hw_params first without starting playback or recording. At that point all formats are available. Once it starts one of the streams, the other one can no longer start, and Audacity fails.

Running arecord and aplay is different from what Audacity is doing, because they start at different times, based on the latest available constraints.

@HiassofT
Copy link
Contributor

With sample format set to the default (32 bit float) everything's fine. Also with 24 bit. But when setting the sample format to 16 bit I can reproduce your issue:

New project, record something, stop, record again (overdub) and I get an error message "please check soundcard settings" and messages on the console:

Expression 'r' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2097
Expression 'PaAlsaStreamComponent_FinishConfigure( &self->playback, hwParamsPlayback, outParams, self->primeBuffers, realSr, outputLatency )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2738
Expression 'PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer, &inputLatency, &outputLatency, &hostBufferSizeMode )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2843

If I then try record (overdub) a second time it works fine.

I've tried changing the playback/recording settings (default, sysdefault - which should use plughw and RPi-Cirrus:hw) but that didn't make a difference.

I suspect that could be a bug in Audacity (I'm using the raspbian version 2.0.6 which is already quite old - latest version is 2.1.2 from january last year).

@gtrainavicius
Copy link
Contributor Author

I don't think symmetric_samplebits is the right way to go, because the processor itself supports asymmetric rates.

Could you give the patched code a go and check what's the impact on the samples during reconfiguration of stream and the glitch itself?

@HiassofT
Copy link
Contributor

HiassofT commented Jan 24, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants