• WANTED: Happy members who like to discuss audio and other topics related to our interest. Desire to learn and share knowledge of science required. There are many reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

Pi4 + CamillaDSP + Audio Interface (Motu M4) = Phenomal DSP streamer

HenrikEnquist

Member
Joined
Jul 1, 2021
Messages
82
Likes
110
With CamillaDSP / ALSA I do not understand how I can have an input file at 44.1 kHz, set a 96 kHz processing rate in the CamillaDSP and have no resampling. Seems to me that that there must be a sample rate conversion somewhere but all the documentation states you can use enable_rate_adjust without enable_resampling (and this works in my experience!) but I have not idea how this is possible. Just want to understand what I am missing here.
That setup definitely has resampling. What happens here is that CamillaDSP opens the loopback at 96 kHz. This locks both ends of the loopback to that rate. The resampling 44.1 -> 96 kHz can happen either in the music player app itself, or Alsa can be configured to do it. If the app is outputting to the loopback directly, then Alsa won't resample. That means the app has do do the resampling itself. But if the Alsa config contains a "plug", then this can do the sample rate conversion.
Rate adjust is used to sync the rates of independent sample clocks. If an Alsa loopback is used, then it will adjust the speed of the loopback by tuning the loopback software clock. If not, it needs an asynchronous resampler, and will tune the resampling ratio of that to match.
 

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,511
Likes
3,356
Location
Detroit, MI
That setup definitely has resampling. What happens here is that CamillaDSP opens the loopback at 96 kHz. This locks both ends of the loopback to that rate. The resampling 44.1 -> 96 kHz can happen either in the music player app itself, or Alsa can be configured to do it. If the app is outputting to the loopback directly, then Alsa won't resample. That means the app has do do the resampling itself. But if the Alsa config contains a "plug", then this can do the sample rate conversion.
Rate adjust is used to sync the rates of independent sample clocks. If an Alsa loopback is used, then it will adjust the speed of the loopback by tuning the loopback software clock. If not, it needs an asynchronous resampler, and will tune the resampling ratio of that to match.

Thank you so much for responding, I was going to post the same question over at DIYaudio but your answer eliminates the need.

It makes sense that ALSA would resample to the CamillaDSP specified rate, I was poking around in /proc/asound and it definitely looked like the input stream was 44.1 kHz and the output to the DAC was 96 kHz so I figured there was resampling just didn't know if that was occurring in or outside of Camilla. Also good to know that I could do the resampling in squeezelite as an alternative.

Thank you for the awesome software and excellent support!

Michael
 

phofman

Addicted to Fun and Learning
Joined
Apr 13, 2021
Messages
501
Likes
323
I was poking around in /proc/asound and it definitely looked like the input stream was 44.1 kHz and the output to the DAC was 96 kHz

If your hw_params files for capture and playback listed 44100 and 96000, then it did not comply with your config in
https://www.audiosciencereview.com/...u-m4-phenomal-dsp-streamer.24493/#post-832728

In such case something between capture and playback devices had to resample. And if you used hw:XX as in your config, it had to be CamillaDSP. I think a few different configurations are being mixed here...
 

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,511
Likes
3,356
Location
Detroit, MI
If your hw_params files for capture and playback listed 44100 and 96000, then it did not comply with your config in
https://www.audiosciencereview.com/...u-m4-phenomal-dsp-streamer.24493/#post-832728

In such case something between capture and playback devices had to resample. And if you used hw:XX as in your config, it had to be CamillaDSP. I think a few different configurations are being mixed here...

OK, interesting. Some more info that may be helpful, when I was setting up CamillaDSP I installed REW so that I could measure the filters that were being generated and make sure they matched what I expected. I also used REW to determine which Loopback I should use in my CamillaDSP config as there were two. All of the Loopbacks shown in REW had plughw in front of them (see screenshot) below.
Screen Shot 2021-07-02 at 8.24.21 AM.jpeg

I then set plughw:Loopback,0,1 as my default soundcard in asound.conf. This shows my ignorance but I am guessing by doing that I have resampling in ALSA.

Michael
 

phofman

Addicted to Fun and Learning
Joined
Apr 13, 2021
Messages
501
Likes
323
Ad REW devices: Java wraps all alsa devices with the plug plugin (hw:X -> plughw:X) https://github.com/openjdk/jdk11u/b.../PLATFORM_API_LinuxOS_ALSA_CommonUtils.c#L113 https://github.com/openjdk/jdk11u/b...ound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h#L36

