Skip to content

Commit e99bc3b

Browse files
committed
Initial release
0 parents  commit e99bc3b

37 files changed

+15059
-0
lines changed

.gitignore

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Compiled Object files
2+
*.o
3+
*.obj
4+
5+
# Compiled Dynamic libraries
6+
*.so
7+
*.dylib
8+
*.dll
9+
10+
# Compiled Static libraries
11+
*.a
12+
*.lib
13+
14+
# Executables
15+
*.exe
16+
17+
# DUB
18+
.dub
19+
docs.json
20+
__dummy.html
21+
docs/
22+
23+
# Code coverage
24+
*.lst
25+
26+
build/
27+
dump/
28+
dub.selections.json

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (Expat)
2+
3+
Copyright (c) 2015 Andrew Kelley
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# libsoundio-d
2+
Translation from C to D of [libsoundio](https://github.com/andrewrk/libsoundio).
3+
4+
Libsoundio is a library for cross-platform real-time audio input and output.
5+
6+
It is licensed under the MIT License.
7+
The translation is not affiliated with the original project.
8+
9+
Currently not all backends are translated.
10+
11+
| Backend | Translated | Used for |
12+
|--------------------------------------------------------------------------|-----------------|--------------------------------------------|
13+
| [Jack](https://jackaudio.org) | 🟠 Yes (untested)| See [JACK FAQ](https://jackaudio.org/faq/) |
14+
| [Pulseaudio](https://en.wikipedia.org/wiki/PulseAudio) | ✔️ Yes | Linux (higher-level) |
15+
| [Alsa](https://en.wikipedia.org/wiki/Advanced_Linux_Sound_Architecture) | ✔️ Yes | Linux (lower-level) |
16+
| [WASAPI](https://docs.microsoft.com/en-us/windows/win32/coreaudio/wasapi)| ✔️ Yes | Windows |
17+
| [Core Audio](https://en.wikipedia.org/wiki/Core_Audio) | ❌ No | macOS |
18+
| Dummy | ✔️ Yes | Testing |
19+
20+
### Usage
21+
22+
Add this package as a dependency to your project.
23+
24+
dub.sdl:
25+
```
26+
dependency "libsoundio-d" version="~>1.0.0"
27+
```
28+
29+
dub.json:
30+
```
31+
"dependencies": {
32+
"libsoundio-d": "~>1.0.0"
33+
}
34+
```
35+
36+
And then use it:
37+
```D
38+
import soundio.api;
39+
40+
void main() {
41+
SoundIo* soundio = soundio_create();
42+
soundio_connect(soundio);
43+
// your app
44+
soundio_destroy(soundio);
45+
}
46+
```
47+
48+
The configuration should be automatically selected based on your platform, but you can also choose one explicitly:
49+
- linux
50+
- windows
51+
- dummy
52+
53+
dub.sdl:
54+
```
55+
subConfiguration "libsoundio-d" "dummy"
56+
```
57+
58+
dub.json:
59+
```
60+
"subConfigurations": {
61+
"libsoundio-d": "dummy"
62+
}
63+
```
64+
65+
On Linux, you should have ALSA and PulseAudio installed (which you probably have by default, otherwise look up how to install it).
66+
67+
The following version identifiers are used:
68+
- `SOUNDIO_HAVE_JACK`
69+
- `SOUNDIO_HAVE_PULSEAUDIO`
70+
- `SOUNDIO_HAVE_ALSA`
71+
- `SOUNDIO_HAVE_COREAUDIO`
72+
- `SOUNDIO_HAVE_WASAPI`
73+
74+
**Run the examples**
75+
76+
Assuming your current directory is the root of this repository:
77+
```
78+
dub run libsoundio-d:sine
79+
dub run libsoundio-d:list-devices -- --short
80+
dub run libsoundio-d:microphone -- --latency 0.05
81+
dub run libsoundio-d:record -- output.bin
82+
```
83+
84+
**Run the tests**
85+
```
86+
dub run libsoundio-d:backend-disconnect-recover
87+
dub run libsoundio-d:latency
88+
dub run libsoundio-d:overflow
89+
dub run libsoundio-d:underflow
90+
dub run libsoundio-d:unit-tests
91+
```
92+
93+
### Translation events
94+
95+
The translation is closely converting C-syntax to D-syntax, no attempt to change the style to idiomatic D has been made.
96+
There are a few exceptions where certain constructs had to be changed however.
97+
98+
- ALSA defines certain structs with an unknown size at compile time.
99+
There are specific `alloca` macros that allocate these structs on the stack, and libsoundio uses these.
100+
I translated these with malloc and free variants, because alloca has its own share of problems.
101+
102+
- Libsoundio has certain `static` functions with the same name across backends: both ALSA and Pulse have `probe_device` and `my_flush_events`.
103+
Since D does not have C's notion of `static` functions (even `private` functions emit symbols), this introduces a name clash.
104+
Worse, because DMD emits weak symbols, it gives no multiple definition error, but instead silently calls the wrong function:
105+
The Pulse backend calls `probe_device` from the alsa backend instead of its own.
106+
This is mitigated by making those functions `extern(D)` giving them unique names.
107+
108+
- D does not have C bindings of `stdatomic.h`, so I used equivalent functionality from `core.atomic`.
109+
`core.atomic` has no direct equivalent of 'flag test and set'.
110+
I initially translated as `cas` (compare and swap), but return value needed to be negated.
111+
`atomicFetchAdd` was added in dmd 2.089 and is not supported in LDC as of 1.22, so I used `atomicOp!"+="` instead.
112+
113+
- On Windows `InterlockedIncrement` and `InterlockedDecrement` are not in the shipped import library "Kernel32.lib".
114+
I replaced it with a corresponding `atomicOp!"+="` and `atomicOp!"-="`.
115+
116+
- On 32-bit Windows, 64-bit atomic operations are not supported.
117+
The `SoundIoRingBuffer` uses `ulong` for its read and write offset, even on 32-bit.
118+
I changed these to a `size_t` instead.
119+
120+
- Use of `fprintf(sderr, ...)` on Windows with `extern(C) main` triggers [issue 20532](https://issues.dlang.org/show_bug.cgi?id=20532). A custom `printf_stderr` function was made to work around this.

dub.sdl

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name "libsoundio-d"
2+
description "D translation of libsoundio"
3+
authors "dkorpel"
4+
copyright "Copyright © 2020, dkorpel"
5+
license "MIT"
6+
targetName "libsoundio-d"
7+
targetPath "build"
8+
targetType "library"
9+
10+
buildOptions "betterC"
11+
dflags "-preview=dip1000" "-preview=dip25"
12+
dflags "-preview=fieldwise"
13+
dflags "-preview=markdown"
14+
dflags "-preview=fixAliasThis"
15+
dflags "-preview=intpromote"
16+
dflags "-preview=dtorfields"
17+
dflags "-mixin=build/mixin.d"
18+
19+
sourcePaths // no default sourcepath
20+
sourceFiles "source/soundio/api.d"
21+
sourceFiles "source/soundio/atomics.d"
22+
sourceFiles "source/soundio/channel_layout.d"
23+
sourceFiles "source/soundio/config.d" // enums only
24+
sourceFiles "source/soundio/list.d" // templates only
25+
sourceFiles "source/soundio/dummy.d"
26+
sourceFiles "source/soundio/os.d"
27+
sourceFiles "source/soundio/package.d"
28+
sourceFiles "source/soundio/ring_buffer.d"
29+
sourceFiles "source/soundio/soundio.d"
30+
sourceFiles "source/soundio/soundio_internal.d" // list template instantiations are in here sometimes
31+
sourceFiles "source/soundio/soundio_private.d"
32+
sourceFiles "source/soundio/util.d"
33+
34+
configuration "linux" {
35+
platforms "linux"
36+
37+
libs "asound"
38+
versions "SOUNDIO_HAVE_ALSA"
39+
sourceFiles "source/soundio/alsa.d"
40+
41+
libs "pulse"
42+
versions "SOUNDIO_HAVE_PULSEAUDIO"
43+
sourceFiles "source/soundio/pulseaudio.d"
44+
}
45+
46+
configuration "windows" {
47+
platforms "windows"
48+
versions "SOUNDIO_OS_WINDOWS"
49+
versions "SOUNDIO_HAVE_WASAPI"
50+
sourceFiles "source/soundio/wasapi.d"
51+
sourceFiles "source/soundio/headers/wasapiheader.d"
52+
53+
libs "Ole32" // CoCreateInstance, CoTaskMemFree, PropVariantClear
54+
}
55+
56+
configuration "dummy" {
57+
sourceFiles "source/soundio/dummy.d" // redundant, but config can't be empty
58+
}
59+
60+
configuration "jack" {
61+
versions "SOUNDIO_HAVE_JACK"
62+
sourceFiles "source/soundio/jack.d"
63+
}
64+
65+
// Examples
66+
subPackage {
67+
name "sine"
68+
targetPath "build"
69+
targetType "executable"
70+
sourcePaths
71+
sourceFiles "examples/sio_sine.d"
72+
dependency "libsoundio-d" version="*"
73+
}
74+
75+
subPackage {
76+
name "list-devices"
77+
targetPath "build"
78+
targetType "executable"
79+
sourcePaths
80+
sourceFiles "examples/sio_list_devices.d"
81+
dependency "libsoundio-d" version="*"
82+
}
83+
84+
subPackage {
85+
name "record"
86+
targetPath "build"
87+
targetType "executable"
88+
sourcePaths
89+
sourceFiles "examples/sio_record.d"
90+
dependency "libsoundio-d" version="*"
91+
buildRequirements "allowWarnings" // statements after main-loop not reachable
92+
}
93+
94+
subPackage {
95+
name "microphone"
96+
targetPath "build"
97+
targetType "executable"
98+
sourcePaths
99+
sourceFiles "examples/sio_microphone.d"
100+
dependency "libsoundio-d" version="*"
101+
buildRequirements "allowWarnings" // statement after main-loop not reachable
102+
}
103+
104+
// Tests
105+
subPackage {
106+
name "backend-disconnect-recover"
107+
targetPath "build"
108+
targetType "executable"
109+
sourcePaths
110+
sourceFiles "test/backend_disconnect_recover.d"
111+
dependency "libsoundio-d" version="*"
112+
}
113+
114+
subPackage {
115+
name "latency"
116+
targetPath "build"
117+
targetType "executable"
118+
sourcePaths
119+
sourceFiles "test/latency.d"
120+
dependency "libsoundio-d" version="*"
121+
buildRequirements "allowWarnings" // statement after main-loop not reachable
122+
}
123+
124+
subPackage {
125+
name "overflow"
126+
targetPath "build"
127+
targetType "executable"
128+
sourcePaths
129+
sourceFiles "test/overflow.d"
130+
dependency "libsoundio-d" version="*"
131+
}
132+
133+
subPackage {
134+
name "underflow"
135+
targetPath "build"
136+
targetType "executable"
137+
sourcePaths
138+
sourceFiles "test/underflow.d"
139+
dependency "libsoundio-d" version="*"
140+
}
141+
142+
subPackage {
143+
name "unit-tests"
144+
targetPath "build"
145+
targetType "executable"
146+
sourcePaths
147+
sourceFiles "test/unit_tests.d"
148+
dependency "libsoundio-d" version="*"
149+
}

examples/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
# Examples
3+
4+
These examples are translated from the original C examples, so they are not idiomatic D.
5+
6+
Note that the dub commands below should be executed from the root of the repository, not this examples folder.
7+
8+
### Sine
9+
10+
Plays a simple sine wave sound.
11+
```
12+
dub run libsoundio-d:sine
13+
```
14+
15+
### List devices
16+
17+
Lists available input- and output devices.
18+
19+
Without the `--short` flag, it displays each device's id, which can be passed as an argument to the other examples to select an input/output device.
20+
```
21+
dub run libsoundio-d:list-devices
22+
dub run libsoundio-d:list-devices -- --short
23+
```
24+
25+
### Microphone
26+
27+
Reads from an input device (microphone) and pipe it to an output device (speaker / headphones).
28+
Watch out that your microphone is not too close to the speaker or you might get a feedback loop.
29+
```
30+
dub run libsoundio-d:microphone -- --latency 0.05
31+
```
32+
33+
### Record
34+
35+
Records sound from an input device and saves it as a binary file.
36+
```
37+
dub run libsoundio-d:record -- test.bin
38+
```

0 commit comments

Comments
 (0)