Skip to content

Commit d26f0dd

Browse files
committed
Switch to PortAudio
Switch to PortAudio for cross-platform and cross backend compatibility. Linux v6.7 propose a solution to resolve sound stutter effect. Therefore, upgrade the kernel version as well. It is confirmed that there exists unknown issues in Linux Kernel that user has to adjust the buffer size to more than four times of period size, or the program cannot write PCM frames into guest ALSA stack.
1 parent 3aa76a9 commit d26f0dd

File tree

10 files changed

+328
-188
lines changed

10 files changed

+328
-188
lines changed

.clang-format

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,5 @@ ForEachMacros:
2424
- hlist_for_each_entry
2525
- rb_list_foreach
2626
- rb_list_foreach_safe
27+
StatementAttributeLikeMacros:
28+
- IIF

.gitmodules

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
[submodule "cnfa"]
2-
path = cnfa
3-
url = https://github.com/cntools/cnfa
4-
shallow = true
51
[submodule "mini-gdbstub"]
62
path = mini-gdbstub
73
url = https://github.com/RinHizakura/mini-gdbstub
84
shallow = true
95
[submodule "minislirp"]
106
path = minislirp
117
url = https://github.com/edubart/minislirp
12-
shallow = true
8+
shallow = true
9+
[submodule "portaudio"]
10+
path = portaudio
11+
url = https://github.com/PortAudio/portaudio
12+
shallow = true

Makefile

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ OBJS_EXTRA :=
1414
# command line option
1515
OPTS :=
1616

17-
LDFLAGS := -lm
17+
LDFLAGS :=
1818

1919
# virtio-blk
2020
ENABLE_VIRTIOBLK ?= 1
@@ -56,37 +56,61 @@ endif
5656

5757
# virtio-snd
5858
ENABLE_VIRTIOSND ?= 1
59-
ifneq ($(UNAME_S),$(filter $(UNAME_S),Linux))
59+
ifneq ($(UNAME_S),$(filter $(UNAME_S),Linux Darwin))
6060
ENABLE_VIRTIOSND := 0
6161
endif
6262

63-
# Check ALSA installation
6463
ifeq ($(UNAME_S),Linux)
64+
# Check ALSA installation
6565
ifeq (0, $(call check-alsa))
6666
$(warning No libasound installed. Check libasound in advance.)
6767
ENABLE_VIRTIOSND := 0
6868
endif
6969
endif
70+
ifeq ($(UNAME_S),Darwin)
71+
ifeq (0, $(call check-coreaudio))
72+
$(warning No CoreAudio installed Check AudioToolbox in advance.)
73+
ENABLE_VIRTIOSND := 0
74+
endif
75+
endif
7076
$(call set-feature, VIRTIOSND)
7177
ifeq ($(call has, VIRTIOSND), 1)
7278
OBJS_EXTRA += virtio-snd.o
7379

74-
LDFLAGS += -lasound -lpthread
75-
CFLAGS += -Icnfa
80+
PORTAUDIOLIB := portaudio/lib/.libs/libportaudio.a
81+
LDFLAGS += $(PORTAUDIOLIB)
7682

77-
cnfa/Makefile:
78-
git submodule update --init cnfa
79-
cnfa/os_generic: cnfa/Makefile
80-
$(MAKE) -C $(dir $<) os_generic.h
81-
CNFA_LIB := cnfa/CNFA_sf.h
82-
$(CNFA_LIB): cnfa/Makefile cnfa/os_generic
83-
$(MAKE) -C $(dir $<) CNFA_sf.h
84-
main.o: $(CNFA_LIB)
83+
ifeq ($(UNAME_S),Linux)
84+
LDFLAGS += -lasound -lrt
85+
# Check PulseAudio installation
86+
ifeq (0, $(call check-pa))
87+
LDFLAGS += -lpulse
88+
endif
89+
endif
90+
ifeq ($(UNAME_S),Darwin)
91+
LDFLAGS += -framework CoreServices -framework CoreFoundation -framework AudioUnit -framework AudioToolbox -framework CoreAudio
92+
endif
8593

86-
# suppress warning when compiling CNFA
87-
virtio-snd.o: CFLAGS += -Wno-unused-parameter -Wno-sign-compare
94+
CFLAGS += -Iportaudio/include
95+
# PortAudio requires libm, yet we set -lm in the end of LDFLAGS
96+
# so that the other libraries will be benefited for no need to set
97+
# -lm separately.
98+
LDFLAGS += -lpthread
99+
100+
portaudio/Makefile:
101+
git submodule update --init portaudio
102+
$(PORTAUDIOLIB): portaudio/Makefile
103+
cd $(dir $<) && ./configure
104+
$(MAKE) -C $(dir $<)
105+
main.o: $(PORTAUDIOLIB)
106+
107+
# suppress warning when compiling PortAudio
108+
virtio-snd.o: CFLAGS += -Wno-unused-parameter
88109
endif
89110

