From 83908c64ee1195244acac1f64e2fb2f57cf99e58 Mon Sep 17 00:00:00 2001 From: IllusionMan1212 Date: Sat, 28 Jun 2025 10:40:05 +0200 Subject: [PATCH] initial commit --- LICENSE | 21 +++++ alsa.odin | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 LICENSE create mode 100644 alsa.odin diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..45423b3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 IllusionMan1212 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/alsa.odin b/alsa.odin new file mode 100644 index 0000000..28547e6 --- /dev/null +++ b/alsa.odin @@ -0,0 +1,242 @@ +#+build linux +package alsa + +import "core:c" + +foreign import alsa "system:asound" + +pcm_open_flags :: enum i32 { + BLOCK = 0x0, + NONBLOCK = 0x00000001, + ASYNC = 0x00000002, +} + +/** PCM stream (direction) */ +pcm_stream_t :: enum i32 { + /** Playback stream */ + PLAYBACK = 0, + /** Capture stream */ + CAPTURE, + LAST = CAPTURE, +} + +/** PCM sample format */ +pcm_format_t :: enum { + /** Unknown */ + UNKNOWN = -1, + /** Signed 8 bit */ + S8 = 0, + /** Unsigned 8 bit */ + U8, + /** Signed 16 bit Little Endian */ + S16_LE, + /** Signed 16 bit Big Endian */ + S16_BE, + /** Unsigned 16 bit Little Endian */ + U16_LE, + /** Unsigned 16 bit Big Endian */ + U16_BE, + /** Signed 24 bit Little Endian using low three bytes in 32-bit word */ + S24_LE, + /** Signed 24 bit Big Endian using low three bytes in 32-bit word */ + S24_BE, + /** Unsigned 24 bit Little Endian using low three bytes in 32-bit word */ + U24_LE, + /** Unsigned 24 bit Big Endian using low three bytes in 32-bit word */ + U24_BE, + /** Signed 32 bit Little Endian */ + S32_LE, + /** Signed 32 bit Big Endian */ + S32_BE, + /** Unsigned 32 bit Little Endian */ + U32_LE, + /** Unsigned 32 bit Big Endian */ + U32_BE, + /** Float 32 bit Little Endian, Range -1.0 to 1.0 */ + FLOAT_LE, + /** Float 32 bit Big Endian, Range -1.0 to 1.0 */ + FLOAT_BE, + /** Float 64 bit Little Endian, Range -1.0 to 1.0 */ + FLOAT64_LE, + /** Float 64 bit Big Endian, Range -1.0 to 1.0 */ + FLOAT64_BE, + /** IEC-958 Little Endian */ + IEC958_SUBFRAME_LE, + /** IEC-958 Big Endian */ + IEC958_SUBFRAME_BE, + /** Mu-Law */ + MU_LAW, + /** A-Law */ + A_LAW, + /** Ima-ADPCM */ + IMA_ADPCM, + /** MPEG */ + MPEG, + /** GSM */ + GSM, + /** Signed 20bit Little Endian in 4bytes format, LSB justified */ + S20_LE, + /** Signed 20bit Big Endian in 4bytes format, LSB justified */ + S20_BE, + /** Unsigned 20bit Little Endian in 4bytes format, LSB justified */ + U20_LE, + /** Unsigned 20bit Big Endian in 4bytes format, LSB justified */ + U20_BE, + /** Special */ + SPECIAL = 31, + /** Signed 24bit Little Endian in 3bytes format */ + S24_3LE = 32, + /** Signed 24bit Big Endian in 3bytes format */ + S24_3BE, + /** Unsigned 24bit Little Endian in 3bytes format */ + U24_3LE, + /** Unsigned 24bit Big Endian in 3bytes format */ + U24_3BE, + /** Signed 20bit Little Endian in 3bytes format */ + S20_3LE, + /** Signed 20bit Big Endian in 3bytes format */ + S20_3BE, + /** Unsigned 20bit Little Endian in 3bytes format */ + U20_3LE, + /** Unsigned 20bit Big Endian in 3bytes format */ + U20_3BE, + /** Signed 18bit Little Endian in 3bytes format */ + S18_3LE, + /** Signed 18bit Big Endian in 3bytes format */ + S18_3BE, + /** Unsigned 18bit Little Endian in 3bytes format */ + U18_3LE, + /** Unsigned 18bit Big Endian in 3bytes format */ + U18_3BE, + /* G.723 (ADPCM) 24 kbit/s, 8 samples in 3 bytes */ + G723_24, + /* G.723 (ADPCM) 24 kbit/s, 1 sample in 1 byte */ + G723_24_1B, + /* G.723 (ADPCM) 40 kbit/s, 8 samples in 3 bytes */ + G723_40, + /* G.723 (ADPCM) 40 kbit/s, 1 sample in 1 byte */ + G723_40_1B, + /* Direct Stream Digital (DSD) in 1-byte samples (x8) */ + DSD_U8, + /* Direct Stream Digital (DSD) in 2-byte samples (x16) */ + DSD_U16_LE, + /* Direct Stream Digital (DSD) in 4-byte samples (x32) */ + DSD_U32_LE, + /* Direct Stream Digital (DSD) in 2-byte samples (x16) */ + DSD_U16_BE, + /* Direct Stream Digital (DSD) in 4-byte samples (x32) */ + DSD_U32_BE, + LAST = DSD_U32_BE, + + /** Signed 16 bit CPU endian */ + S16 = S16_BE when ODIN_ENDIAN == .Big else S16_LE, + /** Unsigned 16 bit CPU endian */ + U16 = U16_BE when ODIN_ENDIAN == .Big else U16_LE, + /** Signed 24 bit CPU endian */ + S24 = S24_BE when ODIN_ENDIAN == .Big else S32_LE, + /** Unsigned 24 bit CPU endian */ + U24 = U24_BE when ODIN_ENDIAN == .Big else U24_LE, + /** Signed 32 bit CPU endian */ + S32 = S32_BE when ODIN_ENDIAN == .Big else S32_LE, + /** Unsigned 32 bit CPU endian */ + U32 = U32_BE when ODIN_ENDIAN == .Big else U32_LE, + /** Float 32 bit CPU endian */ + FLOAT = FLOAT_BE when ODIN_ENDIAN == .Big else FLOAT_LE, + /** Float 64 bit CPU endian */ + FLOAT64 = FLOAT64_BE when ODIN_ENDIAN == .Big else FLOAT64_LE, + /** IEC-958 CPU Endian */ + IEC958_SUBFRAME = IEC958_SUBFRAME_BE when ODIN_ENDIAN == .Big else IEC958_SUBFRAME_LE, + /** Signed 20bit in 4bytes format, LSB justified, CPU Endian */ + S20 = S20_BE when ODIN_ENDIAN == .Big else S20_LE, + /** Unsigned 20bit in 4bytes format, LSB justified, CPU Endian */ + U20 = U20_BE when ODIN_ENDIAN == .Big else U20_LE, +} + +/** PCM access type */ +pcm_access_t :: enum { + /** mmap access with simple interleaved channels */ + MMAP_INTERLEAVED = 0, + /** mmap access with simple non interleaved channels */ + MMAP_NONINTERLEAVED, + /** mmap access with complex placement */ + MMAP_COMPLEX, + /** snd_pcm_readi/snd_pcm_writei access */ + RW_INTERLEAVED, + /** snd_pcm_readn/snd_pcm_writen access */ + RW_NONINTERLEAVED, + LAST = RW_NONINTERLEAVED +} + +/** channel positions */ +pcm_chmap_position :: enum i32 { + UNKNOWN = 0, /**< unspecified */ + NA, /**< N/A, silent */ + MONO, /**< mono stream */ + FL, /**< front left */ + FR, /**< front right */ + RL, /**< rear left */ + RR, /**< rear right */ + FC, /**< front center */ + LFE, /**< LFE */ + SL, /**< side left */ + SR, /**< side right */ + RC, /**< rear center */ + FLC, /**< front left center */ + FRC, /**< front right center */ + RLC, /**< rear left center */ + RRC, /**< rear right center */ + FLW, /**< front left wide */ + FRW, /**< front right wide */ + FLH, /**< front left high */ + FCH, /**< front center high */ + FRH, /**< front right high */ + TC, /**< top center */ + TFL, /**< top front left */ + TFR, /**< top front right */ + TFC, /**< top front center */ + TRL, /**< top rear left */ + TRR, /**< top rear right */ + TRC, /**< top rear center */ + TFLC, /**< top front left center */ + TFRC, /**< top front right center */ + TSL, /**< top side left */ + TSR, /**< top side right */ + LLFE, /**< left LFE */ + RLFE, /**< right LFE */ + BC, /**< bottom center */ + BLC, /**< bottom left center */ + BRC, /**< bottom right center */ + LAST = BRC, +} + +pcm_uframes_t :: c.ulong +pcm_sframes_t :: c.long +pcm_t :: struct{} +pcm_hw_params_t :: struct{} + +pcm_chmap_t :: struct { + // Number of channels + channels: u32, + // Channel position array + pos: [0]u32, +} + +@(link_prefix="snd_") +foreign alsa { + pcm_open :: proc(pcmp: ^^pcm_t, name: cstring, stream: pcm_stream_t, mode: pcm_open_flags) -> i32 --- + strerror :: proc(errnum: i32) -> cstring --- + pcm_set_params :: proc( + pcm: ^pcm_t, + format: pcm_format_t, + access: pcm_access_t, + channels: u32, + rate: u32, + soft_resample: i32, + latency: u32) -> i32 --- + pcm_drain :: proc(pcm: ^pcm_t) -> i32 --- + pcm_close :: proc(pcm: ^pcm_t) -> i32 --- + pcm_writei :: proc(pcm: ^pcm_t, buffer: rawptr, size: pcm_uframes_t) -> pcm_sframes_t --- + pcm_hw_params_set_channels :: proc(pcm: ^pcm_t, params: ^pcm_hw_params_t, val: u32) --- + pcm_chmap_long_name :: proc(val: pcm_chmap_position) -> cstring --- + pcm_get_chmap :: proc(pcm: ^pcm_t) -> ^pcm_chmap_t --- +}