{"id":15650884,"url":"https://github.com/zkat/cl-openal","last_synced_at":"2026-01-08T02:35:22.495Z","repository":{"id":586287,"uuid":"220067","full_name":"zkat/cl-openal","owner":"zkat","description":"Common Lisp bindings for the OpenAL audio library.","archived":false,"fork":false,"pushed_at":"2023-07-09T03:56:37.000Z","size":99,"stargazers_count":35,"open_issues_count":1,"forks_count":13,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-05T02:40:19.293Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://connect.creativelabs.com/openal/default.aspx","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zkat.png","metadata":{"files":{"readme":"README.mkdn","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2009-06-06T06:18:36.000Z","updated_at":"2024-09-10T15:31:37.000Z","dependencies_parsed_at":"2024-10-03T12:37:55.234Z","dependency_job_id":"f387a7b5-dff6-429a-80d8-85e8bdc0a82a","html_url":"https://github.com/zkat/cl-openal","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkat%2Fcl-openal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkat%2Fcl-openal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkat%2Fcl-openal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zkat%2Fcl-openal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zkat","download_url":"https://codeload.github.com/zkat/cl-openal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246262492,"owners_count":20749170,"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":[],"created_at":"2024-10-03T12:36:10.549Z","updated_at":"2026-01-08T02:35:22.453Z","avatar_url":"https://github.com/zkat.png","language":"Common Lisp","funding_links":[],"categories":["Expert Systems"],"sub_categories":[],"readme":"About\n-----\n\ncl-openal is a series of semi-lispy public domain bindings to the OpenAL API. It includes direct\nCFFI bindings, as well as varying levels of lispy wrappings around AL, ALC, and ALUT.\n\nThe translation from the C bindings to lispy bindings is pretty straightforward, and follows\ncl-opengl's example, in spirit.\n\nLoading\n-------\n\ncl-openal depends on CFFI to load. It's split into three separate systems: cl-openal for the basic\nOpenAL bindings, cl-alc for ALC, and cl-alut for ALUT. If you need anything from ALC or ALUT, you'll\nhave to specifically load them.\n\nIn order to use cl-openal and cl-alc, you'll need to have OpenAL installed on your system, or\navailable as a shared library/.dll. Additionally, an implementation of ALUT needs to be available in\norder to use cl-alut (such as freealut).\n\ncl-openal should run on all major platforms, including Linux, the BSDs, OSX, and Windows. It should\nbe usable by any Common Lisp implementation supported by CFFI.\n\nError handling\n--------------\n\n**BREAKING CHANGE NOTICE:** The new error handling API represents a breaking change. It introduces\n`*PROPAGATE-ERRORS*` with the default value of `T`, which means that OpenAL operations which would\npreviously fail silently will now signal `AL-ERROR` in case of an error. This is a better default,\nbut will break well-written code using the old API that expects to do its own error checking using\n`GET-ERROR`. To restore the old behaviour, set `*PROPAGATE-ERRORS*` to `NIL**.\n\n**NOTE:** `AL:GET-ERROR`/`AL:CLEAR-ERROR` are distinct from `ALUT:GET-ERROR`/`ALUT:CLEAR-ERROR`,\nbecause the error handling in ALUT differs from error handling in OpenAL/ALC. Similarly, the\ncondition reported for OpenAL/ALC errors is `AL-ERROR`, whereas for ALUT it's `ALUT-ERROR`. In\nprevious versions, these symbols were accidentally merged. Code relying on the old behaviour will\nneed to be updated (or converted to use automatic error checking, see below).\n\nBy default, cl-openal will call `alGetError()`/`alutGetError` after every C operation and signal any\nerrors via the `AL-ERROR`/`ALUT-ERROR` conditions. The specific error code be retrieved via\n`(AL:ERRCODE CONDITION)`.\n\nPrevious versions of cl-openal did not have any provision for automatic error detection, and only\nprovided `GET-ERROR` as a very thin wrapper around `alGetError()`. This not only requires user code to\ndo its own error check after every operation, which is tedious and error-prone, but makes some\noperations inherently unsafe, as certain wrappers perform foreign memory accesses immediately after\ncalling the underlying OpenAL functions, without any opportunity for the user to check for errors\nand abort. This means memory corruption is highly likely in those instances. This issue has been\nfixed, and even if `*PROPAGATE-ERRORS*` is `NIL`, all wrappers exported by packages `AL`, `ALC` and\n`ALUT` will now abort if any underlying C operations signals an error. In this case, the wrapper\nfunction will return `NIL`.\n\nIf for some reason you need to use one of the low-level bindings in the `%AL` or `%ALC` packages,\nthe macro `AL:DEFUN-AL` should be use instead of regular `DEFUN`. It automates clearing the error\nstate at the beginning of the function, and the checking at the end, and exposes a local macro\ncalled `CHECKPOINT`, which should be inserted after every low-level operation, if it's not the last\noperation in the function definition. It will also ensure that `*PROPAGATE-ERRORS*` is respected.\n\nIf you need to interact with the low-level bindings in `%ALUT`, a similar macro called `DEFUN-ALUT`\nis provided. It also automates error clearing and handling, but because the ALUT error reporting is\ndifferent, it's simpler to use: there's no need to call `(CHECKPOINT)`, all CFFI calls are checked\nautomatically.\n\nThread safety\n-------------\n\nUnfortunately, the OpenAL specification is incomplete when it comes to thread safety. Although\nOpenAL contexts are specified to be thread safe, and a single OpenAL operation is atomic, the\nspecification does not specify enough details to allow safe sharing of contexts between multiple\nthreads. In particular, error handling through `alGetError()` is inherently not thread-safe, and if\nmultiple threads perform operations on a single context simultaneously, they will have no way to\ntell whose operation caused the error being reported.\n\ncl-openal on its part is also not thread-safe in its error handling. If `*PROPAGATE-ERRORS*` is\n`NIL`, the mechanism uses the value of a special variable to store and report errors. Because\nspecial variable bindings are not visible across threads, retrieving the last error *will* break if\ndone from multiple threads.\n\nFor these reasons, **multiple threads should never access a single OpenAL context at the same\ntime. Doing so is inherently unsafe and cannot be done without introducing race conditions.**\n\nSupport\n-------\n\nIf you have any questions, you may contact me at \u003ckzm@sykosomatic.org\u003e. Patches or similar\nalways welcome!\n\nExtra Notes\n-----------\n\nThe OpenAL Programming Guide says that buffers can not be destroyed while they are queued. Sources,\non the other hand, can be destroyed while buffers are queued on them.\n\nFor this reason it's probably a good idea to do:\n\n    (with-buffers ...\n      (with-sources ...\n        (queueing code)))\n\ninstead of\n\n    (with-sources ...\n      (with-buffers ...\n        (queueing code)))\n\nSame goes for WITH-SOURCES which you want to wrap in WITH-CONTEXT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzkat%2Fcl-openal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzkat%2Fcl-openal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzkat%2Fcl-openal/lists"}