annotate semiconginev2/audio/platform/linux.nim @ 1224:a3fa15c25026 compiletime-tests

did: cleanup, add audio, change platform-dependent structure
author sam <sam@basx.dev>
date Wed, 17 Jul 2024 22:02:11 +0700
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1224
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
1 # alsa API
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
2 type
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
3 OpenMode*{.size: sizeof(culong).} = enum
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
4 SND_PCM_BLOCK = 0x00000000 # added by semicongine, for clarity
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
5 SND_PCM_NONBLOCK = 0x00000001
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
6 StreamMode* {.size: sizeof(cint).} = enum
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
7 SND_PCM_STREAM_PLAYBACK = 0
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
8 AccessMode*{.size: sizeof(cint).} = enum
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
9 SND_PCM_ACCESS_RW_INTERLEAVED = 3
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
10 PCMFormat*{.size: sizeof(cint).} = enum
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
11 SND_PCM_FORMAT_S16_LE = 2
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
12 snd_pcm_p* = ptr object
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
13 snd_pcm_hw_params_p* = ptr object
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
14 snd_pcm_uframes_t* = culong
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
15 snd_pcm_sframes_t* = clong
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
16 {.pragma: alsafunc, importc, cdecl, dynlib: "libasound.so.2".}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
17 proc snd_pcm_open*(pcm_ref: ptr snd_pcm_p, name: cstring, streamMode: StreamMode, openmode: OpenMode): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
18 proc snd_pcm_close*(pcm: snd_pcm_p): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
19 proc snd_pcm_hw_params_malloc*(hw_params_ptr: ptr snd_pcm_hw_params_p): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
20 proc snd_pcm_hw_params_free*(hw_params: snd_pcm_hw_params_p) {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
21 proc snd_pcm_hw_params_any*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
22 proc snd_pcm_hw_params_set_access*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p, mode: AccessMode): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
23 proc snd_pcm_hw_params_set_format*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p, format: PCMFormat): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
24 proc snd_pcm_hw_params_set_channels*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p, val: cuint): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
25 proc snd_pcm_hw_params_set_buffer_size*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p, size: snd_pcm_uframes_t): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
26 proc snd_pcm_hw_params_set_rate*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p, val: cuint, dir: cint): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
27 proc snd_pcm_hw_params*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
28 proc snd_pcm_writei*(pcm: snd_pcm_p, buffer: pointer, size: snd_pcm_uframes_t): snd_pcm_sframes_t {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
29 proc snd_pcm_recover*(pcm: snd_pcm_p, err: cint, silent: cint): cint {.alsafunc.}
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
30
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
31 template checkAlsaResult(call: untyped) =
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
32 let value = call
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
33 if value < 0:
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
34 raise newException(Exception, "Alsa error: " & astToStr(call) &
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
35 " returned " & $value)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
36
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
37 # required for engine:
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
38
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
39 type
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
40 NativeSoundDevice* = object
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
41 handle: snd_pcm_p
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
42 buffers: seq[ptr SoundData]
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
43
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
44 proc OpenSoundDevice*(sampleRate: uint32, buffers: seq[ptr SoundData]): NativeSoundDevice =
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
45 var hw_params: snd_pcm_hw_params_p = nil
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
46 checkAlsaResult snd_pcm_open(addr result.handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_BLOCK)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
47
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
48 # hw parameters, quiet a bit of hardcoding here
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
49 checkAlsaResult snd_pcm_hw_params_malloc(addr hw_params)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
50 checkAlsaResult snd_pcm_hw_params_any(result.handle, hw_params)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
51 checkAlsaResult snd_pcm_hw_params_set_access(result.handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
52 checkAlsaResult snd_pcm_hw_params_set_format(result.handle, hw_params, SND_PCM_FORMAT_S16_LE)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
53 checkAlsaResult snd_pcm_hw_params_set_rate(result.handle, hw_params, sampleRate, 0)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
54 checkAlsaResult snd_pcm_hw_params_set_channels(result.handle, hw_params, 2)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
55 checkAlsaResult snd_pcm_hw_params_set_buffer_size(result.handle, hw_params, snd_pcm_uframes_t(buffers[0][].len))
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
56 checkAlsaResult snd_pcm_hw_params(result.handle, hw_params)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
57 snd_pcm_hw_params_free(hw_params)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
58 result.buffers = buffers
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
59
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
60 proc WriteSoundData*(soundDevice: NativeSoundDevice, buffer: int) =
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
61 var ret = snd_pcm_writei(soundDevice.handle, addr soundDevice.buffers[buffer][][0], snd_pcm_uframes_t(soundDevice.buffers[buffer][].len))
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
62 if ret < 0:
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
63 checkAlsaResult snd_pcm_recover(soundDevice.handle, cint(ret), 0)
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
64
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
65 proc CloseSoundDevice*(soundDevice: NativeSoundDevice) =
a3fa15c25026 did: cleanup, add audio, change platform-dependent structure
sam <sam@basx.dev>
parents:
diff changeset
66 discard snd_pcm_close(soundDevice.handle)