Your redefined "default" device applies only to the default device, not to specific devices configured in your camilladsp config. If you used hw:Loopback and hw: D20, alsa did no resampling (hw means direct access to the driver, no modifier used). And if the hw_params file for the two cards showed different samplerates, something in between had to do the conversion.
 

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,511
Likes
3,356
Location
Detroit, MI
Ad REW devices: Java wraps all alsa devices with the plug plugin (hw:X -> plughw:X) https://github.com/openjdk/jdk11u/b.../PLATFORM_API_LinuxOS_ALSA_CommonUtils.c#L113 https://github.com/openjdk/jdk11u/b...ound/PLATFORM_API_LinuxOS_ALSA_PCMUtils.h#L36

Your redefined "default" device applies only to the default device, not to specific devices configured in your camilladsp config. If you used hw:Loopback and hw: D20, alsa did no resampling (hw means direct access to the driver, no modifier used). And if the hw_params file for the two cards showed different samplerates, something in between had to do the conversion.

That makes sense with regards to REW, thanks for the info. Maybe I need to take a step back and ask a much more basic question as I obviously do not understand the ins and outs of this stuff. How would you setup your asound.conf and CamillaDSP configuration files such that all resampling was done in CamillaDSP (and nothing was resampled prior to CamillaDSP)?

Michael
 

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,511
Likes
3,356
Location
Detroit, MI
OK to confuse matters even more I did a bit more tinkering and now am getting different hw_params information although I think it now makes more sense. I switched from Ubuntu Server to RPi OS as I was having squeezelite issues and I have existing Pi's running squeezelite on RPi OS without issue. I also removed the asound.conf default stuff.

Probably best to first describe what I think I understand first.

By running "mod probe snd-aloop" this creates an ALSA loopback. What this looks like from an ALSA perspective is CARD "0" named "Loopback" and 2 DEVICES "0" and "1".

In my /etc/default/squeezelite configuration I have set SL_SOUNDCARD="hw:0,1" which tells squeezelite to output to my Loopback CARD 0, DEVICE 1. Because I did not use plughw ALSA will not resample here but squeezelite can still resample.

In my CamillaDSP .yml file I have the capture device set as "hw:Loopback,0,0" which means my Loopback CARD 0, DEVICE 0 is recording what is coming from squeezelite. I have "enable_rate_adjust: true" in my .yml file but no resampling.

Running cat /proc/asound/Loopback/pcm0c/sub0/hw_params shows that my CamillaDSP capture device is recording at the specified 96 kHz.

access: RW_INTERLEAVED
format: S32_LE
subformat: STD
channels: 2
rate: 96000 (96000/1)
period_size: 1024
buffer_size: 8192

Running cat /proc/asound/Loopback/pcm1p/sub0/hw_params shows that squeezelite is outputting at 96 kHz regardless of the file I am playing in squeezelite. To me this means that squeezelite is resampling everything to 96 kHz to match the loopback.

access: MMAP_INTERLEAVED
format: S32_LE
subformat: STD
channels: 2
rate: 96000 (96000/1)
period_size: 960
buffer_size: 3840

If I change the sample rate in the .yml file then both the both the rates in hw_params change to match the rate in the .yml file.

I guess I can play some test tones over LMS and look the FFTs to see if squeezelite sampling (hw:0,1) or ALSA sampling (plughw:0,1) are preferred (or if any differences are even noticeable).

To the more experienced folks, does the above make sense?

Michael
 

phofman

Addicted to Fun and Learning
Joined
Apr 13, 2021
Messages
501
Likes
323
Just a few things which may give you the answer, depending on situation.

1) The hw:Loopback device can be opened on first side at any samplerate. Once it is opened on one side (e.g. player playing, or camilladsp capturing), the other side can only be opened/used at the same samplerate.

2) Alsa resampling with the rate plugin (used by the plug plugin) is quite inefficient and low quality. Only recently have the developers pushed patches for 24bit https://mailman.alsa-project.org/pipermail/alsa-devel/2021-June/186333.html , the existing stable versions always downconvert to 16 bits before the conversion. High quality resampling (configured in .asoundrc https://wiki.archlinux.org/title/Advanced_Linux_Sound_Architecture#High_quality_resampling https://wiki.archlinux.org/title/Talk:Advanced_Linux_Sound_Architecture#On_high_quality_resampling ) is very CPU consuming, way more than resamplers in camilladsp.

