cl-portaudio icon indicating copy to clipboard operation
cl-portaudio copied to clipboard

Not working with SBCL on Mac os

Open anquegi opened this issue 6 years ago • 12 comments

This library is working well using CCL on MacBook Pro with sierra at least the sample echo from here and print-devices the only problem is that you must shadow the symbol portaudio:terminate.

I'm using

CL-USER> (machine-instance)
"MacBook-Pro-de-Antonio.local"
CL-USER> (machine-type)
"X86-64"
CL-USER> (machine-version)
"Intel(R) Core(TM) i7-5557U CPU @ 3.10GHz"
CL-USER> (software-type)
"Darwin"
CL-USER> (software-version)
"16.7.0"

and

brew info portaudio                                                                                                                                                                                                 
portaudio: stable 19.6.0 (bottled), HEAD
Cross-platform library for audio I/O
http://www.portaudio.com
/usr/local/Cellar/portaudio/19.6.0 (33 files, 452.7KB) *
  Poured from bottle on 2017-07-28 at 15:43:55
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/portaudio.rb
==> Dependencies
Build: pkg-config ✔

But working with SBCL (print-devices) never returns

CL-USER> (print-devices) PortAudio version number = 1246720 PortAudio version text = PortAudio V19.6.0-devel, revision 396fe4b6699ae929d3a685b3ef8a7e97396139a4 Number of devices = 3 ---------------------- device 0 [ Default Input ] Name = Built-in Microphone Host API = Core Audio Max inputs = 2, Max outputs = 0 Default low input latency = 0.0029 Default low output latency = 0.0100 Default high input latency = 0.0247 Default high output latency = 0.1000 Default sample rate = 44100.0000 Supported standard sample rates for half-duplex float 32 bit 2 channel input = <===== Hangs here forever

Then when I stop the process I get this stack:

Interrupt from Emacs
   [Condition of type SIMPLE-ERROR]

Restarts:
 0: [CONTINUE] Continue from break.
 1: [*ABORT] Return to SLIME's top level.
 2: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {10030A8003}>)

