csukuangfj / PortAudioSharp2

C# binding for portaudio supporting Linux, macOS, Windows, iOS
Apache License 2.0
26 stars 4 forks source link

Linux build 0 devices #19

Open FossaMalaEnt opened 5 months ago

FossaMalaEnt commented 5 months ago

Hi, thanks for the work on this repo!

On windows It works great, but on linux I'm having some touble, the device count is always 0 and I'm unable to record any audio.

I've updated the package on the version 1.0.0 but the issue is still present, tested on Ubuntu Desktop, Arch linux and Porteus Kiosk.

csukuangfj commented 5 months ago

@nwhitehead Could you have a look?

I thought https://github.com/csukuangfj/PortAudioSharp2/issues/14 has fixed the issue.

nwhitehead commented 5 months ago

@FossaMalaEnt Could you take a look at the libportaudio.so file in a project directory like bin/Debug/net8.0/runtimes/linux-x64/native. The latest 1.0.0 file should have size 203240, the old one was different. I got the behavior you described with the old libportaudio.so library but the new one works for me in Ubuntu 23.10 (at least to enumerate more than 0 devices).

FossaMalaEnt commented 5 months ago

I installed Ubuntu Desktop on my PC along with all the necessary .NET tools. When I run my application in debug mode locally, the library works fine, I can see the audio inputs and I'm able to record audio. However, when I build the application for release and package it into a snap (still using Ubuntu Desktop, and I can still see the audio inputs from the settings of ubuntu), I encounter issues.

After unpacking the snap and examining the build files, I found libportaudio.so with the correct file size: image

Maybe the snap package can cause some issues?

This week I will try to make different build and debug on this, will update

nwhitehead commented 5 months ago

I've never built snaps before. Today I went down the rabbit hole and got a test app working in Linux.

.NET and Snap

The first annoyance was getting anything compiled with dotnet to run. I tried to use the dotnet plugin in the core22 base for a hello world app but the final application would never run properly. The app would always say "You must install .NET to run this application..." That happened even if I installed various things outside or inside the snap package.

The solution for this first hurdle was to add the line dotnet-self-contained-runtime-identifier: linux-x64. That seemed to tell the dotnet plugin to build a self-contained application.

Then I got an error message at runtime that said "Process terminated. Couldn't find a valid ICU package...". I fixed that by adding libicu70 to stage-packages.

ALSA Configuration

Next the app tried to run but had trouble with missing libraries. So I added libasound2 and libjack0 to the stage-packages. I added alsa to the plugs configuration.

Now the app ran and tried to use ALSA, but got permission denied errors on paths like /usr/share/alsa/alsa.conf. I read documentation on that and figured out that the alsa plug still requires you to map filenames for alsa into the snap. I mapped in /usr/share/alsa and /etc/alsa into the snap using a layout. That seemed to be enough.

I also did a command sudo snap connect portaudiotest:alsa which enables ALSA for the snap. I'm not sure if that was needed since I was using --devmode.

In the end my tiny test snap app was able to use PortAudioSharp2, call Initialize(), and play some sine waves. So, success!

Weirdness

One thing I noticed is that the snap app sees 13 audio devices. Running the app outside the snap shows 20 devices. I think this might be related to versions of things in containers but I have no idea. Another oddity is that the snap application defaults to 48 kHz; running the release binary directly defaults to 44.1 kHz. In my test app I always request 44.1 kHz so the change in defaults did not affect the playback.

In case it's helpful, here is my snapcraft.yaml:

name: portaudiotest
base: core22
version: '0.1'
summary: Test of PortAudioSharp2 from CSharp
description: |
  This is a test of a bug related to PortAudioSharp2.

grade: devel
confinement: devmode

apps:
  portaudiotest:
    command: ConsoleApp1
    plugs:
    - alsa

parts:
  portaudiotest:
    plugin: dotnet
    dotnet-build-configuration: Release
    dotnet-self-contained-runtime-identifier: linux-x64
    source: .
    stage-packages:
      - libasound2
      - libjack0
      - libicu70
    build-packages:
      - dotnet-sdk-8.0

layout:
    /usr/share/alsa:
        bind: $SNAP/usr/share/alsa
    /etc/alsa:
        bind: $SNAP/etc/alsa
nwhitehead commented 5 months ago

My conclusion after the snap experiments is that PortAudioSharp2 doesn't have any issue. There are some hurdles in general to getting ALSA and .NET working in snaps but I think those are outside the scope of this project.

@FossaMalaEnt Are you able to get anything working, perhaps following the snapcraft.yml stuff I used?

FossaMalaEnt commented 5 months ago

I tried but encountered errors with libicu70, which seems to be due to me using Ubuntu 20. Therefore, I'm upgrading to Ubuntu 22 and will retry today after finishing the installation. Meanwhile, I tried building the app in the .AppImage format, and the library works well, so I expect your assumptions to be correct. I will provide an update after also testing the snap.

FossaMalaEnt commented 5 months ago

I noticed that Ubuntu 20 uses libicu66 and Ubuntu 22 uses libicu70. However, this doesn't seem to be related. I tried on the new Ubuntu 22 machine and encountered the same error: Failed to fetch stage packages: Error downloading packages for part 'app': The package 'libicu70' was not found.. during the snapcraft process, is it required?

nwhitehead commented 5 months ago

@FossaMalaEnt For me it was required. My local Ubuntu 23.10 has a version of libicu, it is libicu72. Inside the snapcraft container it needed libicu70. I think which libraries it needs is controlled mostly by the base: core22 part of the snapcraft.yaml. The need for libicuNN is a .NET thing for internationalization. You can turn it off with some configuration, see Microsoft docs:

https://learn.microsoft.com/en-us/dotnet/core/runtime-config/globalization