Page 1 of 1

sound sample doesn't work right, osx mojave

Posted: Sun Jan 13, 2019 1:46 am
by jbattle
I have my application running fine on windows, and I'm just now getting it working for OSX. I was having problems with wxSound, so my first course of action was to build the samples/sound program, completely unmodified. It was built using the developer command line tools (that is, apple's faux gcc, no xcode) using just "make -f makefile.unx"

The shortest repro steps after building are:
[*]launch program
[*]Cmd-L (loop sound) ... and the sound does loop
[*]Cmd-T (stop playing) ... and the sound does stop playing
[*]Cmd-L (loop sound) ... silence

Another sequence that fails:
[*]launch program
[*]Cmd-S (play synchronously) ... and it works as expected
[*]Cmd-S (play synchronously) ... nothing is heard and the spinning ball goes forever

Can anyone else repro this on OSX or does this indicate some problem in my setup?

wx-3.1.2, no patches or modifications
Apple Developer Command Line tools
built with debug, no optimization
no setup.h tweaks, just the stock wx-3.1.2 build

[76 wx-3.1.2/samples/sound]wx-config --cxx
g++ -std=gnu++14 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -mmacosx-version-min=10.7 -stdlib=libc++

[77 wx-3.1.2/samples/sound]wx-config --cxxflags
-I/Users/jb/lib/wx/include/osx_cocoa-unicode-static-3.1 -I/Users/jb/include/wx-3.1 -D_FILE_OFFSET_BITS=64 -D__WXMAC__ -D__WXOSX__ -D__WXOSX_COCOA__

[78 wx-3.1.2/samples/sound]wx-config --libs
-L/Users/jb/lib -framework IOKit -framework Carbon -framework Cocoa -framework AudioToolbox -framework System -framework OpenGL /Users/jb/lib/libwx_osx_cocoau_xrc-3.1.a /Users/jb/lib/libwx_osx_cocoau_qa-3.1.a /Users/jb/lib/libwx_baseu_net-3.1.a /Users/jb/lib/libwx_osx_cocoau_html-3.1.a /Users/jb/lib/libwx_osx_cocoau_core-3.1.a /Users/jb/lib/libwx_baseu_xml-3.1.a /Users/jb/lib/libwx_baseu-3.1.a -framework WebKit -lwxtiff-3.1 -lwxjpeg-3.1 -lwxpng-3.1 -lwxregexu-3.1 -lwxscintilla-3.1 -lexpat -lz -framework Security -lpthread -liconv

Re: sound sample doesn't work right, osx mojave

Posted: Fri Jan 18, 2019 7:46 am
by jbattle
I believe I understand what is going wrong. I have no experience developing on OSX, but just looking at src/osx/core/sound.cpp was enough.

I have not tested a fix.

The call to Create() obtains a handle for the sound resource. This is saved in the wxOSXAudioToolboxSoundData class as m_soundID.

In DoStop(), AudioServicesDisposeSystemSoundID is called. That seems like an error, as a subsequent call to Play() will be using the old m_soundID handle, explaining why the sample app is does not play the sound a second time.

I think DoStop() should not call that function, and instead it should be called from the ~wxOSXAudioToolboxSoundData() destructor, just after callingn DoStop().

Re: sound sample doesn't work right, osx mojave

Posted: Fri Jan 18, 2019 8:26 am
by doublemax
I don't know about OSX, but what you're saying sounds reasonable. Please open a bug report at

Re: sound sample doesn't work right, osx mojave

Posted: Fri Jan 18, 2019 4:46 pm
If you can test it, making sure it works and submit it as a PR on Github, it would be great.

Thank you.

Re: sound sample doesn't work right, osx mojave

Posted: Sat Jan 19, 2019 1:06 am
by jbattle
I did make the change and the sound sample works now. I downloaded wxwidgets as a zip file and don't have a repository set up. So to send a patch back I'll need to do that and learn enough git to make it happen.

(that is the end of the useful information. below is just details about why, even with this fix, sound is better but not working right with my app. you can skip it unless you care to form your own theory)

As for my application, I'm going to have to work on this a bit more. I emulate a particular old computer. When HEX(07) is printed, the emulator beeps, using the same frequency and duration as the original machine. That duration is 100ms. On MSW I have been generating in in-memory .wav struct and that worked fine, but for OSX that interface is not supported. Next I created an external 100ms long .wav file of the beep.

Because the emulated program might print HEX(07) in a loop, how the emulator really works is it plays the .wav async and with the loop flag set. Any time HEX(07) is printed, a 100ms timer is restarted. Thus, a long train of HEX(07) output sounds like one long beep. Once the timer expires, I kill the sound. That all works perfectly on MSW.

But for OSX, something weird is happening. If I do

10 PRINT HEX(07):GOTO 10

I hear a train of beeps, which is about 50% beep and 50% pause between the beeps. If I do

10 PRINT HEX(07)

I get two beeps. My current theory is that the wav sample is too short on OSX and due to its implementation it introduces a gap between loops. Secondly, I suspect my 100ms timer is firing just after the first loop has been scheduled to loop again, so when I ask it to stop, there is a delay before it takes effect and I end up with a 2nd beep.

Re: sound sample doesn't work right, osx mojave

Posted: Sat Jan 19, 2019 1:23 am
by jbattle
That took less time to confirm that I expected.

I generated a 0.5 second audio sample, just a 1Khz tone, as a wav file. When I load it using the sound sample program and play it in a loop, there is a gap between each iteration of the loop. So I don't think that the sound is just too short, I think there is some problem with looping audio on osx.

A second problem is that if I start the audio playing asynchronously, then 100ms later issue a Stop() on it, the sample plays the full 500ms.

Using the same code (loading the same .wav file from the external source, instead of internally generating it) on MSW doesn't have any gap between loops.

I'll still issue the patch for the first issue, but there is still more in the sound subsystem that could be improved on OSX.

Re: sound sample doesn't work right, osx mojave

Posted: Sat Jan 19, 2019 6:50 am
by jbattle
I've studied the code a bit more. wxWidgets is using the system sound services set of APIs ( ... d_services) for implementing the wxSound API on OSX. This is a very simple but very limited API. As a result, the stuff I was jibbering about previously is true.

1. once a sound is launched, it can't be stopped
2. the native API has no looping capability. to impliment wx's looping option, a callback which fires when the sample reaches the end causes wx to reschedule the sample to play again. the result is a gap on each iteration, as there is some lag from the end of the audio playing and when wx's callback gets notified, and/or some lag from when wx asks the sample to play and when it actually starts.

As for creating a pull request, I'm sorry, I tried, but the learning curve is too steep to submit a two line change. If one uses git every day I'm sure the process is easy, but coming from the outside, there are way too many concepts to understand to succeed. (I've used svn for my own projects and perforce daily at work for years, but git is different enough that it isn't clicking).

Instead I offer this context diff and hope this is good enough.

*** sound.cpp.orig 2019-01-18 18:11:57.000000000 -0600
--- sound.cpp 2019-01-18 18:12:22.000000000 -0600
*** 58,63 ****
--- 58,64 ----
+ AudioServicesDisposeSystemSoundID (m_soundID);

*** 95,102 ****
m_playing = false;
- AudioServicesDisposeSystemSoundID (m_soundID);
--- 96,101 ----

Re: sound sample doesn't work right, osx mojave

Posted: Sat Jan 19, 2019 8:59 am
by doublemax
Thanks for your research, but this a user forum, so your patch won't reach the right people. If you can't make a pull request, please open a ticket at anyway or post this to the wx-users mailing list / Google group:!forum/wx-users