respeaker/seeed-voicecard

Ubuntu 64-bit driver on 6-mics missed 3rd channel

HinTak opened this issue · 7 comments

I managed to test my v5.5 fork on ubuntu 20.04.1 64-bit.

20.04 was no good for me, due to a lot of networking bugs and won't do headless - I spent most of a day just fighting the headless network configuration, then I see that 20.04.1 has been out since the time I downloaded 20.04 , and 20.04.1 came with substantial changes and bug fixes over 20.04 in the network configuration area (LTS is a joke...) .

The driver works more or less working correctly, on the 6-mics against kernel 5.4.x which ubuntu shipped - the individual channels of the 8-channels recording plays back correctly to my ears, except channel 3 comes out empty.

I went back to raspbian just to be sure it is not a broken microphone.

My first suspicion is that one of the long 's in the code should be uint32_t etc. Driver/hardware data are usually fixed size, so using variables which have different sizes on different platforms are definitely wrong.

Alternatively it could be the 419 to 5.4 changes. I suppose I could find out one way or the other if I switch to ubuntu 32-bit. But I don't feel like doing it - spending more money on another SD card. (Having two, one for main use, and another for throw-away tries, is alright - but really this needs a 3-way comparison...). However, if seeedstudio want to sponsor me to do the work, or others, please feel free to get in touch or just click the link https://sourceforge.net/p/hp-pxl-jetready/donate/ (it is unrelated software but go to my paypal acct).

And also sorry, I only have the 6-mic array...

There are a bunch of ubuntu-specific (vs raspbian) userland / tools changes outside the kernel, needed to get it to work, but that's another story.

Hmm, almost all the usage of long in the code seems wrong! Irq values, channels, various alsa parameters, are 32-bit.

Edit: okay, all the long's are returned from the kernel and needs to be as the bitness of the kernel. Still suspect a conversion / cast / wrapped (signed int) to (unsigned long) mistake somewhere.

cc @rotdrop (where the -c 1 came from). The amixer command when applied to newer kernel, does not enable headphone jack, but turning channel 3's recording volume really low ( 1 in the range of 0 to 255).

changlog for this fix:

remove "-c 1" and also protect with test for older kernel / alsa

The "-c 1" was simply wrong. The default (-c 0) sound device of
older kernel / alsa has a numid=3 selector for auto vs headphone vs hdmi .
Newer kernel simply has multiple devices. Also, headphone is -c 0 .

$ amixer contents
numid=2,iface=MIXER,name='Headphone Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=1,iface=MIXER,name='Headphone Playback Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=-10239,max=400,step=0
  : values=-2000
  | dBscale-min=-102.39dB,step=0.01dB,mute=1

TODO: For now, broadly dividing by kernel v4.x vs v5.x is good enough, but
it would be nice to find out when / which kernel /alsa this is relevant.

it works perfectly for me on the 6-mic device with ubuntu 64-bit now. I'll add the ubuntu userland stuff in my branch soon.

TODO: For now, broadly dividing by kernel v4.x vs v5.x is good enough, but
it would be nice to find out when / which kernel /alsa this is relevant.

I found a common solution, match by the widget name 'PCM Playback Route',
in kernel >= 5.4, amixer will just fail, not change rest settings.

pi@raspberrypi:~ $ uname -r
4.19.75-v7l+
pi@raspberrypi:~ $ amixer contents
numid=3,iface=MIXER,name='PCM Playback Route'
  ; type=INTEGER,access=rw------,values=1,min=0,max=3,step=0
  : values=1
numid=2,iface=MIXER,name='PCM Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=1,iface=MIXER,name='PCM Playback Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=-10239,max=400,step=0
  : values=-2206
  | dBscale-min=-102.39dB,step=0.01dB,mute=1
numid=5,iface=PCM,name='IEC958 Playback Con Mask'
  ; type=IEC958,access=r-------,values=1
  : values=[AES0=0x02 AES1=0x00 AES2=0x00 AES3=0x00]
numid=4,iface=PCM,name='IEC958 Playback Default'
  ; type=IEC958,access=rw------,values=1
  : values=[AES0=0x00 AES1=0x00 AES2=0x00 AES3=0x00]

You did not see my latest code - it was fixed to the proper condition later.

These 4 lines of explanation and the conditional after it, is the correct fix:
https://github.com/HinTak/seeed-voicecard/blob/e0f9a554fc23045704f69b65b475ebc4786cd69f/seeed-voicecard#L153

OK, I just saw it.