3) Some applications have built-in resamplers and if the alsa device returns a different samplerate available than required, they resample themselves first. E.g. mplayer does that, I do not know about LMS/squeezelite.

I would definitely try to configure the chain to leave the resampling task to camilladsp which is highly optimized and top quality.
The loopback device (timed by software-adjustable clock) allows enable_rate_adust, therefore the simpler synchronous resampler can be used.
 

HenrikEnquist

Member
Joined
Jul 1, 2021
Messages
82
Likes
110

Daverz

Major Contributor
Joined
Mar 17, 2019
Messages
1,309
Likes
1,475
On the config page at https://github.com/HEnquist/camilladsp-config they have an /etc/asound.conf ALSA setup that looks like this

Code:
pcm.!default {
   type plug
   slave.pcm "camilladsp"
}
 
pcm.camilladsp {

    # Use the ALSA plug-in "plug" for rate-/format-conversion.
    type plug

This seems to be exactly what I don't want. How can I keep ALSA from resampling?
 

HenrikEnquist

Member
Joined
Jul 1, 2021
Messages
82
Likes
110
This seems to be exactly what I don't want. How can I keep ALSA from resampling?
Just don't use that asound.conf file! ALSA won't do any resampling if you don't ask for it by defining a plug device.
 
Last edited:

Daverz

Major Contributor
Joined
Mar 17, 2019
Messages
1,309
Likes
1,475
Just don't use that asound.conf file! ALSA won't do any resampling if you don't ask for it by defining a plug device.

EDIT: Sorry about all this verbiage. TL;DR: squeezelite reopens the alsa device in the plug mode if the audio file's rate is lower than the samplerate. If the audio file's rate is higher, LMS downsamples with sox.

EDIT: In summary, either use the squeezelite -R flag or the previously mentioned alsa_cdsp if you want to have camillaDSP do the resampling. Otherwise squeezelite will use alsa's resampling.

https://github.com/scripple/alsa_cdsp

Info on squeezelite resampling:

https://soundcheck-audio.blogspot.com/2011/04/resampling-if-you-cant-avoid-it.html

I use Archimago's settings

Setting.png


http://archimago.blogspot.com/2017/12/howto-musings-playing-with-digital_23.html

...

Thanks. I removed /etc/asound.conf and rebooted. I hope this isn't getting too tiresome, but I'm still confused about where resampling is taking place. There are 4 places it could take place:

* My squeezebox server (LMS). This uses a sox process for resampling, if needed. My LMS config just passes flac files thru, and no sox process is running during playback (of, say, RBCD files).

* Squeezelite. My reading of the man page is that you have to use the -u or -R flag for resampling to take place, but maybe it does it anyway?

My squeezelite command is:

Bash:
/usr/bin/squeezelite -n pi4 -o hw:Loopback,0 -a 120 4 32 1

* Alsa. Should not be resampling in my case.

* CamillaDSP

So I tried turning off any resampling in camillaDSP

YAML:
devices:
  samplerate: 96000
  buffersize: 8192
  enable_rate_adjust: false
  enable_resampling: false
  capture:
    type: Alsa
    channels: 2
    device: "hw:Loopback,1"
    format: S32LE
  playback:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4"
    format: S32LE

I notice in the status output it says

Code:
● camilladsp.service - CamillaDSP Daemon
     Loaded: loaded (/etc/systemd/system/camilladsp.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2021-07-02 22:07:01 UTC; 9min ago
   Main PID: 2692 (camilladsp)
      Tasks: 6 (limit: 969)
     Memory: 1.2M
     CGroup: /system.slice/camilladsp.service
             └─2692 /usr/local/bin/camilladsp /home/ubuntu/my-camilladsp-config/alsaconfig.yml -p 1>

Jul 02 22:07:01 ubuntu systemd[1]: Started CamillaDSP Daemon.
Jul 02 22:07:01 ubuntu camilladsp[2692]: 22:07:01.551 [INFO] Capture device supports rate adjust
Jul 02 22:07:01 ubuntu camilladsp[2692]: 22:07:01.648 [INFO] Starting playback from Prepared state

I'm not sure what "Capture device supports rate adjust" refers to here.

My /proc/asound looks like

Bash:
$ cat /proc/asound/Loopback/pcm1c/sub0/hw_params
access: RW_INTERLEAVED
format: S32_LE
subformat: STD
channels: 2
rate: 96000 (96000/1)
period_size: 4096
buffer_size: 32768

and

Bash:
$ cat /proc/asound/Loopback/pcm0p/sub0/hw_params
access: MMAP_INTERLEAVED
format: S32_LE
subformat: STD
channels: 2
rate: 96000 (96000/1)
period_size: 2880
buffer_size: 11520

EDIT: I tried using aplay to see what it would do with the wrong sample rate:

Bash:
aplay -D hw:CARD=Loopback,DEV=0 01_orpheus_haydn.wav
Playing WAVE '01_orpheus_haydn.wav' : Signed 32 bit Little Endian, Rate 44100 Hz, Stereo
Warning: rate is not accurate (requested = 44100Hz, got = 96000Hz)
         please, try the plug plugin

So alsa isn't doing it.

EDIT: Well, alsa is doing the resampling, but only because squeezelite reopens the resampling alsa device when there's a samplerate mismatch. From the squeezelite debug output:

Code:
[00:05:28.205807] _output_frames:152 track start sample rate: 44100 replay_gain: 0
[00:05:28.215785] sendSTAT:195 STAT: STMs
[00:05:28.216042] sendSTAT:195 STAT: STMt
[00:05:28.216166] output_thread:687 open output device: hw:Loopback,0
[00:05:28.216394] alsa_open:351 opening device at: 44100
[00:05:28.217116] alsa_open:381 reopening device hw:Loopback,0 in plug mode as plughw:Loopback,0 for resampling
[00:05:28.217951] alsa_open:422 opened device plughw:Loopback,0 using format: S32_LE sample rate: 44100 mmap: 1

So it first tries opening the hw device at 44100 then reopens it in plug mode.

So it seems better in this case to turn squeezelite upsampling back on with the -R option since this uses the sox resampling library.

By the way, in the case of audio with a higher sampling rate than the max reported to LMS by squeezelite, LMS automatically downsamples using sox based on what squeezelite reports to it:

Bash:
sh -c "/usr/share/squeezeboxserver/Bin/x86_64-linux/flac" -dcs --force-raw-format --sign=signed --endian=little -- - | "/usr/share/squeezeboxserver/Bin/x86_64-linux/sox" -q -t raw --encoding signed-integer -b 24 -r 192000 -c 2 -L - -t flac -r 96000 -C 0  -

But LMS is not upsampling RBCD files (no sox running in that case).
 
Last edited:

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,511
Likes
3,356
Location
Detroit, MI
Really good info @Daverz, I did some brief experimentation and it seems to match with what my measurements are showing.

I generated 44.1 kHz and 96 kHz sample rate 24 bit 1 kHz wav test tones in Audacity and loaded them on to LMS. I am using a DIYINHK ES9016 DAC for playback and the MOTU M4 for measurements. My CamillaDSP configuration is running at 96 kHz and has no filtering.

The results were identical whether I used hw:0,1 or plughw:0,1 in my squeezelite configuration.

96 kHz looked fine.

96 - hw.png


44.1 kHz looked terrible which seems to match what @phofman said about ALSA resampling.

44 - hw.png


Implementing resampling in squeezelite resulted in a vast improvement over ALSA resampling, 44.1 kHz file with squeezelite resampling below.

44 - squeezelite.png


Still need to play around a bit with all the possible resampling settings in squeezelite but squeezelite resampling seems like a good solution for my use case with LMS.

Michael
 

Daverz

Major Contributor
Joined
Mar 17, 2019
Messages
1,309
Likes
1,475
Finally have my turntable integrated into the system. Sorry about the crappy phone pic.

turntable + motu M4.jpeg


DRC filters are computed with DRC-FIR from REW measured impulse response. So this is a DIY miniDSP SHD, assembled for about $450. In the pic from top left ot bottom right:

Michell Gyro SE turntable
SME 309 arm
Benz Ace high output moving coil cartridge
Rogue Audio Stealth phono preamp
Raspberry Pi 4b 8Gb board in FLIRC case ($104) + FLIRC USB IR receiver ($20)
SunFounder 7 Inch Monitor HDMI - 1024×600 HD LCD Display Screen ($76)
Motu M4 ($250)

I'm using an old Logitech Harmony 350 universal remote control, but just about any remote control should work.

EDIT: forgot to include my Camilla DSP config file for the analog line inputs of the Motu M4. Here's one for simple stereo in => stereo out with volume control:

YAML:
devices:
  samplerate: 96000
  buffersize: 8192
  enable_rate_adjust: true
  capture:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE
  playback:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE

filters:
  volume:
    type: Volume
    parameters:
      ramp_time: 200
 
mixers:
  line_in_to_stereo_out:
    channels:
      in: 4
      out: 4
    mapping:
      - dest: 0
        sources:
          - channel: 2
            gain: 0
            inverted: false
      - dest: 1
        sources:
          - channel: 3
            gain: 0
            inverted: false

pipeline:
  - type: Filter
    channel: 2
    names:
      - volume
  - type: Filter
    channel: 3
    names:
      - volume
  - type: Mixer
    name: line_in_to_stereo_out

And then a 2.1 output with FIR filters generated by DRC-FIR:

YAML:
devices:
  samplerate: 96000
  buffersize: 8192
  enable_rate_adjust: true
  capture:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE
  playback:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE

filters:
  volume:
    type: Volume
    parameters:
      ramp_time: 200
  drc_l:
    type: Conv
    parameters:
      type: Wav
      filename: filters/s400+sb1kp-pos2-normal-96000.wav
      channel: 0
  drc_r:
    type: Conv
    parameters:
      type: Wav
      filename: filters/s400+sb1kp-pos2-normal-96000.wav
      channel: 1
  mainshighpass:
    type: BiquadCombo
    parameters:
      type: LinkwitzRileyHighpass
      freq: 80
      order: 8
  sublowpass:
    type: BiquadCombo
    parameters:
      type: LinkwitzRileyLowpass
      freq: 80
      order: 8
  mainsdelay:
    type: Delay
    parameters:
      delay: 9.2
      unit: ms
      subsample: false
 
mixers:
  to3:
    channels:
      in: 4
      out: 4
    mapping:
      - dest: 0
        sources:
          - channel: 2
            gain: 0
            inverted: false
      - dest: 1
        sources:
          - channel: 3
            gain: 0
            inverted: false
      - dest: 2
        sources:
          - channel: 2
            gain: 0
            inverted: false
          - channel: 3
            gain: 0
            inverted: false

pipeline:
  - type: Filter
    channel: 2
    names:
      - volume
      - drc_l
  - type: Filter
    channel: 3
    names:
      - volume
      - drc_r
  - type: Mixer
    name: to3
  - type: Filter
    channel: 0
    names:
      - mainshighpass
      - mainsdelay
  - type: Filter
    channel: 1
    names:
      - mainshighpass
      - mainsdelay
  - type: Filter
    channel: 2
    names:
      - sublowpass
 
Last edited:

mike70

Addicted to Fun and Learning
Joined
May 9, 2021
Messages
912
Likes
623
Finally have my turntable integrated into the system. Sorry about the crappy phone pic.

View attachment 142104

DRC filters are computed with DRC-FIR from REW measured impulse response. So this is a DIY miniDSP SHD, assembled for about $450. In the pic from top left ot bottom right:

Michell Gyro SE turntable
SME 309 arm
Benz Ace high output moving coil cartridge
Rogue Audio Stealth phono preamp
Raspberry Pi 4b 8Gb board in FLIRC case ($104) + FLIRC USB IR receiver ($20)
SunFounder 7 Inch Monitor HDMI - 1024×600 HD LCD Display Screen ($76)
Motu M4 ($250)

I'm using an old Logitech Harmony 350 universal remote control, but just about any remote control should work.

EDIT: forgot to include my Camilla DSP config file for the analog line inputs of the Motu M4. Here's one for simple stereo in => stereo out with volume control:

YAML:
devices:
  samplerate: 96000
  buffersize: 8192
  enable_rate_adjust: true
  capture:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE
  playback:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE

filters:
  volume:
    type: Volume
    parameters:
      ramp_time: 200
 
mixers:
  line_in_to_stereo_out:
    channels:
      in: 4
      out: 4
    mapping:
      - dest: 0
        sources:
          - channel: 2
            gain: 0
            inverted: false
      - dest: 1
        sources:
          - channel: 3
            gain: 0
            inverted: false

pipeline:
  - type: Filter
    channel: 2
    names:
      - volume
  - type: Filter
    channel: 3
    names:
      - volume
  - type: Mixer
    name: line_in_to_stereo_out

And then a 2.1 output with FIR filters generated by DRC-FIR:

YAML:
devices:
  samplerate: 96000
  buffersize: 8192
  enable_rate_adjust: true
  capture:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE
  playback:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE

filters:
  volume:
    type: Volume
    parameters:
      ramp_time: 200
  drc_l:
    type: Conv
    parameters:
      type: Wav
      filename: filters/s400+sb1kp-pos2-normal-96000.wav
      channel: 0
  drc_r:
    type: Conv
    parameters:
      type: Wav
      filename: filters/s400+sb1kp-pos2-normal-96000.wav
      channel: 1
  mainshighpass:
    type: BiquadCombo
    parameters:
      type: LinkwitzRileyHighpass
      freq: 80
      order: 8
  sublowpass:
    type: BiquadCombo
    parameters:
      type: LinkwitzRileyLowpass
      freq: 80
      order: 8
  mainsdelay:
    type: Delay
    parameters:
      delay: 9.2
      unit: ms
      subsample: false
 
mixers:
  to3:
    channels:
      in: 4
      out: 4
    mapping:
      - dest: 0
        sources:
          - channel: 2
            gain: 0
            inverted: false
      - dest: 1
        sources:
          - channel: 3
            gain: 0
            inverted: false
      - dest: 2
        sources:
          - channel: 2
            gain: 0
            inverted: false
          - channel: 3
            gain: 0
            inverted: false

pipeline:
  - type: Filter
    channel: 2
    names:
      - volume
      - drc_l
  - type: Filter
    channel: 3
    names:
      - volume
      - drc_r
  - type: Mixer
    name: to3
  - type: Filter
    channel: 0
    names:
      - mainshighpass
      - mainsdelay
  - type: Filter
    channel: 1
    names:
      - mainshighpass
      - mainsdelay
  - type: Filter
    channel: 2
    names:
      - sublowpass


That's what I want to do!!!
Have my Spotify streaming AND my turntable with DRC. I'm close to buy the minidsp shd studio but ... reliability / support ... too many software inside that devices. Maybe a "real computer" when everything can be modified / updated it's a good solution.
I mean, i cannot build an amplifier, but a computer with the right software and configuration, yes.
 

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,511
Likes
3,356
Location
Detroit, MI
Finally have my turntable integrated into the system. Sorry about the crappy phone pic.

View attachment 142104

DRC filters are computed with DRC-FIR from REW measured impulse response. So this is a DIY miniDSP SHD, assembled for about $450. In the pic from top left ot bottom right:

Michell Gyro SE turntable
SME 309 arm
Benz Ace high output moving coil cartridge
Rogue Audio Stealth phono preamp
Raspberry Pi 4b 8Gb board in FLIRC case ($104) + FLIRC USB IR receiver ($20)
SunFounder 7 Inch Monitor HDMI - 1024×600 HD LCD Display Screen ($76)
Motu M4 ($250)

I'm using an old Logitech Harmony 350 universal remote control, but just about any remote control should work.

EDIT: forgot to include my Camilla DSP config file for the analog line inputs of the Motu M4. Here's one for simple stereo in => stereo out with volume control:

YAML:
devices:
  samplerate: 96000
  buffersize: 8192
  enable_rate_adjust: true
  capture:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE
  playback:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE

filters:
  volume:
    type: Volume
    parameters:
      ramp_time: 200

mixers:
  line_in_to_stereo_out:
    channels:
      in: 4
      out: 4
    mapping:
      - dest: 0
        sources:
          - channel: 2
            gain: 0
            inverted: false
      - dest: 1
        sources:
          - channel: 3
            gain: 0
            inverted: false

pipeline:
  - type: Filter
    channel: 2
    names:
      - volume
  - type: Filter
    channel: 3
    names:
      - volume
  - type: Mixer
    name: line_in_to_stereo_out

And then a 2.1 output with FIR filters generated by DRC-FIR:

YAML:
devices:
  samplerate: 96000
  buffersize: 8192
  enable_rate_adjust: true
  capture:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE
  playback:
    type: Alsa
    channels: 4
    device: "hw:CARD=M4,DEV=0"
    format: S32LE

filters:
  volume:
    type: Volume
    parameters:
      ramp_time: 200
  drc_l:
    type: Conv
    parameters:
      type: Wav
      filename: filters/s400+sb1kp-pos2-normal-96000.wav
      channel: 0
  drc_r:
    type: Conv
    parameters:
      type: Wav
      filename: filters/s400+sb1kp-pos2-normal-96000.wav
      channel: 1
  mainshighpass:
    type: BiquadCombo
    parameters:
      type: LinkwitzRileyHighpass
      freq: 80
      order: 8
  sublowpass:
    type: BiquadCombo
    parameters:
      type: LinkwitzRileyLowpass
      freq: 80
      order: 8
  mainsdelay:
    type: Delay
    parameters:
      delay: 9.2
      unit: ms
      subsample: false

mixers:
  to3:
    channels:
      in: 4
      out: 4
    mapping:
      - dest: 0
        sources:
          - channel: 2
            gain: 0
            inverted: false
      - dest: 1
        sources:
          - channel: 3
            gain: 0
            inverted: false
      - dest: 2
        sources:
          - channel: 2
            gain: 0
            inverted: false
          - channel: 3
            gain: 0
            inverted: false

pipeline:
  - type: Filter
    channel: 2
    names:
      - volume
      - drc_l
  - type: Filter
    channel: 3
    names:
      - volume
      - drc_r
  - type: Mixer
    name: to3
  - type: Filter
    channel: 0
    names:
      - mainshighpass
      - mainsdelay
  - type: Filter
    channel: 1
    names:
      - mainshighpass
      - mainsdelay
  - type: Filter
    channel: 2
    names:
      - sublowpass

Would you mind posting more info on your display / volume control setup? I just started playing around with the CamillaDSP GUI and now have volume control implemented but would like to move to something like your setup with an IR receiver and standalone display.

Michael
 

Daverz

Major Contributor
Joined
Mar 17, 2019
Messages
1,309
Likes
1,475
Would you mind posting more info on your display / volume control setup? I just started playing around with the CamillaDSP GUI and now have volume control implemented but would like to move to something like your setup with an IR receiver and standalone display.

Michael

I intend to put the code and instructions up on GitHub. It's pretty specific to my setup, though, so would be more of an example of what you can do than a generally usable app.

It uses PyGobject on Ubuntu Desktop, though I've set it up boot into console mode and start the app on "bare" X11 so it runs as a kiosk app. PyGObject is probably huge overkill for this app, but it's already installed on Ubuntu Desktop and I'm familiar with it. (I actually wanted to use the console directly with something like Kivy, but could not get Kivy to work in the console.) This PyGobject setup actually uses less than 500M memory, so you could start with Ubuntu Server, add the needed packages, and it should work fine on a 1Gb Pi4. A full server OS is not ideal for this application, though. You cannot just pull the power. It might be more ideal (but more work) to start with one of the appliance type Linux images and then build out the image with the needed software.
 

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,511
Likes
3,356
Location
Detroit, MI
I intend to put the code and instructions up on GitHub. It's pretty specific to my setup, though, so would be more of an example of what you can do than a generally usable app.

It uses PyGobject on Ubuntu Desktop, though I've set it up boot into console mode and start the app on "bare" X11 so it runs as a kiosk app. PyGObject is probably huge overkill for this app, but it's already installed on Ubuntu Desktop and I'm familiar with it. (I actually wanted to use the console directly with something like Kivy, but could not get Kivy to work in the console.) This PyGobject setup actually uses less than 500M memory, so you could start with Ubuntu Server, add the needed packages, and it should work fine on a 1Gb Pi4. A full server OS is not ideal for this application, though. You cannot just pull the power. It might be more ideal (but more work) to start with one of the appliance type Linux images and then build out the image with the needed software.

Thanks for the info that is really helpful, definitely a bit more involved than I originally assumed but not too bad. I've actually been pretty impressed with how easy it is to adjust volume on the web interface on an old iPhone connected to wifi although I do prefer a traditional display.

Michael
 

Daverz

Major Contributor
Joined
Mar 17, 2019
Messages
1,309
Likes
1,475
Would you mind posting more info on your display / volume control setup? I just started playing around with the CamillaDSP GUI and now have volume control implemented but would like to move to something like your setup with an IR receiver and standalone display.

Michael

I pushed the code:

https://github.com/daverz/camilla-remote-control

No documentation yet, and as you can see I'm not big on commenting my code. But one thing to explain: I wanted everything in one file, so all the Camilla configs needed are built as Python objects when the script is started. So there are no YAML files.

Note that if you don't have the FLIRC USB infrared receiver, you can just hook up a keyboard to the Pi.

Also, I started on a balance control, but there's no display for that yet, and I bound left and right balance directly to the Left and Right keys. The intent is to eventually have this in a menu.
 
Top Bottom