Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Add support for the portaudio library #116

Closed
dubnemo opened this issue Apr 19, 2020 · 68 comments
Closed

Add support for the portaudio library #116

dubnemo opened this issue Apr 19, 2020 · 68 comments
Labels
feature request Feature request

Comments

@dubnemo
Copy link

dubnemo commented Apr 19, 2020

I understand you have a Jack wrapper implementation, but native alsa may provide even better performance on the raspberry pi for Jamulus clients leveraging HiFiBerry DAC+ ADC boards.

@corrados corrados added the feature request Feature request label Apr 20, 2020
@corrados
Copy link
Contributor

Can you prove that? I run Jamulus on a Raspberry Pi Zero with Jack. I do not think direct ALSA interface can improve the performance. Maybe some Jack Audio developer can comment on that.

@mirabilos
Copy link
Contributor

JACK also uses ALSA in the backend, because ALSA is what the kernel provides (that, or OSS).

So, as long as you have only one application using sound running, ALSA has much less overhead (less processes ⇒ less RAM and less context switches).

I’d prefer ALSA on Linux but have JACK as an option (e.g. for proper musicians who use it anyway), but we need JACK on GNU/kFreeBSD and GNU/Hurd in Debian because these don’t have ALSA because they don’t use the Linux kernel, so ideally both would be available and the user could choose.

@trebmuh
Copy link
Member

trebmuh commented Apr 20, 2020

JACK can use ALSA in the backend, but it can use a bunch of other backends too (think FFADO as an example).

@corrados
Copy link
Contributor

See this commit: cb951c9 and also this: https://github.com/corrados/jamulus/blob/master/ChangeLog#L368
We have an audio interface for ASIO, CoreAudio, Jack and Android (under development). I actually do not want to have another one...

@dubnemo
Copy link
Author

dubnemo commented Apr 20, 2020

My HiFiBerry DAC+ ADC has shipped (Switzerland -> Minneapolis US), and it is only accessed via ALSA interface. My guess is the coverage of the implementation of ALSA within Jack.
I too have Jamulus working on RPi4 in listening mode only. Need the ADC for full functionality. I will have proof when I receive and test -- I suspect I will be OK.

@mirabilos
Copy link
Contributor

mirabilos commented Apr 20, 2020 via email

@dubnemo
Copy link
Author

dubnemo commented Apr 23, 2020

@mirabilos

This makes no sense. If it works without JACK it will work with JACK.

Really.
So are you saying that JACK implements 100% of the ALSA interfaces?
https://www.alsa-project.org/alsa-doc/alsa-lib/files.html

An application may choose to implement what it needs for the scope of its functionality; e.g., MIDI (rawmidi.h) may be out of scope. That is what is typically is called 'coverage', at least in my 30+ years of development.

@mirabilos
Copy link
Contributor

mirabilos commented Apr 23, 2020 via email

@elliotclee
Copy link

@corrados Could you just switch Jamulus to using portaudio (portaudio.com) as its audio API? It would relieve you of the need to maintain code for multiple audio APIs, and it would add support for additional audio interfaces (e.g. WDM-KS on Windows). It's also the library that Jack itself uses.

@corrados
Copy link
Contributor

Jack on Linux uses portaudio?

@elliotclee
Copy link

Not on Linux. Definitely on Windows, maybe on Mac (git has libportaudio.a but I'm not sure it's still used).

Does the portaudio API provide adequate functionality for Jamulus' needs?

@corrados
Copy link
Contributor

Does portaudio support the Google Oboe library for Android? We are currently working on a new audio interface implementation for Jamulus for Android which uses the Oboe library, see #83

@elliotclee
Copy link

Good question. Looks like the official Portaudio is mainly a Win/Mac/Linux deal. There is a port of portaudio to opensles at https://github.com/Gundersanne/portaudio_opensles/tree/master/src/hostapi/opensles but that's the old Android API. I can't find any port of portaudio to AAudio or Oboe.

It might be just as much work to add Oboe support to portaudio as it would be to update the Jamulus audio code to support all the other platforms it would be nice to have. E.g. using portaudio would allow switching between ASIO and Jack at runtime on Windows, and allow also using WDM-KS devices.

