{"id":13439747,"url":"https://github.com/i-rinat/apulse","last_synced_at":"2025-04-04T08:09:40.743Z","repository":{"id":20750259,"uuid":"24034726","full_name":"i-rinat/apulse","owner":"i-rinat","description":"PulseAudio emulation for ALSA","archived":false,"fork":false,"pushed_at":"2024-05-11T19:53:16.000Z","size":344,"stargazers_count":616,"open_issues_count":54,"forks_count":35,"subscribers_count":42,"default_branch":"master","last_synced_at":"2025-03-28T07:08:28.159Z","etag":null,"topics":["alsa","c","linux","pulseaudio","pulseaudio-emulation","sound"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/i-rinat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.MIT","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-09-14T22:11:02.000Z","updated_at":"2025-03-13T15:45:08.000Z","dependencies_parsed_at":"2024-05-11T20:45:10.285Z","dependency_job_id":null,"html_url":"https://github.com/i-rinat/apulse","commit_stats":{"total_commits":167,"total_committers":9,"mean_commits":"18.555555555555557","dds":0.05988023952095811,"last_synced_commit":"6c4ce36bd02189fe4fadd09ac074a4d0d1045d32"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/i-rinat%2Fapulse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/i-rinat%2Fapulse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/i-rinat%2Fapulse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/i-rinat%2Fapulse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/i-rinat","download_url":"https://codeload.github.com/i-rinat/apulse/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247142074,"owners_count":20890653,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alsa","c","linux","pulseaudio","pulseaudio-emulation","sound"],"created_at":"2024-07-31T03:01:16.760Z","updated_at":"2025-04-04T08:09:40.726Z","avatar_url":"https://github.com/i-rinat.png","language":"C","readme":"About\n=====\n\nPulseAudio emulation for ALSA.\n\nThe program provides an alternative partial implementation of the PulseAudio\nAPI. It consists of a loader script and a number of shared libraries with the\nsame names as from original PulseAudio, so applications could dynamically load\nthem and think they are talking to PulseAudio. Internally, no separate sound\nmixing daemon is used. Instead, apulse relies on ALSA's `dmix`, `dsnoop`, and\n`plug` plugins to handle multiple sound sources and capture streams running at\nthe same time. `dmix` plugin muxes multiple playback streams; `dsnoop` plugin\nallow multiple applications to capture from a single microphone; and `plug`\nplugin transparently converts audio between various sample formats, sample rates\nand channel numbers. For more than a decade now, ALSA comes with these plugins\nenabled and configured by default.\n\n`apulse` wasn't designed to be a drop-in replacement of PulseAudio. It's\npointless, since that will be just reimplementation of original PulseAudio, with\nthe same client-daemon architecture, required by the complete feature\nset. Instead, only parts of the API that are crucial to specific applications\nare implemented. That's why there is a loader script, named `apulse`. It updates\nvalue of `LD_LIBRARY_PATH` environment variable to point also to the directory\nwhere apulse's libraries are installed, making them available to the\napplication.\n\nName comes from names of both ALSA and PulseAudio. As `aoss` was a compatibility\nlayer between OSS programs and ALSA, `apulse` was designed to be compatibility\nlayer between PulseAudio applications and ALSA.\n\n\nInstall\n=======\n\nYou need ALSA libraries and GLib installed. On Debian-based distributions, they\nare in packages `libasound2-dev` and `libglib2.0-dev`.\n\nTo build and install, run in source directory:\n\n```\n$ mkdir build \u0026\u0026 cd build\n$ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release ..\n$ make\n# make install\n```\n\nThat will create directory named `build`, and build there. It's possible to\ninstall just by running `make install` as `root`, as shown above. But you won't\nbe able to uninstall installed files. That's why it's recommended to wrap files\ninto a package. Use `checkinstall`, or some alternative.\n\nIf you want 32-bit binaries on 64-bit machine (for example, for Skype), use:\n```\n$ mkdir build \u0026\u0026 cd build\n$ CFLAGS=-m32 cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release ..\n$ make\n# make install\n```\n\nRecent GLib versions use different `.pc` files for `i386` and `amd64`. To help\n`pkg-config` find 32-bit versions, use `PKG_CONFIG_PATH` variable.  So, on\nDebian it will be something like:\n\n```\n$ PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig CFLAGS=-m32 cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release ..\n```\n\nThere is a way to configure where apulse libraries will be installed, via\n`APULSEPATH` cmake variable. For example, if you want to install libraries\ninto default path, `/usr/lib`, use\n```\ncmake -DAPULSEPATH=/usr/lib -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release ..\n```\n\nIf libraries are installed to a regular library path, you don't need run applications\nthrough `apulse` wrapper.\n\n\nUsage\n=====\n\n```\n$ apulse \u003cprogram-name\u003e [program-parameters]\n```\n\nEnvironment variables `APULSE_CAPTURE_DEVICE` and `APULSE_PLAYBACK_DEVICE` can be used\nto configure capture and playback devices. Try `hw:0,0`, `plughw:0,0` and the like.\nRefer to the ALSA user guide for a full list of device names.\n\nSystem directory versus separate directory installations\n--------------------------------------------------------\n\nBy default, libraries from `apulse` are installed into a separate directory, in\norder to hide them from all applications.\n\nMost applications in the wild, that support both PulseAudio and ALSA, try to\nautodetect which sound system is used. First, applications try to start with\nPulseAudio. Original client libraries fail early if no PulseAudio daemon is\nrunning or can be started. Then they switch to ALSA. Decision is made once, at\nthe beginning. It works fine with PulseAudio, but doesn't work with\n`apulse`. Latter has no daemons, it happily says that everything is fine, and\nit's capable of playing audio. Applications then try to call more functions, and\neventually touch unimplemented parts, often with crashes. So, libraries are\nhidden, and become visible only when a program is called through `apulse`\nwrapper script.\n\nIt's possible to install apulse libraries to `/usr/lib`. Wrapper script won't\nbe required, but then all applications will try to use PulseAudio API, despite\nthey can use ALSA.\n\nPer-app RPATH trick\n-------------------\n\nThere is the RPATH property of ELF executable format, which is used to specify\npaths to search for dynamic libraries. It's like LD_LIBRARY_PATH variable, but\nper-executable. Since all that `apulse` launcher script does is setting\nLD_LIBRARY_PATH value before launching an application, it's possible to bake\npaths to apulse libraries into target executable itself. And so to launch it\nas usual, without helper script.\n\nFor example, for Firefox it would be:\n\n```\n# patchelf --set-rpath /usr/lib/apulse /usr/lib/firefox/libxul.so\n```\n\nFor some reason, it doesn't work if RPATH is set for `/usr/lib/firefox/firefox`\nitself, so some experiments are required to make it work.\n\nKnown issues\n============\n\nNot implemented functions, application crashes\n----------------------------------------------\n\nLarge portion of PulseAudio API is not implemented. There are functions that do\nnothing and return some arbitraty values. Often, if application tries to call\nsomething not implemented, it crashes while trying to dereference a NULL\npointer.  By default, tracing level is set to `0`, which means no messages are\nprinted to standard output. It's possible to increase that value to `1`, which\nshows unimplemented function calls, or to `2`, which shows all function calls.\n\nTo change level, use `WITH_TRACE` parameter when calling `cmake`. Something like\n`cmake -DWITH_TRACE=1 ..`\n\nBuilding apulse with trace level 1 won't fix issues, but will at least help to\nidentify if crashes are caused by not implemented functions.\n\nGeneric errors in do_connect_pcm\n--------------------------------\n\nApulse acts as a generic ALSA client. It tries to open audio device, and\nsometimes fails.  At its core, apulse does neither audio mixing nor\nresampling. Instead, it relies on `plug`, `dmix`, and `dsnoop` ALSA plugins,\nwhich are usually enabled by default. These plugins handle multiple audio\nsources, performing resampling and mixing transparently. For years now ALSA\ncomes with those plugins enabled. Audio just works without configuring\nanything. But not everybody use default settings.\n\nOn custom configurations apulse may fail to output and/or capture audio. There\ncould be no sound at all, or just a single audio stream playing at a time.  It's\nalso possible that adapters with hardware mixers, which capable of playing\nmultiple streams, may still be unable to handle multiple capture\nstreams. Depending on hardware, you may still need either `dmix` or `dsnoop`\nplugins. Or both.\n\nIn other words, for apulse to work, your setup should be capable of playing and\ncapturing multiple streams simultaneously.\n\nAccess errors in do_connect_pcm\n-------------------------------\n\nIf other applications output sound just fine, it's possible that application you\nare using restricts itself.\n\nFor example, Firefox now have a sandbox, that blocks file access. It has\npredefined list of allowed paths, but ALSA devices are not included by\ndefault. Fortunately, it's possible to add those path by hand. Add \"/dev/snd/\"\nto \"security.sandbox.content.write_path_whitelist\" parameter in\n`about:config`. Note that trailing slash in \"/dev/snd/\" is required.\n\n\nFirefox 58 tabs crashing when trying to play audio\n--------------------------------------------------\n\nFirefox 58 (Nightly) tightened its sandbox a bit more. Now `ioctl()` calls are\nforbidden too, but are used by ALSA libraries. That causes sandbox violation\nwith subsequent process termination. Exception can be added by setting parameter\n`security.sandbox.content.syscall_whitelist` in `about:config`. That field\naccepts a comma separated list of system call numbers. Add there `16` for\nx86-64, or `54` for x86 or ARM.\n\nFirefox 60 tighened its content sandbox more, but at the same time moved audio\naccesses from content processes to the main process. From Firefox 60 onwards no\nchanges to the sandbox settings are necessary.\n\nLicense\n=======\n\nSource code is distributed under the terms of the MIT License. See LICENSE.MIT for full text.\n\nThird party code\n================\n\n`/3rdparty/pulseaudio-headers` contains part of PulseAudio project and is distributed\nunder LGPLv2.1+ terms. See content of the files for details.\n","funding_links":[],"categories":["C"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fi-rinat%2Fapulse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fi-rinat%2Fapulse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fi-rinat%2Fapulse/lists"}