8 #include <soundio/soundio.h>
10 struct SoundIoOutStream
*outstream
;
11 struct SoundIo
*soundio
;
12 struct SoundIoDevice
*device
;
13 struct SoundIoRingBuffer
*ring_buffer
= NULL
;
15 static int min_int(int a
, int b
) { return (a
< b
) ? a
: b
; }
17 static void write_callback(struct SoundIoOutStream
*outstream
, int frame_count_min
,
18 int frame_count_max
) {
19 struct SoundIoChannelArea
*areas
;
23 char *read_ptr
= soundio_ring_buffer_read_ptr(ring_buffer
);
24 int fill_bytes
= soundio_ring_buffer_fill_count(ring_buffer
);
25 if (outstream
->bytes_per_frame
== 0)
26 die("soundio: outstream->bytes_per_frame is zero.");
27 int fill_count
= fill_bytes
/ outstream
->bytes_per_frame
;
30 "[--->>] frame_count_min: %d , frame_count_max: %d , fill_bytes: %d , fill_count: %d , "
31 "outstream->bytes_per_frame: %d",
32 frame_count_min
, frame_count_max
, fill_bytes
, fill_count
, outstream
->bytes_per_frame
);
34 if (frame_count_min
> fill_count
) {
35 int frame_count
= frame_count_min
;
36 if ((err
= soundio_outstream_begin_write(outstream
, &areas
, &frame_count
))) {
37 debug(0, "[--->>] begin write error: %s", soundio_strerror(err
));
39 for (int frame
= 0; frame
< frame_count
; frame
+= 1) {
40 for (int ch
= 0; ch
< outstream
->layout
.channel_count
; ch
+= 1) {
41 memset(areas
[ch
].ptr
, 0, outstream
->bytes_per_sample
);
42 areas
[ch
].ptr
+= areas
[ch
].step
;
45 if ((err
= soundio_outstream_end_write(outstream
)))
46 debug(0, "[--->>] end write error: %s", soundio_strerror(err
));
50 int read_count
= min_int(frame_count_max
, fill_count
);
51 int frames_left
= read_count
;
53 while (frames_left
> 0) {
54 int frame_count
= frames_left
;
56 if ((err
= soundio_outstream_begin_write(outstream
, &areas
, &frame_count
)))
57 debug(0, "[--->>] begin write error: %s", soundio_strerror(err
));
62 for (int frame
= 0; frame
< frame_count
; frame
+= 1) {
63 for (int ch
= 0; ch
< outstream
->layout
.channel_count
; ch
+= 1) {
64 memcpy(areas
[ch
].ptr
, read_ptr
, outstream
->bytes_per_sample
);
65 areas
[ch
].ptr
+= areas
[ch
].step
;
66 read_ptr
+= outstream
->bytes_per_sample
;
70 if ((err
= soundio_outstream_end_write(outstream
)))
71 debug(0, "[--->>] end write error: %s", soundio_strerror(err
));
73 frames_left
-= frame_count
;
76 debug(3, "[--->>] Wrote: %d", read_count
* outstream
->bytes_per_frame
);
77 soundio_ring_buffer_advance_read_ptr(ring_buffer
, read_count
* outstream
->bytes_per_frame
);
80 static void underflow_callback(__attribute__((unused
)) struct SoundIoOutStream
*outstream
) {
82 debug(0, "underflow %d\n", ++count
);
85 static int init(__attribute__((unused
)) int argc
, __attribute__((unused
)) char **argv
) {
88 config
.audio_backend_buffer_desired_length
= 2.0;
89 config
.audio_backend_latency_offset
= 0;
91 // get settings from settings file
93 // do the "general" audio options. Note, these options are in the "general" stanza!
94 parse_general_audio_options();
96 // get the specific settings
98 soundio
= soundio_create();
100 debug(0, "out of memory\n");
103 if ((err
= soundio_connect_backend(soundio
, SoundIoBackendCoreAudio
))) {
104 debug(0, "error connecting: %s", soundio_strerror(err
));
107 soundio_flush_events(soundio
);
109 int default_out_device_index
= soundio_default_output_device_index(soundio
);
110 if (default_out_device_index
< 0) {
111 debug(0, "no output device found");
115 device
= soundio_get_output_device(soundio
, default_out_device_index
);
117 debug(0, "out of memory");
120 debug(0, "Output device: %s\n", device
->name
);
124 static void deinit(void) {
125 soundio_ring_buffer_destroy(ring_buffer
);
126 soundio_device_unref(device
);
127 soundio_destroy(soundio
);
128 debug(0, "soundio audio deinit\n");
131 static void start(int sample_rate
, int sample_format
) {
134 debug(1, "soundion rate: %d, format: %d", sample_rate
, sample_format
);
136 // soundio_device_sort_channel_layouts(device);
138 outstream
= soundio_outstream_create(device
);
139 outstream
->format
= SoundIoFormatS16NE
;
140 outstream
->sample_rate
= sample_rate
;
141 outstream
->layout
.channel_count
= 2;
142 outstream
->write_callback
= write_callback
;
143 outstream
->underflow_callback
= underflow_callback
;
144 // outstream->software_latency = 0;
146 if ((err
= soundio_outstream_open(outstream
))) {
147 debug(0, "unable to open device: %s", soundio_strerror(err
));
149 if (outstream
->layout_error
)
150 debug(0, "unable to set channel layout: %s\n", soundio_strerror(outstream
->layout_error
));
152 int capacity
= outstream
->sample_rate
* outstream
->bytes_per_frame
;
153 ring_buffer
= soundio_ring_buffer_create(soundio
, capacity
);
155 debug(0, "unable to create ring buffer: out of memory");
156 char *buf
= soundio_ring_buffer_write_ptr(ring_buffer
);
157 memset(buf
, 0, capacity
);
158 soundio_ring_buffer_advance_write_ptr(ring_buffer
, capacity
);
160 if ((err
= soundio_outstream_start(outstream
))) {
161 debug(0, "unable to start outstream: %s", soundio_strerror(err
));
164 debug(1, "libsoundio output started\n");
167 static int play(void *buf
, int samples
, __attribute__((unused
)) int sample_type
,
168 __attribute__((unused
)) uint32_t timestamp
,
169 __attribute__((unused
)) uint64_t playtime
) {
171 int free_bytes
= soundio_ring_buffer_free_count(ring_buffer
);
172 int written_bytes
= 0;
174 int left_bytes
= samples
* outstream
->bytes_per_frame
;
175 char *write_ptr
= soundio_ring_buffer_write_ptr(ring_buffer
);
177 debug(3, "[<<---] samples: %d , size: %d", samples
, left_bytes
);
178 write_bytes
= min_int(left_bytes
, free_bytes
);
179 debug(3, "[<<---] left_bytes: %d, write_bytes: %d, free_bytes: %d\n", left_bytes
, write_bytes
,
183 memcpy(write_ptr
, buf
, write_bytes
);
184 written_bytes
+= write_bytes
;
185 soundio_ring_buffer_advance_write_ptr(ring_buffer
, write_bytes
);
186 debug(3, "[<<---] Written to buffer : %d\n", written_bytes
);
191 static void parameters(audio_parameters
*info
) {
192 info
->minimum_volume_dB
= -30.0;
193 info
->maximum_volume_dB
= 0.0;
194 debug(2, "Parameters\n");
195 debug(2, "Current Volume dB: %f\n", info
->current_volume_dB
);
196 debug(2, "Minimum Volume dB: %d\n", info
->minimum_volume_dB
);
197 debug(2, "Maximum Volume dB: %d\n", info
->maximum_volume_dB
);
200 static void stop(void) {
201 soundio_outstream_destroy(outstream
);
202 soundio_ring_buffer_clear(ring_buffer
);
203 debug(1, "libsoundio output stopped\n");
206 static void flush(void) {
207 soundio_ring_buffer_clear(ring_buffer
);
208 debug(1, "libsoundio output flushed\n");
211 static void help(void) { printf(" There are no options for libsoundio.\n"); }
213 audio_output audio_soundio
= {.name
= "soundio",
226 .parameters
= ¶meters
,