@corrados
Copy link
Contributor

Yes, I see the advantages of portaudio. It is definitely much better to include portaudio than ALSA directly (as is the title of this Issue). But right now I do not see an urgent need of including portaudio. Maybe we should change the title of this Issue and work on a portaudio integration sometime later (maybe when the peak of Corona is over and we have more time for other stuff).

@corrados
Copy link
Contributor

corrados commented May 9, 2020

Since portaudio supports ALSA directly, I will change the title of this Issue now to better reflect the ongoing discussion here.

@corrados corrados changed the title consider ALSA interface on linux/ raspbian Add support for the portaudio library May 9, 2020
This was referenced May 18, 2020
@dubnemo
Copy link
Author

dubnemo commented May 25, 2020

I still don't understand why you are not considering dmix plug-in for ALSA to eliminate the extra dependencies. One can provide basic instructions on the asound.conf file.
https://www.alsa-project.org/main/index.php/Asoundrc

@mirabilos
Copy link
Contributor

mirabilos commented May 25, 2020 via email

@dubnemo
Copy link
Author

dubnemo commented May 27, 2020

@mirabilos I am using an add-on ADC GPIO board to avoid the USB interface and any potential latency that introduces. So in order to make that happen, I currently do have to create asound.conf with dmix slave. As @streaps states it would work fine for USB interface users without any asound.conf once you have Jack routed - not so casual.

The dmix C interface seems pretty straight-forward to pass in the PCM stream.
https://www.alsa-project.org/alsa-doc/alsa-lib/pcm__dmix_8c.html#ae31120062bceb47f24d18e672f728b4f
the second overload function has slave parameters.

@dubnemo
Copy link
Author

dubnemo commented Mar 21, 2022

Am I reading this correctly, that portaudio depends on Jack?

pi@raspberrypi:~ $ sudo apt install portaudio19-dev
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  libasound2-dev libjack-dev libjack0 libportaudio2 libportaudiocpp0 uuid-dev
Suggested packages:
  libasound2-doc jackd1 portaudio19-doc
The following packages will be REMOVED:
  libjack-jackd2-0
The following NEW packages will be installed:
  libasound2-dev libjack-dev libjack0 libportaudio2 libportaudiocpp0
  portaudio19-dev uuid-dev
0 upgraded, 7 newly installed, 1 to remove and 0 not upgraded.
Need to get 734 kB of archives.
After this operation, 3,142 kB of additional disk space will be used.
Do you want to continue? [Y/n] n

@elliotclee
Copy link

elliotclee commented Mar 22, 2022 via email

@npostavs
Copy link
Contributor

I'll try to add an option to the Jamulus project file to compile portaudio without jack.

@elliotclee
Copy link

elliotclee commented Mar 22, 2022 via email

@npostavs
Copy link
Contributor

I wrote Jamulus' portaudio code so I have an idea about how involved it is ;)

I remember seeing somewhere that Jamulus only compiles portaudio on win32,