Backtrace:
  0: ("bogus stack frame")
  1: ("foreign function: _ZN10Resampler215ConstructorBodyEddidd28ResamplerSpecificationMethodid")
  2: ("foreign function: _ZN17Resampler2WrapperC2EP19SampleRateConverteriddiiidjb")
  3: ("foreign function: _ZN17Resampler2WrapperC1EP19SampleRateConverteriddiiidjb")
  4: ("foreign function: _ZN19SampleRateConverter16ReplaceResamplerEv")
  5: ("foreign function: _ZN19SampleRateConverterC2ERK14StreamDescPairRK18ChainBuildSettings")
  6: ("foreign function: _ZN19PCMConverterFactory6AddSRCER14StreamDescPairRK18ChainBuildSettingsRNSt3__16vectorIP22BufferedAudioConverterNS5_9allocatorIS8_EEEE")
  7: ("foreign function: _ZN19PCMConverterFactory27BuildConverterChainSRCNoMixERK14StreamDescPairRK17ChannelLayoutPairRK18ChainBuildSettingsRNSt3__16vectorIP22BufferedAudioConverterNS9_9allocatorISC_EEEE")
  8: ("foreign function: _ZN19PCMConverterFactory22BuildSubConverterChainERK14StreamDescPairRK17ChannelLayoutPairRK18ChainBuildSettingsRNSt3__16vectorIP22BufferedAudioConverterNS9_9allocatorISC_EEEE")
  9: ("foreign function: _ZN19PCMConverterFactory19BuildConverterChainERK14StreamDescPairRK18ChainBuildSettingsP19AudioConverterChainPS_")
 10: ("foreign function: _ZN17ConverterRegistry15CreateConverterERK14StreamDescPairPP19AudioConverterChainjPK21AudioClassDescription")
 11: ("foreign function: _AudioConverterNewInternal")
 12: ("foreign function: OpenAndSetupOneAudioUnit")
 13: ("foreign function: OpenStream")
 14: ("foreign function: IsFormatSupported")
 15: ("foreign function: Pa_IsFormatSupported")
 16: (PORTAUDIO::%IS-FORMAT-SUPPORTED #<STREAM-PARAMETERS {1004C6E153}> NIL 8000.0d0)
 17: (PORTAUDIO::IS-FORMAT-SUPPORTED #<STREAM-PARAMETERS {1004C6E153}> NIL 8000.0d0)
 18: (PORTAUDIO::PRINT-SUPPORTED-STANDARD-SAMPLE-RATES #<STREAM-PARAMETERS {1004C6E153}> NIL)
 19: (PRINT-DEVICES)
 20: (SB-INT:SIMPLE-EVAL-IN-LEXENV (PRINT-DEVICES) #<NULL-LEXENV>)
 21: (EVAL (PRINT-DEVICES))
 22: (SWANK::%EVAL-REGION "(print-devices) ..)
 23: ((LAMBDA NIL :IN SWANK::%LISTENER-EVAL))
 24: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {1004C6DD4B}>)
 25: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {1004C6DD2B}>)
 26: (SWANK::%LISTENER-EVAL "(print-devices) ..)
 27: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(print-devices) ..)
 28: (EVAL (SWANK-REPL:LISTENER-EVAL "(print-devices) ..)
 29: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(print-devices) ..)
 30: (SWANK::PROCESS-REQUESTS NIL)
 31: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
 32: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
 33: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {10030A7FEB}>)
 34: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/toni/.roswell/lisp/slime/2017.02.27/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {..
 35: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-INPUT* . #1=#<SWANK/GRAY::SLIME-INPUT-STREAM {1002FB67E3}>) (*STANDARD-OUTPUT* . #2=#<SWANK/GRAY::SLIME-OUTPUT-STREAM {100308F6C3}>) (*TRACE-OUTPUT* . #2#) (*ERR..
 36: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {1002F587F3}> NIL)
 37: ((FLET #:WITHOUT-INTERRUPTS-BODY-1148 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 38: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 39: ((FLET #:WITHOUT-INTERRUPTS-BODY-358 :IN SB-THREAD::CALL-WITH-MUTEX))
 40: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {724DCFB}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
 41: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {10030A8003}> NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::SPAWN-REPL-THREAD) {10030A7F6B}> (#<SB-THREAD:THREAD "re..
 42: ("foreign function: call_into_lisp")
 43: ("foreign function: new_thread_trampoline")
 44: ("foreign function: _pthread_body")
 45: ("foreign function: _pthread_body")
 46: ("foreign function: thread_start")

and when I try to run the example:

(use-package :portaudio)


 (defconstant +frames-per-buffer+ 1024)
 (defconstant +sample-rate+ 44100d0)
 (defconstant +seconds+ 15)
 (defconstant +sample-format+ :float)
 (defconstant +num-channels+ 2)


 (defun test-read-write-converted-echo ()
  "Record input into an array; Separate array to channels; Merge channels into array; Play last array." 
  (with-audio
    (format t "~%=== Wire on. Will run ~D seconds . ===~%" +seconds+) 
    (with-default-audio-stream (astream +num-channels+ +num-channels+ :sample-format +sample-format+ :sample-rate +sample-rate+ :frames-per-buffer +frames-per-buffer+) 
      (dotimes (i (round (/ (* +seconds+ +sample-rate+) +frames-per-buffer+)))
         (write-stream astream
                                    (merge-channels-into-array astream
                                                               (separate-array-to-channels astream
                                                                                           (read-stream astream))))))))

I get this error depending only the first time, if I execute print-devices or this again it only hangs

arithmetic error DIVISION-BY-ZERO signalled
   [Condition of type DIVISION-BY-ZERO]

Restarts:
 0: [*ABORT] Return to SLIME's top level.
 1: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {10030D0003}>)

Backtrace:
  0: ("bogus stack frame")
  1: ("foreign function: _ZN17SincKernelFactory19ReferenceSincKernelEiidd")
  2: ("foreign function: _ZN10Resampler215ConstructorBodyEddidd28ResamplerSpecificationMethodid")
  3: ("foreign function: _ZN17Resampler2WrapperC2EP19SampleRateConverteriddiiidjb")
  4: ("foreign function: _ZN17Resampler2WrapperC1EP19SampleRateConverteriddiiidjb")
  5: ("foreign function: _ZN19SampleRateConverter16ReplaceResamplerEv")
  6: ("foreign function: _ZN19SampleRateConverterC2ERK14StreamDescPairRK18ChainBuildSettings")
  7: ("foreign function: _ZN19PCMConverterFactory6AddSRCER14StreamDescPairRK18ChainBuildSettingsRNSt3__16vectorIP22BufferedAudioConverterNS5_9allocatorIS8_EEEE")
  8: ("foreign function: _ZN19PCMConverterFactory27BuildConverterChainSRCNoMixERK14StreamDescPairRK17ChannelLayoutPairRK18ChainBuildSettingsRNSt3__16vectorIP22BufferedAudioConverterNS9_9allocatorISC_EEEE")
  9: ("foreign function: _ZN19PCMConverterFactory22BuildSubConverterChainERK14StreamDescPairRK17ChannelLayoutPairRK18ChainBuildSettingsRNSt3__16vectorIP22BufferedAudioConverterNS9_9allocatorISC_EEEE")
 10: ("foreign function: _ZN19PCMConverterFactory19BuildConverterChainERK14StreamDescPairRK18ChainBuildSettingsP19AudioConverterChainPS_")
 11: ("foreign function: _ZN17ConverterRegistry15CreateConverterERK14StreamDescPairPP19AudioConverterChainjPK21AudioClassDescription")
 12: ("foreign function: _AudioConverterNewInternal")
 13: ("foreign function: _ZN23AUInputFormatConverter210SetFormatsERK27AudioStreamBasicDescriptionS2_")
 14: ("foreign function: _ZN15AUConverterBase14SetupConverterEjb")
 15: ("foreign function: _ZN5AUHAL14SetupConverterEjb")
 16: ("foreign function: _ZN15AUConverterBase18SetupAllConvertersEbj")
 17: ("foreign function: _ZN5AUHAL10InitializeEv")
 18: ("foreign function: _ZN6AUBase12DoInitializeEv")
 19: ("foreign function: _ZN6AUBase22ComponentEntryDispatchEP19ComponentParametersPS_")
 20: ("foreign function: _ZN19ComponentEntryPointI5AUHALE8DispatchEP19ComponentParametersPS0_")
 21: ("foreign function: AudioUnitInitialize")
 22: ("foreign function: OpenAndSetupOneAudioUnit")
 23: ("foreign function: OpenStream")
 24: ("foreign function: Pa_OpenStream")
 25: ("foreign function: Pa_OpenDefaultStream")
 26: (PORTAUDIO::%OPEN-DEFAULT-STREAM #.(SB-SYS:INT-SAP #X0744DFF0) 2 2 1 44100.0d0 1024 #.(SB-SYS:INT-SAP #X00000000) #.(SB-SYS:INT-SAP #X00000000))
 27: (OPEN-DEFAULT-STREAM 2 2 :FLOAT 44100.0d0 1024)
 28: (TEST-READ-WRITE-CONVERTED-ECHO)
 29: (SB-INT:SIMPLE-EVAL-IN-LEXENV (TEST-READ-WRITE-CONVERTED-ECHO) #<NULL-LEXENV>)
 30: (EVAL (TEST-READ-WRITE-CONVERTED-ECHO))
 31: (SWANK::%EVAL-REGION "(test-read-write-converted-echo) ..)
 32: ((LAMBDA NIL :IN SWANK::%LISTENER-EVAL))
 33: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {100409FDCB}>)
 34: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {100409FDAB}>)
 35: (SWANK::%LISTENER-EVAL "(test-read-write-converted-echo) ..)
 36: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(test-read-write-converted-echo) ..)
 37: (EVAL (SWANK-REPL:LISTENER-EVAL "(test-read-write-converted-echo) ..)
 38: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(test-read-write-converted-echo) ..)
 39: (SWANK::PROCESS-REQUESTS NIL)
 40: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
 41: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
 42: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {10030CFFEB}>)
 43: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/toni/.roswell/lisp/slime/2017.02.27/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {..
 44: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-INPUT* . #1=#<SWANK/GRAY::SLIME-INPUT-STREAM {1002FE64B3}>) (*STANDARD-OUTPUT* . #2=#<SWANK/GRAY::SLIME-OUTPUT-STREAM {10030B7353}>) (*TRACE-OUTPUT* . #2#) (*ERR..
 45: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {1002F587F3}> NIL)
 46: ((FLET #:WITHOUT-INTERRUPTS-BODY-1148 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 47: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 48: ((FLET #:WITHOUT-INTERRUPTS-BODY-358 :IN SB-THREAD::CALL-WITH-MUTEX))
 49: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {724DCFB}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
 50: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {10030D0003}> NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::SPAWN-REPL-THREAD) {10030CFF6B}> (#<SB-THREAD:THREAD "re..
 51: ("foreign function: call_into_lisp")
 52: ("foreign function: new_thread_trampoline")
 53: ("foreign function: _pthread_body")
 54: ("foreign function: _pthread_body")
 55: ("foreign function: thread_start")

anquegi avatar Jul 28 '17 15:07 anquegi

FWIW this seems to be an issue with OS X/CoreAudio itself, as I've had reports of the same issue appearing in a native implementation for CoreAudio. See shirakumo/harmony#3. It's possible this doesn't crop up elsewhere as other languages/implementations ignore division by zero signals.

Shinmera avatar Nov 25 '17 08:11 Shinmera

I get the same error as @anquegi when running (print-devices) on SBCL 1.4.1 on Mac, but test-read-write-converted-echo does work correctly for me.

It seems like it's having trouble with these checks: https://github.com/filonenko-mikhail/cl-portaudio/blob/master/src/portaudio.lisp#L1055

Maybe those could be optional checks, toggled by some option to PRINT-DEVICES?

belambert avatar Dec 30 '17 03:12 belambert

Like everything FFI in SBCL, you need to ignore floating point exceptions. Try this @belambert, @anquegi

(ql:quickload "cl-portaudio")

(sb-int:with-float-traps-masked 
    (:divide-by-zero :invalid) 
  (portaudio:print-devices))

See also https://bugs.launchpad.net/sbcl/+bug/1519630

lispnik avatar Aug 01 '20 21:08 lispnik

I seem to be getting almost the same issue, but unsolved by masking float traps:

CL-USER> (sb-int:with-float-traps-masked 
    (:divide-by-zero :invalid) 
  (portaudio:print-devices))
PortAudio version number = 1246976
PortAudio version text = PortAudio V19.7.0-devel, revision 147dd722548358763a8b649b3e4b41dfffbcfbb6
Number of devices = 4
---------------------- device 0
[ Default Output ]
Name                        = USB Audio Device
Host API                    = Core Audio
Max inputs = 0, Max outputs = 2
Default low input latency   =   0.0100
Default low output latency  =   0.0039
Default high input latency  =   0.1000
Default high output latency =   0.0239
Default sample rate         = 48000.0000
Supported standard sample rates
 for half-duplex float 32 bit 2 channel output = 

It hangs at that point and never continues to the next device; here is the stack when I C-c C-c:

Backtrace:
  0: ("bogus stack frame")
  1: ("foreign function: _pthread_mutex_firstfit_lock_slow")
  2: ("foreign function: _ZN10Resampler2C2Eddiiidb")
  3: ("foreign function: _ZN19SampleRateConverter16ReplaceResamplerEv")
  4: ("foreign function: _ZN19PCMConverterFactory6AddSRCER14StreamDescPairRK18ChainBuildSettingsRNSt3__16vectorIP22BufferedAudioConverterNS5_9allocatorIS8_EEEE")
  5: ("foreign function: _ZN19PCMConverterFactory19BuildConverterChainERK14StreamDescPairRK18ChainBuildSettingsP19AudioConverterChainPS_")
  6: ("foreign function: _AudioConverterNewInternal")
  7: ("foreign function: DefaultOutputAUFactory")
  8: ("foreign function: DefaultOutputAUFactory")
  9: ("foreign function: DefaultOutputAUFactory")
 10: ("foreign function: DefaultOutputAUFactory")
 11: ("foreign function: DefaultOutputAUFactory")
 12: ("foreign function: DefaultOutputAUFactory")
 13: ("foreign function: OpenAndSetupOneAudioUnit")
 14: ("foreign function: OpenStream")
 15: ("foreign function: IsFormatSupported")
 16: ("foreign function: Pa_IsFormatSupported")
 17: (PORTAUDIO::%IS-FORMAT-SUPPORTED NIL #<PORTAUDIO:STREAM-PARAMETERS {100485BDD3}> 8000.0d0)
 18: (PORTAUDIO::IS-FORMAT-SUPPORTED NIL #<PORTAUDIO:STREAM-PARAMETERS {100485BDD3}> 8000.0d0)
 19: (PORTAUDIO::PRINT-SUPPORTED-STANDARD-SAMPLE-RATES NIL #<PORTAUDIO:STREAM-PARAMETERS {100485BDD3}>)

Anyone seen similar?

CL-USER> (software-type)
"Darwin"
CL-USER> (software-version)
"20.4.0"
[jackc@n] ~ :) $ brew info portaudio
portaudio: stable 19.7.0 (bottled), HEAD
Cross-platform library for audio I/O
http://www.portaudio.com
/usr/local/Cellar/portaudio/19.7.0 (33 files, 528.8KB) *
  Poured from bottle on 2022-01-10 at 21:37:52
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/portaudio.rb
License: MIT
==> Dependencies
Build: pkg-config ✔
==> Options
--HEAD
	Install HEAD version
==> Analytics
install: 7,429 (30 days), 24,078 (90 days), 107,324 (365 days)
install-on-request: 3,760 (30 days), 11,743 (90 days), 47,806 (365 days)
build-error: 1 (30 days)
[jackc@n] ~ $ sbcl --version
SBCL 2.1.4

TIA!

jackcarrozzo avatar Jan 16 '22 03:01 jackcarrozzo

For whatever reason, in my case the problem appears to be is-format-supported, a foreign-bound function called from print-supported-standard-sample-rates which is itself called by print-devices.

When I shadow is-format-supported with a function that just returns (not (eql rate 44100d0)) (why is the logic inverted from the name?), everything works as expected, as long as you were only interested in that sample rate:

CL-USER> (pa::new-print-devices)
PortAudio version number = 1246976
PortAudio version text = PortAudio V19.7.0-devel, revision 147dd722548358763a8b649b3e4b41dfffbcfbb6
Number of devices = 2
---------------------- device 0
[ Default Input ]
Name                        = MacBook Pro Microphone
Host API                    = Core Audio
Max inputs = 1, Max outputs = 0
Default low input latency   =   0.0551
Default low output latency  =   0.0100
Default high input latency  =   0.0768
Default high output latency =   0.1000
Default sample rate         = 44100.0000
Supported standard sample rates
 for half-duplex float 32 bit 1 channel input = 
44100.00, 
---------------------- device 1
[ Default Output ]
Name                        = MacBook Pro Speakers
Host API                    = Core Audio
Max inputs = 0, Max outputs = 2
Default low input latency   =   0.0100
Default low output latency  =   0.0122
Default high input latency  =   0.1000
Default high output latency =   0.0339
Default sample rate         = 44100.0000
Supported standard sample rates
 for half-duplex float 32 bit 2 channel output = 
44100.00, 
--------------------

jackcarrozzo avatar Jan 19 '22 05:01 jackcarrozzo

In case this is of any value, the bug doesn't occur for me at all ((print-devices) returns immediately) on Linux:

* (pa:print-devices)
Expression 'GetExactSampleRate( hwParams, &defaultSr )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 895
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.front
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround40
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround41
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround50
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround51
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
PortAudio version number = 1246720
PortAudio version text = PortAudio V19.6.0-devel, revision 396fe4b6699ae929d3a685b3ef8a7e97396139a4
Number of devices = 3
---------------------- device 0
Name                        = sysdefault
Host API                    = ALSA
Max inputs = 0, Max outputs = 128
Default low input latency   =  -1.0000
Default low output latency  =   0.0016
Default high input latency  =  -1.0000
Default high output latency =   0.0348
Default sample rate         = 44100.0000
Supported standard sample rates
 for half-duplex float 32 bit 128 channel output = 
 8000.00,  9600.00, 11025.00, 12000.00, 16000.00, 22050.00, 24000.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00, 
---------------------- device 1
[ Default Output ]
Name                        = default
Host API                    = ALSA
Max inputs = 0, Max outputs = 128
Default low input latency   =  -1.0000
Default low output latency  =   0.0016
Default high input latency  =  -1.0000
Default high output latency =   0.0348
Default sample rate         = 44100.0000
Supported standard sample rates
 for half-duplex float 32 bit 128 channel output = 
 8000.00,  9600.00, 11025.00, 12000.00, 16000.00, 22050.00, 24000.00, 32000.00, 44100.00, 48000.00, 88200.00, 96000.00, 192000.00, 
---------------------- device 2
Name                        = dmix
Host API                    = ALSA
Max inputs = 0, Max outputs = 2
Default low input latency   =  -1.0000
Default low output latency  =   0.0213
Default high input latency  =  -1.0000
Default high output latency =   0.0213
Default sample rate         = 48000.0000
Supported standard sample rates
 for half-duplex float 32 bit 2 channel output = 
48000.00, 
--------------------
NIL

(although I do find it interesting that my default ALSA output device reportedly supports 192khz sampling, which does not appear to actually work when opened as such- is there a better way to determine what sample formats and rates a given device will accept?)

jackcarrozzo avatar Jan 19 '22 05:01 jackcarrozzo

Hm this is interesting- portaudio's examples/pa_devs.c does more or less exactly what cl-portaudio's (print-devices) does, but the former works on my laptop where the latter did not:

[jackc@n] ~/Projects/portaudio $ bin/pa_devs 
PortAudio version: 0x00130700
Version text: 'PortAudio V19.7.0-devel, revision unknown'
Number of devices = 2
--------------------------------------- device #0
[ Default Input ]
Name                        = MacBook Pro Microphone
Host API                    = Core Audio
Max inputs = 1, Max outputs = 0
Default low input latency   =   0.0551
Default low output latency  =   0.0100
Default high input latency  =   0.0652
Default high output latency =   0.1000
Default sample rate         = 44100.00
Supported standard sample rates
 for half-duplex 16 bit 1 channel input = 
	 8000.00,  9600.00, 11025.00, 12000.00,
	16000.00, 22050.00, 24000.00, 32000.00,
	44100.00, 48000.00, 88200.00, 96000.00,
	192000.00
--------------------------------------- device #1
[ Default Output ]
Name                        = MacBook Pro Speakers
Host API                    = Core Audio
Max inputs = 0, Max outputs = 2
Default low input latency   =   0.0100
Default low output latency  =   0.0122
Default high input latency  =   0.1000
Default high output latency =   0.0223
Default sample rate         = 44100.00
Supported standard sample rates
 for half-duplex 16 bit 2 channel output = 
	 8000.00,  9600.00, 11025.00, 12000.00,
	16000.00, 22050.00, 24000.00, 32000.00,
	44100.00, 48000.00, 88200.00, 96000.00,
	192000.00
----------------------------------------------

jackcarrozzo avatar Jan 19 '22 22:01 jackcarrozzo

CL-USER> (sb-int:with-float-traps-masked (:divide-by-zero :invalid) (portaudio:print-devices)) PortAudio version number = 1246976

On macOS, I started SBCL, quickloaded cl-portaudio and ran the quoted example in a loop a few thousand times and didn't get a hang. When I see CL-USER in your example output I wonder if you're trying it from SLIME or SLY. Have you tried it from outside of SLIME/SLY with just cl-portaudio loaded? Perhaps portaudio and SLIME/SLY are disagreeing on underlying thread coordination...

lispnik avatar Jan 20 '22 19:01 lispnik

Ahh good call @lispnik , it does indeed work as expected when I do what you suggested:

sbcl --eval '(ql:quickload :cl-portaudio)' --eval '(sb-int:with-float-traps-masked (:divide-by-zero :invalid) (portaudio:print-devices))' --quit

This is the backtrace I got today doing exactly the same thing in SLIME:

Backtrace:
  0: ("bogus stack frame")
  1: ("foreign function: _ZN12CADeprecated7CAGuard7WaitForEy")
  2: ("foreign function: _ZN9HALObject22RemovePropertyListenerERK26AudioObjectPropertyAddressRK19HALPropertyListener")
  3: ("foreign function: AudioObjectRemovePropertyListener")
  4: ("foreign function: DefaultOutputAUFactory")
  5: ("foreign function: AUGenericOutputFactory")
  6: ("foreign function: DefaultOutputAUFactory")
  7: ("foreign function: DefaultOutputAUFactory")
  8: ("foreign function: OpenAndSetupOneAudioUnit")
  9: ("foreign function: OpenStream")
 10: ("foreign function: IsFormatSupported")
 11: ("foreign function: Pa_IsFormatSupported")
 12: (PORTAUDIO::%IS-FORMAT-SUPPORTED #<PORTAUDIO:STREAM-PARAMETERS {1002D12493}> NIL 8000.0d0)
 13: (PORTAUDIO::IS-FORMAT-SUPPORTED #<PORTAUDIO:STREAM-PARAMETERS {1002D12493}> NIL 8000.0d0)
 14: (PORTAUDIO::PRINT-SUPPORTED-STANDARD-SAMPLE-RATES #<PORTAUDIO:STREAM-PARAMETERS {1002D12493}> NIL)
 15: (PORTAUDIO:PRINT-DEVICES)

Any suggestions what route I should follow to try to figure out where the difference between plain-sbcl and invocation lies? I am unfortunately ignorant as to the innerworkings of SLIME et al, but if you can tell me what area of the docs to check out I might be able to make some progress.

Thanks!

jackcarrozzo avatar Jan 20 '22 21:01 jackcarrozzo

Try one of the other SLIME communication styles: https://slime.common-lisp.dev/doc/html/Communication-style.html

lispnik avatar Jan 22 '22 03:01 lispnik

OK, here are my results trying all four methods, conveniently commented in my swank init:

~ $ cat .swank.lisp 
;; this works!
(setq SWANK:*COMMUNICATION-STYLE* nil)

;; cl-portaudio hangs while loading, never returns (TODO:)
;;(setq SWANK:*COMMUNICATION-STYLE* :FD-HANDLER)

;; cl-portaudio loads but print-devices still exhibits bug (hangs)
;;(setq SWANK:*COMMUNICATION-STYLE* :SIGIO)

;; default (cl-portaudio loads but print-devices hangs)
;;(setq SWANK:*COMMUNICATION-STYLE* :SPAWN)

I didn't spend much time trying to figure out why the package wouldn't load using :FD-HANDLER, just got to here every time and stayed there forever, nothing of value in any buffers:

CL-USER> (ql:quickload 'cl-portaudio)
To load "cl-portaudio":
  Load 1 ASDF system:
    cl-portaudio
; Loading "cl-portaudio"
...

In any event, it is cool that NIL works! I guess it has some downsides in terms of fancy interaction, but at least cl-portaudio seems to be operating the same as it does directly in sbcl (that is to say, correctly).

jackcarrozzo avatar Jan 25 '22 02:01 jackcarrozzo