111+
# Set libm as the last dependency so that no need to set -lm seperately.
112+
LDFLAGS += -lm
113+
90114
# .DEFAULT_GOAL should be set to all since the very first target is not all
91115
# after git submodule.
92116
.DEFAULT_GOAL := all

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ A minimalist RISC-V system emulator capable of running Linux the kernel and corr
1212
- Three types of I/O support using VirtIO standard:
1313
- virtio-blk acquires disk image from the host.
1414
- virtio-net is mapped as TAP interface.
15-
- virtio-snd uses ALSA for sound operation with the following limitations:
16-
- The emulator will hang if PulseAudio is enabled on host.
17-
- The playback may plays with repeating artifact.
15+
- virtio-snd uses [PortAudio](https://github.com/PortAudio/portaudio) for sound playback on the host with one limitations:
16+
- As some unknown issues in guest Linux OS (confirmed in v6.7 and v6.12), you need
17+
to adjust the buffer size to more than four times of period size, or
18+
the program cannot write the PCM frames into guest OS ALSA stack.
19+
- For instance, the following buffer/period size settings on `aplay` has been tested
20+
with broken and stutter effects yet complete with no any errors: `aplay --buffer-size=32768 --period-size=4096 /usr/share/sounds/alsa/Front_Center.wav`.
1821

1922
## Prerequisites
2023

cnfa

Lines changed: 0 additions & 1 deletion
This file was deleted.

common.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,19 @@ static inline int ilog2(int x)
3434
#else /* unsupported compilers */
3535
#define PACKED(name)
3636
#endif
37+
38+
/* Pattern Matching for C macros.
39+
* https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
40+
*/
41+
42+
/* In Visual Studio, __VA_ARGS__ is treated as a separate parameter. */
43+
#define FIX_VC_BUG(x) x
44+
45+
/* catenate */
46+
#define PRIMITIVE_CAT(a, ...) FIX_VC_BUG(a##__VA_ARGS__)
47+
48+
#define IIF(c) PRIMITIVE_CAT(IIF_, c)
49+
/* run the 2nd parameter */
50+
#define IIF_0(t, ...) __VA_ARGS__
51+
/* run the 1st parameter */
52+
#define IIF_1(t, ...) t

configs/linux.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,7 @@ CONFIG_DUMMY_CONSOLE_ROWS=25
945945
CONFIG_SOUND=y
946946
CONFIG_SND=y
947947
CONFIG_SND_VIRTIO=y
948+
CONFIG_SND_HRTIMER=y
948949

949950
#
950951
# HID support

mk/check-libs.mk

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,41 @@ int main(){\n\
1010
}\n'
1111
endef
1212

13+
# Create a mininal PulseAudio program
14+
define create-pa-prog
15+
echo '\
16+
#include <pulse/mainloop.h>\n\
17+
int main(){\n\
18+
pa_mainloop *m;\n\
19+
return 0;\n\
20+
}\n'
21+
endef
22+
23+
# Create a mininal CoreAudio program
24+
define create-ca-prog
25+
echo '\
26+
#include <CoreAudio/CoreAudio.h>\n\
27+
#include <AudioToolbox/AudioQueue.h>
28+
int main(){\n\
29+
AudioQueueRef queue;\n\
30+
AudioQueueDispose(queue, TRUE);\n\
31+
return 0;\n\
32+
}\n'
33+
endef
34+
1335
# Check ALSA installation
1436
define check-alsa
1537
$(shell $(call create-alsa-prog) | $(CC) -x c -lasound -o /dev/null > /dev/null 2> /dev/null -
1638
&& echo $$?)
1739
endef
40+
41+
# Check PulseAudio installation
42+
define check-pa
43+
$(shell $(call create-pa-prog) | $(CC) -x c -lpulse -o /dev/null - && echo 0 || echo 1)
44+
endef
45+
46+
# Check CoreAudio installation
47+
define check-coreaudio
48+
$(shell $(call create-ca-prog) | $(CC) -x c -framework AudioToolbox -o /dev/null > /dev/null 2> /dev/null -
49+
&& echo $$?)
50+
endef

portaudio

Submodule portaudio added at e97effb

0 commit comments

Comments
 (0)