Initially I only did it for win32, but later extended it to unix & macOS platforms (although I don't recall if anyone ever tested on macOS so it may not actually work).

@dubnemo
Copy link
Author

dubnemo commented Mar 22, 2022

@elliotclee @npostavs
I noticed the latest PortAudio will not compile on Raspberry Pi4 without edits, hopefully resolved on the next V19.8 milestone.
PortAudio/portaudio#683

Yes, because portaudio can act as an abstraction layer on top of Jack. If you don't want Jack installed then you'd need to build your own custom portaudio19 packages. Elliot

@jujudusud
Copy link
Member

On portaudio's website, they say :

That will build PortAudio using Jack, ALSA and OSS in whatever combination they are found on your system. For example, if you have Jack and OSS but not ALSA, it will build using Jack and OSS but not ALSA.

If you compile portaudio yourself without JACK installed, then it doesn't use JACK?
Take a look at this page : Compilation guide for Linux

@dubnemo
Copy link
Author

dubnemo commented Mar 22, 2022

Is it fair to state the minimal viable product for a PortAudio build for RPi4 would only need these files?
portaudio.h
pa_devs.c
pa_linux_alsa.h

Ref:
http://files.portaudio.com/docs/v19-doxydocs/files.html

@npostavs
Copy link
Contributor

I wrote Jamulus' portaudio code so I have an idea about how involved it is ;)

Okay, I actually had forgotten that the non-win32 support was only for the shared lib config, so it was slightly more involved than I realized. But I think the following patch (or git commit here) against the feature branch should work (I tested on my Linux box, though I don't have rPi so I can't guarantee it will work there). Compile with qmake CONFIG+=portaudio and it will use ALSA-only on non-win32 systems.

[PATCH] Allow compiling portaudio with ALSA only
From 7c7ab672a01cae400b689c60201868b8d9ab921b Mon Sep 17 00:00:00 2001
From: Noam Postavsky <[email protected]>
Date: Sat, 26 Mar 2022 13:15:57 -0400
Subject: [PATCH] Allow compiling portaudio with ALSA only

---
 Jamulus.pro | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/Jamulus.pro b/Jamulus.pro
index a8fda289..f9b28ab7 100644
--- a/Jamulus.pro
+++ b/Jamulus.pro
@@ -63,6 +63,8 @@ INCLUDEPATH_OPUS = libs/opus/include \
 INCLUDEPATH_PORTAUDIO = libs/portaudio/include libs/portaudio/src/common
 win32 {
     INCLUDEPATH_PORTAUDIO += libs/portaudio/src/os/win
+} else {
+    INCLUDEPATH_PORTAUDIO += libs/portaudio/src/os/unix
 }
 
 DEFINES += APP_VERSION=\\\"$$VERSION\\\" \
@@ -763,12 +765,15 @@ win32 {
     }
 } else:unix {
     SOURCES_PORTAUDIO += $$files(libs/portaudio/src/os/unix/*.c)
-    SOURCES_PORTAUDIO += $$files(libs/portaudio/src/os/hostapi/alsa/*.c) \
-        $$files(libs/portaudio/src/os/hostapi/jack/*.c) \
-        $$files(libs/portaudio/src/os/hostapi/oss/*.c)
+    # Does it ever make sense to use OSS?
+    # $$files(libs/portaudio/src/hostapi/oss/*.c)
+    SOURCES_PORTAUDIO += $$files(libs/portaudio/src/hostapi/alsa/*.c)
+    CONFIG(portaudio_jack) {
+        SOURCES_PORTAUDIO += $$files(libs/portaudio/src/hostapi/jack/*.c)
+    }
 } else:macx {
     SOURCES_PORTAUDIO += $$files(libs/portaudio/src/os/unix/*.c)
-    SOURCES_PORTAUDIO += $$files(libs/portaudio/src/os/hostapi/coreaudio/*.c)
+    SOURCES_PORTAUDIO += $$files(libs/portaudio/src/hostapi/coreaudio/*.c)
 }
 
 # I can't figure out how to make the custom compiler stuff work for
@@ -1231,8 +1236,12 @@ CONFIG(portaudio) {
     SOURCES += src/portaudiosound.cpp
     CONFIG(portaudio_shared_lib) {
         LIBS += $$libnames(portaudio)
-    } else:win32 {
-        DEFINES += PA_USE_ASIO=1 PA_USE_WASAPI=1 PA_USE_WDMKS=1
+    } else {
+        win32 {
+            DEFINES += PA_USE_ASIO=1 PA_USE_WASAPI=1 PA_USE_WDMKS=1
+        } else {
+            DEFINES += PA_USE_ALSA=1
+        }
         INCLUDEPATH += $$INCLUDEPATH_PORTAUDIO
         HEADERS += $$HEADERS_PORTAUDIO
         mingw {
@@ -1243,9 +1252,11 @@ CONFIG(portaudio) {
             SOURCES += $$SOURCES_PORTAUDIO $$SOURCES_CXX_PORTAUDIO
         }
         DISTFILES += $$DISTFILES_PORTAUDIO
-        LIBS += $$libnames(winmm ole32 uuid setupapi)
-    } else {
-        error ( "non-shared portaudio only implemented for win32" )
+        win32 {
+              LIBS += $$libnames(winmm ole32 uuid setupapi)
+        } else {
+              LIBS += -lasound
+        }
     }
 }
 
-- 
2.11.0

@dubnemo
Copy link
Author

dubnemo commented Mar 27, 2022

@npostavs

used qmake CONFIG+=portaudio

it was going so well until this...

g++ -Wl,--as-needed -Wl,-O1 -o Jamulus buffer.o channel.o client.o main.o protocol.o jamcontroller.o server.o serverlist.o serverlogging.o settings.o signalhandler.o socket.o soundbase.o util.o jamrecorder.o creaperproject.o cwavestream.o audiomixerboard.o chatdlg.o clientsettingsdlg.o connectdlg.o clientdlg.o serverdlg.o multicolorled.o levelmeter.o analyzerconsole.o bands.o celt.o celt_decoder.o celt_encoder.o celt_lpc.o cwrs.o entcode.o entdec.o entenc.o kiss_fft.o laplace.o mathops.o mdct.o modes.o pitch.o quant_bands.o rate.o vq.o A2NLSF.o ana_filt_bank_1.o biquad_alt.o bwexpander.o bwexpander_32.o check_control_input.o CNG.o code_signs.o control_audio_bandwidth.o control_codec.o control_SNR.o debug.o decoder_set_fs.o decode_core.o decode_frame.o decode_indices.o decode_parameters.o decode_pitch.o decode_pulses.o dec_API.o encode_indices.o encode_pulses.o enc_API.o apply_sine_window_FLP.o autocorrelation_FLP.o burg_modified_FLP.o bwexpander_FLP.o corrMatrix_FLP.o encode_frame_FLP.o energy_FLP.o find_LPC_FLP.o find_LTP_FLP.o find_pitch_lags_FLP.o find_pred_coefs_FLP.o inner_product_FLP.o k2a_FLP.o LPC_analysis_filter_FLP.o LTP_analysis_filter_FLP.o LTP_scale_ctrl_FLP.o noise_shape_analysis_FLP.o pitch_analysis_core_FLP.o process_gains_FLP.o residual_energy_FLP.o scale_copy_vector_FLP.o scale_vector_FLP.o schur_FLP.o sort_FLP.o warped_autocorrelation_FLP.o wrappers_FLP.o gain_quant.o HP_variable_cutoff.o init_decoder.o init_encoder.o inner_prod_aligned.o interpolate.o lin2log.o log2lin.o LPC_analysis_filter.o LPC_fit.o LPC_inv_pred_gain.o LP_variable_cutoff.o NLSF2A.o NLSF_decode.o NLSF_del_dec_quant.o NLSF_encode.o NLSF_stabilize.o NLSF_unpack.o NLSF_VQ.o NLSF_VQ_weights_laroia.o NSQ.o NSQ_del_dec.o pitch_est_tables.o PLC.o process_NLSFs.o quant_LTP_gains.o resampler.o resampler_down2.o resampler_down2_3.o resampler_private_AR2.o resampler_private_down_FIR.o resampler_private_IIR_FIR.o resampler_private_up2_HQ.o resampler_rom.o shell_coder.o sigm_Q15.o sort.o stereo_decode_pred.o stereo_encode_pred.o stereo_find_predictor.o stereo_LR_to_MS.o stereo_MS_to_LR.o stereo_quant_pred.o sum_sqr_shift.o tables_gain.o tables_LTP.o tables_NLSF_CB_NB_MB.o tables_NLSF_CB_WB.o tables_other.o tables_pitch_lag.o tables_pulses_per_block.o table_LSF_cos.o VAD.o VQ_WMat_EC.o analysis.o mlp.o mlp_data.o opus.o opus_decoder.o opus_encoder.o repacketizer.o portaudiosound.o qrc_resources.o moc_channel.o moc_client.o moc_protocol.o moc_jamcontroller.o moc_server.o moc_serverlist.o moc_settings.o moc_socket.o moc_soundbase.o moc_testbench.o moc_util.o moc_jamrecorder.o moc_creaperproject.o moc_signalhandler.o moc_audiomixerboard.o moc_chatdlg.o moc_clientsettingsdlg.o moc_connectdlg.o moc_clientdlg.o moc_serverdlg.o moc_levelmeter.o moc_analyzerconsole.o moc_multicolorled.o   -lasound -lpthread /usr/lib/aarch64-linux-gnu/libQt5Widgets.so /usr/lib/aarch64-linux-gnu/libQt5Gui.so /usr/lib/aarch64-linux-gnu/libQt5Network.so /usr/lib/aarch64-linux-gnu/libQt5Xml.so /usr/lib/aarch64-linux-gnu/libQt5Concurrent.so /usr/lib/aarch64-linux-gnu/libQt5Core.so -lGL   
/usr/bin/ld: portaudiosound.o: in function `CSound::GetNumInputChannels() [clone .localalias]':
portaudiosound.cpp:(.text+0x28): undefined reference to `Pa_GetDeviceInfo'
/usr/bin/ld: portaudiosound.o: in function `CSound::GetNumOutputChannels() [clone .localalias]':
portaudiosound.cpp:(.text+0x58): undefined reference to `Pa_GetDeviceInfo'
/usr/bin/ld: portaudiosound.o: in function `CSound::UnloadCurrentDriver()':
portaudiosound.cpp:(.text+0x88): undefined reference to `Pa_CloseStream'
/usr/bin/ld: portaudiosound.cpp:(.text+0xa0): undefined reference to `Pa_Terminate'
/usr/bin/ld: portaudiosound.o: in function `CSound::Start()':
portaudiosound.cpp:(.text+0x214): undefined reference to `Pa_StartStream'
/usr/bin/ld: portaudiosound.o: in function `CSound::Stop()':
portaudiosound.cpp:(.text+0x244): undefined reference to `Pa_StopStream'
/usr/bin/ld: portaudiosound.o: in function `CSound::SetLeftInputChannel(int)':
portaudiosound.cpp:(.text+0x2b4): undefined reference to `Pa_GetDeviceInfo'
/usr/bin/ld: portaudiosound.o: in function `CSound::SetRightInputChannel(int)':
portaudiosound.cpp:(.text+0x324): undefined reference to `Pa_GetDeviceInfo'
/usr/bin/ld: portaudiosound.o: in function `CSound::SetLeftOutputChannel(int)':
portaudiosound.cpp:(.text+0x394): undefined reference to `Pa_GetDeviceInfo'
/usr/bin/ld: portaudiosound.o: in function `CSound::SetRightOutputChannel(int)':
portaudiosound.cpp:(.text+0x404): undefined reference to `Pa_GetDeviceInfo'
/usr/bin/ld: portaudiosound.o: in function `CSound::InitPa()':
portaudiosound.cpp:(.text+0x584): undefined reference to `Pa_Initialize'
/usr/bin/ld: portaudiosound.cpp:(.text+0x594): undefined reference to `Pa_GetHostApiCount'
/usr/bin/ld: portaudiosound.cpp:(.text+0x5cc): undefined reference to `Pa_GetHostApiInfo'
/usr/bin/ld: portaudiosound.cpp:(.text+0x650): undefined reference to `Pa_GetErrorText'
/usr/bin/ld: portaudiosound.o: in function `CSound::ReinitializeDriver(int, int)':
portaudiosound.cpp:(.text+0x95c): undefined reference to `Pa_GetDeviceInfo'
/usr/bin/ld: portaudiosound.cpp:(.text+0x968): undefined reference to `Pa_GetDeviceInfo'
/usr/bin/ld: portaudiosound.cpp:(.text+0x978): undefined reference to `Pa_CloseStream'
/usr/bin/ld: portaudiosound.cpp:(.text+0xa2c): undefined reference to `Pa_OpenStream'
/usr/bin/ld: portaudiosound.cpp:(.text+0xa60): undefined reference to `Pa_GetErrorText'
/usr/bin/ld: portaudiosound.cpp:(.text+0xaa8): undefined reference to `Pa_GetLastHostErrorInfo'
/usr/bin/ld: portaudiosound.o: in function `CSound::~CSound()':
portaudiosound.cpp:(.text+0xcc4): undefined reference to `Pa_Terminate'
/usr/bin/ld: portaudiosound.o: in function `CSound::GetPaApiNames()':
portaudiosound.cpp:(.text+0xd98): undefined reference to `Pa_Initialize'
/usr/bin/ld: portaudiosound.cpp:(.text+0xda4): undefined reference to `Pa_GetHostApiCount'
/usr/bin/ld: portaudiosound.cpp:(.text+0xdd4): undefined reference to `Pa_GetHostApiInfo'
/usr/bin/ld: portaudiosound.cpp:(.text+0xe48): undefined reference to `Pa_Terminate'
/usr/bin/ld: portaudiosound.cpp:(.text+0xe74): undefined reference to `Pa_Terminate'
/usr/bin/ld: portaudiosound.cpp:(.text+0xe9c): undefined reference to `Pa_Terminate'
/usr/bin/ld: portaudiosound.o: in function `CSound::Init(int)':
portaudiosound.cpp:(.text+0xef8): undefined reference to `Pa_GetHostApiInfo'
/usr/bin/ld: portaudiosound.o: in function `CSound::CSound(void (*)(CVector<short>&, void*), void*, QString const&, bool, QString const&, QString const&)':
portaudiosound.cpp:(.text+0x10a8): undefined reference to `Pa_HostApiDeviceIndexToDeviceIndex'
/usr/bin/ld: portaudiosound.cpp:(.text+0x10b0): undefined reference to `Pa_GetDeviceInfo'
/usr/bin/ld: portaudiosound.cpp:(.text+0x10ec): undefined reference to `Pa_HostApiDeviceIndexToDeviceIndex'
/usr/bin/ld: portaudiosound.cpp:(.text+0x10f4): undefined reference to `Pa_GetDeviceInfo'
collect2: error: ld returned 1 exit status
make: *** [Makefile:1109: Jamulus] Error 1

@dubnemo
Copy link
Author

dubnemo commented Mar 27, 2022

trying qmake 'CONFIG+=portaudio portaudio_shared_lib'

@npostavs
Copy link
Contributor

it was going so well until this...

Hmm, looks like it's failing to link portaudio sources, I don't understand why.

@dubnemo
Copy link
Author

dubnemo commented Mar 27, 2022

This did not return any errors BUT on RPi4 Jamulus was not added to the menu.

qmake 'CONFIG+=portaudio portaudio_shared_lib' 
make

I am trying again..

Compiling.md definitely requires this for the RPi4:
sudo apt install portaudio19-dev

Once PortAudio 19.8 is available, I will try to build a slim MVP package.

@dubnemo
Copy link
Author

dubnemo commented Mar 27, 2022

I suspect this is due to the PortAudio 19.7 package I installed:

2022-03-27-114320_1920x1080_scrot

@npostavs
Copy link
Contributor

I suspect this is due to the PortAudio 19.7 package I installed:

Oh, I forgot to mention you have to run with Jamulus --api ALSA.

@dubnemo
Copy link
Author

dubnemo commented Mar 28, 2022

I will have time to fully test this Wednesday evening Central (us).

After editing jamulus.desktop, I have now have the Jamulus client running and connected to my local server in my studio basement. The previous performance with the Hi-Fi Berry ADC-DAC was ~80ms total roundtrip, and this is about 1/2.

I am not sure about the Pulse device, but again, I will test this out.

pi@raspberrypi:/usr/local/share/applications $ sudo nano jamulus.desktop
pi@raspberrypi:/usr/local/share/applications $ cat jamulus.desktop
[Desktop Entry]
Name=Jamulus
Comment=Jam Session
Comment[fr]=Séance de bœuf
Comment[sv]=Musikaliska jamsessioner över Internet
GenericName=Internet Jam Session Software
GenericName[fr]=Logiciel de séance de bœuf sur Internet
GenericName[es]=Software para Jam Sessions por Internet
GenericName[pt]=Software para Jam Sessions pela Internet
GenericName[nl]=Software voor jamsessies over internet
GenericName[sk]=Softvér na džemovanie cez internet
GenericName[sv]=Mjukvara för Jam Sessioner över Internet
Exec=Jamulus --api ALSA
Icon=jamulus
Terminal=false
Type=Application
Categories=AudioVideo;Audio;Mixer;Qt;
Keywords=jam;live;online;music;conference;

2022-03-28-155255_1920x1080_scrot

When I select the Hi-Fi Berry from the Device drop-down directly, it is throwing an exception. But that may be a configuration issue.

2022-03-28-155712_1920x1080_scrot

@jujudusud
Copy link
Member

jujudusud commented Mar 28, 2022

Nice !
@npostavs: do you need X86_64 Linux and windows 10 64 bits testers ?

I want to test Windows WASAPI to use it instead of asio4all.

P.S.: No need to use OSS server in 2022 from my point of view.

@dubnemo
Copy link
Author

dubnemo commented Mar 29, 2022

@npostavs: I woke up in the middle of the night thinking the Hi-Fi Berry device should work, as there isn't much to configure. I only edited the /boot/config.txt


# use the headphone output jack on the RPi4
dtparam=audio=on
# enable DAC+ ADC Pro
dtoverlay=hifiberry-dacplusadcpro

#Disable Wifi; use eth0 for Jamulus only
dtoverlay=disable-wifi 
# disable bluetooth
dtoverlay=disable-bt

I have not created ~/.asoundrc (my user only) or /etc/asound.conf (all users) files.

There may have an interface mismatch with the number of channels(?).

@npostavs
Copy link
Contributor

I want to test Windows WASAPI to use it instead of asio4all.

You can give it a shot, although I found the results disappointing on my hardware (run Jamulus with --api WASAPI to activate). Note that you can also try KoordASIO instead of asio4all; it uses WASAPI via PortAudio too (and likewise doesn't seem to work well with my hardware).

There may have an interface mismatch with the number of channels(?).

Hmm, I'm not sure what's triggerring that error.

@dubnemo
Copy link
Author

dubnemo commented Mar 31, 2022

@npostavs I thought you'd like to know that I am getting the same error with the channel interface.

Just to be clear the configuration

pi@raspberrypi:~ $ cat /proc/asound/cards
 0 [Headphones     ]: bcm2835_headpho - bcm2835 Headphones
                      bcm2835 Headphones
 1 [vc4hdmi0       ]: vc4-hdmi - vc4-hdmi-0
                      vc4-hdmi-0
 2 [vc4hdmi1       ]: vc4-hdmi - vc4-hdmi-1
                      vc4-hdmi-1
 3 [sndrpihifiberry]: HifiberryDacpAd - snd_rpi_hifiberry_dacplusadcpro
                      snd_rpi_hifiberry_dacplusadcpro

pi@raspberrypi:~ $ cat /proc/asound/devices
  0: [ 0]   : control
 16: [ 0- 0]: digital audio playback
 32: [ 1]   : control
 33:        : timer
 48: [ 1- 0]: digital audio playback
 64: [ 2]   : control
 80: [ 2- 0]: digital audio playback
 96: [ 3]   : control
112: [ 3- 0]: digital audio playback
120: [ 3- 0]: digital audio capture

Works in Audacity:
2022-03-30-230745_1920x1080_scrot

But I get the error when selecting the device in the Jamulus client:

2022-03-30-230851_1920x1080_scrot

Really unrelated, but I am unclear why PulseAudio daemon is referenced, even when I remove it:


pi@raspberrypi:~ $ sudo apt-get purge pulseaudio
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  libpulsedsp pulseaudio-utils rtkit
Use 'sudo apt autoremove' to remove them.
The following packages will be REMOVED:
  lxplug-volumepulse* pulseaudio* pulseaudio-module-bluetooth*
0 upgraded, 0 newly installed, 3 to remove and 48 not upgraded.
After this operation, 6,919 kB disk space will be freed.
Do you want to continue? [Y/n] Y
(Reading database ... 95430 files and directories currently installed.)
Removing lxplug-volumepulse (0.12) ...
Removing pulseaudio-module-bluetooth (14.2-2+rpi1) ...
Removing pulseaudio (14.2-2+rpi1) ...
Processing triggers for man-db (2.9.4-2) ...
(Reading database ... 95179 files and directories currently installed.)
Purging configuration files for pulseaudio (14.2-2+rpi1) ...
Processing triggers for dbus (1.12.20-2) ...

oddly it still shows up when I start the Jamulus client:

pi@raspberrypi:~ $ ps -ef | grep pulse
pi           653     632  1 22:35 ?        00:00:27 /usr/bin/pulseaudio --daemonize=no --log-target=journal
pi          3136    1613  0 23:09 pts/0    00:00:00 grep --color=auto pulse

And the PulseAudio sound server interface seems to be working (I will check my server recording). If this daemon can be bypassed and go direct via PortAudio like Audacity, I suspect the total delay can be further reduced.

2022-03-30-232508_1920x1080_scrot

@dubnemo
Copy link
Author

dubnemo commented Mar 31, 2022

PortAudio seems to use PulseAudio sound server. I went into Audacity again, then killed pid 632, and the RPi4 screen went blank and restarted with the login screen.

@elliotclee
Copy link

elliotclee commented Mar 31, 2022 via email

@dubnemo
Copy link
Author

dubnemo commented Apr 1, 2022

@elliotclee yes, you are correct. It is not spawned by PortAudio. Jamulus client saw PulseAudio and that was able to communicate to the HiFi Berry card in my earlier screenshots, hence why it was able to start. Now after restart of the RPi4, I now see this on startup of Jamulus client.
2022-04-01-072025_1920x1080_scrot

@npostavs do you think there a PortAudio callback that is not set properly? Audacity still works after uninstall of PulseAudio too. Is there a way to turn on fine logging in the client via a cli parameter?

@npostavs
Copy link
Contributor

npostavs commented Apr 1, 2022

I haven't added a logging option; I'm not really what there is to log.

You could try fiddling with the setting of paInputParams.suggestedLatency in src/portaudiosound.cpp, I did find that I got some confusing errors on Windows when it was set to the wrong value (and it's still unclear to me how to know the right value).

Might also be worth investigating whether any the functions in http://files.portaudio.com/docs/v19-doxydocs/pa__linux__alsa_8h.html helps. At least PaAlsa_EnableRealtimeScheduling seems relevant.

@dubnemo
Copy link
Author

dubnemo commented Apr 1, 2022

@npostavs
Curious what is in devInfo for the Hi Fi Berry, as it has a 35mm stereo input and two RCA outputs available out of the box, but it appears there are balanced inputs and outputs available on the board with soldering.
From above:

112: [ 3- 0]: digital audio playback
120: [ 3- 0]: digital audio capture

One of the above errors showed 'invalid number of channels'.

@dubnemo
Copy link
Author

dubnemo commented Apr 21, 2022

It seems more on the device initialization, versus streams.

http://files.portaudio.com/docs/v19-doxydocs/api_overview.html
Although each Device conceptually belongs to a specific Host API, most PortAudio functions and data structures refer to Devices using a global, Host API-independent index of type PaDeviceIndex an integer of that ranges between zero and Pa_GetDeviceCount() - 1. The reasons for this are partly historical but it also makes it easy for applications to ignore the Host API abstraction and just work with Devices and Streams.

If you want to enumerate Devices belonging to a particular Host API you can count between 0 and PaHostApiInfo::deviceCount - 1. You can convert this Host API-specific index value to a global PaDeviceIndex value by calling Pa_HostApiDeviceIndexToDeviceIndex().

=====
deviceCount -1 may be relevant.

Do you really want to iterate on the api count or the device count?
for ( PaHostApiIndex i = 0; i < apiCount; i++ ); ... selectedApiIndex = apiIndex;

selectedApiIndex is passed as an argument to Pa_HostApiDeviceIndexToDeviceIndex

PaDeviceIndex outDevIndex = Pa_HostApiDeviceIndexToDeviceIndex ( selectedApiIndex, j );

@jamulussoftware jamulussoftware locked and limited conversation to collaborators Apr 22, 2022
@ann0see ann0see converted this issue into discussion #2606 Apr 22, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
feature request Feature request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants