View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002638 | FSSCP | speech | public | 2012-04-13 04:20 | 2015-04-23 17:39 |
Reporter | gereedy | Assigned To | Echelon9 | ||
Priority | normal | Severity | feature | Reproducibility | always |
Status | code review | Resolution | open | ||
Summary | 0002638: Support speech on OSX | ||||
Description | This patch implements text-to-speech for mac os x. | ||||
Tags | No tags attached. | ||||
|
macspeech.patch (5,716 bytes)
Index: projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj =================================================================== --- projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj (revision 8666) +++ projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj (working copy) @@ -4169,6 +4169,7 @@ USE_OPENAL, NO_DIRECT3D, APPLE_APP, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ../../libjpeg; LIBRARY_STYLE = STATIC; @@ -4213,6 +4214,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ( ../../code, @@ -4324,6 +4326,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GENERATE_PROFILING_CODE = NO; @@ -4360,6 +4363,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); GCC_STRICT_ALIASING = YES; GCC_UNROLL_LOOPS = YES; @@ -4535,6 +4539,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GENERATE_PROFILING_CODE = NO; @@ -4590,6 +4595,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ( ../../code, @@ -4626,6 +4632,7 @@ USE_OPENAL, NO_DIRECT3D, APPLE_APP, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ../../libjpeg; LIBRARY_STYLE = STATIC; @@ -4741,6 +4748,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); GCC_STRICT_ALIASING = YES; GCC_UNROLL_LOOPS = YES; @@ -4795,6 +4803,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ( ../../code, Index: configure.ac =================================================================== --- configure.ac (revision 8666) +++ configure.ac (working copy) @@ -436,7 +436,7 @@ dnl extra OSX frameworks if test "$fs2_os_osx" = "yes" ; then - FS2_LDFLAGS="$FS2_LDFLAGS -framework AppKit -framework Foundation" + FS2_LDFLAGS="$FS2_LDFLAGS -framework AppKit -framework Foundation -framework ApplicationServices" fi Index: code/sound/speech.cpp =================================================================== --- code/sound/speech.cpp (revision 8666) +++ code/sound/speech.cpp (working copy) @@ -29,6 +29,9 @@ #include <sphelper.h> ISpVoice *Voice_device; +#elif defined(__APPLE__) +#include <ApplicationServices/ApplicationServices.h> + SpeechChannel speech_channel; #elif defined(SCP_UNIX) #include <fcntl.h> // #include <stdio.h> @@ -56,6 +59,13 @@ (void **)&Voice_device); Speech_init = SUCCEEDED(hr); +#elif defined(__APPLE__) + OSErr err; + err = NewSpeechChannel(NULL, &speech_channel); + if (err) { + return false; + } + Speech_init = true; #else speech_dev = open("/dev/speech", O_WRONLY | O_DIRECT); @@ -79,6 +89,8 @@ #ifdef _WIN32 Voice_device->Release(); +#elif defined(__APPLE__) + DisposeSpeechChannel(speech_channel); #else close(speech_dev); // fclose(speech_dev); @@ -113,6 +125,34 @@ speech_stop(); return SUCCEEDED(Voice_device->Speak(Conversion_buffer, SPF_ASYNC, NULL)); +#elif defined(__APPLE__) + int len = strlen(text); + char Conversion_buffer[MAX_SPEECH_CHAR_LEN]; + + if(len > (MAX_SPEECH_CHAR_LEN - 1)) { + len = MAX_SPEECH_CHAR_LEN - 1; + } + + int count = 0; + for(int i = 0; i < len; i++) { + if(text[i] == '$') { + i++; + continue; + } + if(text[i] == '\n') { + Conversion_buffer[count] = '\n'; + count++; + } + + Conversion_buffer[count] = text[i]; + count++; + } + + Conversion_buffer[count] = '\0'; + + CFStringRef speech_string = CFStringCreateWithCString(NULL, Conversion_buffer, kCFStringEncodingASCII); + OSErr err = SpeakCFString(speech_channel, speech_string, NULL); + return !err; #else int len = strlen(text); char Conversion_buffer[MAX_SPEECH_CHAR_LEN]; @@ -150,6 +190,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Pause()); +#elif defined(__APPLE__) + return !PauseSpeechAt(speech_channel, kEndOfWord); #else STUB_FUNCTION; @@ -162,6 +204,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Resume()); +#elif defined(__APPLE__) + return !ContinueSpeech(speech_channel); #else STUB_FUNCTION; @@ -174,6 +218,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Speak( NULL, SPF_PURGEBEFORESPEAK, NULL )); +#elif defined(__APPLE__) + return !StopSpeechAt(speech_channel, kEndOfWord); #else STUB_FUNCTION; @@ -185,6 +231,9 @@ { #ifdef _WIN32 return SUCCEEDED(Voice_device->SetVolume(volume)); +#elif defined(__APPLE__) + STUB_FUNCTION; + return true; #else STUB_FUNCTION; @@ -228,6 +277,9 @@ count++; } return false; +#elif defined(__APPLE__) + STUB_FUNCTION; + return true; #else STUB_FUNCTION; @@ -246,6 +298,11 @@ if (FAILED(hr)) return false; return (pStatus.dwRunningState == SPRS_IS_SPEAKING); +#elif defined(__APPLE__) + SpeechStatusInfo status; + OSErr err = GetSpeechInfo(speech_channel, soStatus, &status); + if (err) return false; + return status.outputBusy; #else STUB_FUNCTION; |
|
Oops, I forgot to release the strings. Here's an updated patch. |
|
macspeech2.patch (5,747 bytes)
Index: configure.ac =================================================================== --- configure.ac (revision 8666) +++ configure.ac (working copy) @@ -436,7 +436,7 @@ dnl extra OSX frameworks if test "$fs2_os_osx" = "yes" ; then - FS2_LDFLAGS="$FS2_LDFLAGS -framework AppKit -framework Foundation" + FS2_LDFLAGS="$FS2_LDFLAGS -framework AppKit -framework Foundation -framework ApplicationServices" fi Index: projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj =================================================================== --- projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj (revision 8666) +++ projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj (working copy) @@ -4169,6 +4169,7 @@ USE_OPENAL, NO_DIRECT3D, APPLE_APP, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ../../libjpeg; LIBRARY_STYLE = STATIC; @@ -4213,6 +4214,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ( ../../code, @@ -4324,6 +4326,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GENERATE_PROFILING_CODE = NO; @@ -4360,6 +4363,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); GCC_STRICT_ALIASING = YES; GCC_UNROLL_LOOPS = YES; @@ -4535,6 +4539,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GENERATE_PROFILING_CODE = NO; @@ -4590,6 +4595,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ( ../../code, @@ -4626,6 +4632,7 @@ USE_OPENAL, NO_DIRECT3D, APPLE_APP, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ../../libjpeg; LIBRARY_STYLE = STATIC; @@ -4741,6 +4748,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); GCC_STRICT_ALIASING = YES; GCC_UNROLL_LOOPS = YES; @@ -4795,6 +4803,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ( ../../code, Index: code/sound/speech.cpp =================================================================== --- code/sound/speech.cpp (revision 8666) +++ code/sound/speech.cpp (working copy) @@ -29,6 +29,9 @@ #include <sphelper.h> ISpVoice *Voice_device; +#elif defined(__APPLE__) +#include <ApplicationServices/ApplicationServices.h> + SpeechChannel speech_channel; #elif defined(SCP_UNIX) #include <fcntl.h> // #include <stdio.h> @@ -56,6 +59,13 @@ (void **)&Voice_device); Speech_init = SUCCEEDED(hr); +#elif defined(__APPLE__) + OSErr err; + err = NewSpeechChannel(NULL, &speech_channel); + if (err) { + return false; + } + Speech_init = true; #else speech_dev = open("/dev/speech", O_WRONLY | O_DIRECT); @@ -79,6 +89,8 @@ #ifdef _WIN32 Voice_device->Release(); +#elif defined(__APPLE__) + DisposeSpeechChannel(speech_channel); #else close(speech_dev); // fclose(speech_dev); @@ -113,6 +125,35 @@ speech_stop(); return SUCCEEDED(Voice_device->Speak(Conversion_buffer, SPF_ASYNC, NULL)); +#elif defined(__APPLE__) + int len = strlen(text); + char Conversion_buffer[MAX_SPEECH_CHAR_LEN]; + + if(len > (MAX_SPEECH_CHAR_LEN - 1)) { + len = MAX_SPEECH_CHAR_LEN - 1; + } + + int count = 0; + for(int i = 0; i < len; i++) { + if(text[i] == '$') { + i++; + continue; + } + if(text[i] == '\n') { + Conversion_buffer[count] = '\n'; + count++; + } + + Conversion_buffer[count] = text[i]; + count++; + } + + Conversion_buffer[count] = '\0'; + + CFStringRef speech_string = CFStringCreateWithCString(NULL, Conversion_buffer, kCFStringEncodingASCII); + OSErr err = SpeakCFString(speech_channel, speech_string, NULL); + CFRelease(speech_string); + return !err; #else int len = strlen(text); char Conversion_buffer[MAX_SPEECH_CHAR_LEN]; @@ -150,6 +191,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Pause()); +#elif defined(__APPLE__) + return !PauseSpeechAt(speech_channel, kEndOfWord); #else STUB_FUNCTION; @@ -162,6 +205,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Resume()); +#elif defined(__APPLE__) + return !ContinueSpeech(speech_channel); #else STUB_FUNCTION; @@ -174,6 +219,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Speak( NULL, SPF_PURGEBEFORESPEAK, NULL )); +#elif defined(__APPLE__) + return !StopSpeechAt(speech_channel, kEndOfWord); #else STUB_FUNCTION; @@ -185,6 +232,9 @@ { #ifdef _WIN32 return SUCCEEDED(Voice_device->SetVolume(volume)); +#elif defined(__APPLE__) + STUB_FUNCTION; + return true; #else STUB_FUNCTION; @@ -228,6 +278,9 @@ count++; } return false; +#elif defined(__APPLE__) + STUB_FUNCTION; + return true; #else STUB_FUNCTION; @@ -246,6 +299,11 @@ if (FAILED(hr)) return false; return (pStatus.dwRunningState == SPRS_IS_SPEAKING); +#elif defined(__APPLE__) + SpeechStatusInfo status; + OSErr err = GetSpeechInfo(speech_channel, soStatus, &status); + if (err) return false; + return status.outputBusy; #else STUB_FUNCTION; |
|
I've got this cleanly compiled into a build, but at a bit of a loss to actually get it working in game. Is there a system-wide setting (i.e. in Preferences) that I need to set before this will work. Using OS X 10.7 here. |
|
Oh yeah, I had to edit the fs2_open.ini file in ~/Library/FS2_Open and add the following lines: SpeechTechroom=1 SpeechBriefings=1 SpeechIngame=1 SpeechMulti=1 I've not seen any other way (launcher or in-game) to set these. |
|
Hrmm, I've tried setting those as well as setting them to 0, as per the code. Across Debug and Retail, no luck getting this working... |
|
I think the 0 in the code is the default value if none is set, they need to be 1 to activate speech. How are you building? The only thing I can think of is that you're building without FS2_SPEECH defined. FYI, I'm on Lion as well and used the Xcode 4 project. The patch include the changes to the project file to turn that define on. |
|
Huh, and here I thought we'd need to be using Festival across the board. |
|
Okay, by using this patch and forcing speech at startup with the -query_speech command line option, I hear part of the initial testing "Welcome to FS..." before Freespace crashes. Looks like there's some memory corruption going on. // fs2_open.log ------------------------------------------------------------ Initializing OpenAL... OpenAL Vendor : Apple Computer Inc. OpenAL Renderer : Software OpenAL Version : 1.1 Found extension "AL_EXT_float32". Sample rate: 0 (44100) EFX enabled: NO Playback device: Built-in Output Capture device: Built-in Microphone ... OpenAL successfully initialized! Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] // Crash reporter ------------------------------------------------------------ Thread 3 Crashed: 0 FS2_Open-Inferno (debug) 0x0057bb00 _vm_free(void*, char*, int) + 128 (stubs.cpp:687) 1 FS2_Open-Inferno (debug) 0x000035cb operator delete(void*) + 43 (fsmemory.cpp:19) 2 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b3e4f0 MTBEDelayedNotifier::ForwardUnit() + 102 3 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b3bcbe MTCBSegmentProducer::NextSegment(MTMBSegment*) + 582 4 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b3b98e MTMBSmoothSegment::NextSegment(MTMBSegment*) + 90 5 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b6b488 non-virtual thunk to MTMBSmoothSegment::NextSegment(MTMBSegment*) + 27 6 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b3b873 MTMBChangePitch::NextSegment(MTMBSegment*) + 145 7 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b6b2b5 non-virtual thunk to MTMBChangePitch::NextSegment(MTMBSegment*) + 27 8 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b3b27a MTMBBlend::NextSegment(MTMBSegment*) + 160 9 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b6b368 non-virtual thunk to MTMBBlend::NextSegment(MTMBSegment*) + 27 10 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b3b079 MTMBChangeAmplitude::NextSegment(MTMBSegment*) + 35 11 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b6b403 non-virtual thunk to MTMBChangeAmplitude::NextSegment(MTMBSegment*) + 27 12 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b3ac71 MTMBSpeechRateModifier::NextSegment(MTMBSegment*) + 211 13 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b6b5fe non-virtual thunk to MTMBSpeechRateModifier::NextSegment(MTMBSegment*) + 27 14 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b3aa15 MTBEPhraseProcessor::GenerateSamples(MTBESoundOutput*, int*) + 277 15 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b2b52f MT3BEngineTask::Execute(void*) + 337 16 com.apple.speech.synthesis.MacinTalkSynthesizer 0x07b06cce MTBEWorker::ExecuteTasks() + 384 |
|
macspeech3.patch (5,999 bytes)
Index: projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj =================================================================== --- projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj (revision 9107) +++ projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj (working copy) @@ -4162,6 +4162,7 @@ USE_OPENAL, NO_DIRECT3D, APPLE_APP, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ../../libjpeg; LIBRARY_STYLE = STATIC; @@ -4204,6 +4205,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ( ../../code, @@ -4312,6 +4314,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GENERATE_PROFILING_CODE = NO; @@ -4345,6 +4348,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); GCC_STRICT_ALIASING = YES; GCC_UNROLL_LOOPS = YES; @@ -4519,6 +4523,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GENERATE_PROFILING_CODE = NO; @@ -4571,6 +4576,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ( ../../code, @@ -4606,6 +4612,7 @@ USE_OPENAL, NO_DIRECT3D, APPLE_APP, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ../../libjpeg; LIBRARY_STYLE = STATIC; @@ -4718,6 +4725,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); GCC_STRICT_ALIASING = YES; GCC_UNROLL_LOOPS = YES; @@ -4771,6 +4779,7 @@ USE_OPENAL, APPLE_APP, INF_BUILD, + FS2_SPEECH, ); HEADER_SEARCH_PATHS = ( ../../code, Index: configure.ac =================================================================== --- configure.ac (revision 9107) +++ configure.ac (working copy) @@ -436,7 +436,7 @@ dnl extra OSX frameworks if test "$fs2_os_osx" = "yes" ; then - FS2_LDFLAGS="$FS2_LDFLAGS -framework AppKit -framework Foundation" + FS2_LDFLAGS="$FS2_LDFLAGS -framework AppKit -framework Foundation -framework ApplicationServices" fi Index: code/sound/speech.cpp =================================================================== --- code/sound/speech.cpp (revision 9107) +++ code/sound/speech.cpp (working copy) @@ -29,6 +29,9 @@ #include <sphelper.h> ISpVoice *Voice_device; +#elif defined(__APPLE__) +#include <ApplicationServices/ApplicationServices.h> + SpeechChannel speech_channel; #elif defined(SCP_UNIX) #include <fcntl.h> // #include <stdio.h> @@ -56,13 +59,18 @@ (void **)&Voice_device); Speech_init = SUCCEEDED(hr); +#elif defined(__APPLE__) + OSErr err; + err = NewSpeechChannel(NULL, &speech_channel); + if (err) { + return false; + } + Speech_init = true; #else speech_dev = open("/dev/speech", O_WRONLY | O_DIRECT); -// speech_dev = fopen("/dev/speech", "w"); if (speech_dev == -1) { -// if (speech_dev == NULL) { mprintf(("Couldn't open '/dev/speech', turning text-to-speech off...\n")); return false; } @@ -79,9 +87,10 @@ #ifdef _WIN32 Voice_device->Release(); +#elif defined(__APPLE__) + DisposeSpeechChannel(speech_channel); #else close(speech_dev); -// fclose(speech_dev); #endif } @@ -113,6 +122,35 @@ speech_stop(); return SUCCEEDED(Voice_device->Speak(Conversion_buffer, SPF_ASYNC, NULL)); +#elif defined(__APPLE__) + int len = strlen(text); + char Conversion_buffer[MAX_SPEECH_CHAR_LEN]; + + if(len > (MAX_SPEECH_CHAR_LEN - 1)) { + len = MAX_SPEECH_CHAR_LEN - 1; + } + + int count = 0; + for(int i = 0; i < len; i++) { + if(text[i] == '$') { + i++; + continue; + } + if(text[i] == '\n') { + Conversion_buffer[count] = '\n'; + count++; + } + + Conversion_buffer[count] = text[i]; + count++; + } + + Conversion_buffer[count] = '\0'; + + CFStringRef speech_string = CFStringCreateWithCString(NULL, Conversion_buffer, kCFStringEncodingASCII); + OSErr err = SpeakCFString(speech_channel, speech_string, NULL); + CFRelease(speech_string); + return !err; #else int len = strlen(text); char Conversion_buffer[MAX_SPEECH_CHAR_LEN]; @@ -150,6 +188,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Pause()); +#elif defined(__APPLE__) + return !PauseSpeechAt(speech_channel, kEndOfWord); #else STUB_FUNCTION; @@ -162,6 +202,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Resume()); +#elif defined(__APPLE__) + return !ContinueSpeech(speech_channel); #else STUB_FUNCTION; @@ -174,6 +216,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Speak( NULL, SPF_PURGEBEFORESPEAK, NULL )); +#elif defined(__APPLE__) + return !StopSpeechAt(speech_channel, kEndOfWord); #else STUB_FUNCTION; @@ -185,6 +229,10 @@ { #ifdef _WIN32 return SUCCEEDED(Voice_device->SetVolume(volume)); +#elif defined(__APPLE__) + OSErr err = SetSpeechInfo(speech_channel, soVolume, &volume); + if (err) return false; + return true; #else STUB_FUNCTION; @@ -228,9 +276,12 @@ count++; } return false; +#elif defined(__APPLE__) + STUB_FUNCTION; + return true; #else STUB_FUNCTION; - + return true; #endif } @@ -246,6 +297,11 @@ if (FAILED(hr)) return false; return (pStatus.dwRunningState != SPRS_DONE); +#elif defined(__APPLE__) + SpeechStatusInfo status; + OSErr err = GetSpeechInfo(speech_channel, soStatus, &status); + if (err) return false; + return status.outputBusy; #else STUB_FUNCTION; |
|
A more recent patch version is attached (macspeech3.patch) |
|
Checked back up on this patch. Only takes two line additions of FS2_SPEECH to the Xcode project now I think, both added below the only two occurences of APPLE_APP. Ran it, no speech. fs2_open.ini in ~/Library/FS2_Open looks like: [Default] VideocardFs2open=OGL -(1024x768)x32 bit TextureFilter=1 OGL_AnisotropicFilter=0 OGL_AntiAliasSamples=0 SoundDeviceOAL=Built-in Output CurrentJoystick=99999 EnableJoystickFF=0 EnableHitEffect=0 NetworkConnection=LAN ConnectionSpeed=Fast LastPlayer=chief_work SpeechTechroom=1 SpeechBriefings=1 SpeechIngame=1 SpeechMulti=1 SpeechGame=1 [Sound] PlaybackDevice=Built-in Output CaptureDevice=Built-in Microphone [PXO] FS2OpenPXO=1 I added SpeechGame as I saw it in my Windows registry list as well. Debug build log looks like: Initializing OpenAL... OpenAL Vendor : Apple Computer Inc. OpenAL Renderer : Software OpenAL Version : 1.1 Found extension "AL_EXT_float32". Sample rate: 0 (44100) EFX enabled: NO Playback device: Built-in Output Capture device: Built-in Microphone ... OpenAL successfully initialized! Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] STUB: speech_set_voice in /Users/cliff.gordon/fs2open/code/sound/speech.cpp at line 280, thread 63763 -query_speech doesn't seem to change anything for me. |
|
macspeech4.patch (4,887 bytes)
Index: code/sound/speech.cpp =================================================================== --- code/sound/speech.cpp (revision 10859) +++ code/sound/speech.cpp (working copy) @@ -29,6 +29,9 @@ #include <sphelper.h> ISpVoice *Voice_device; +#elif defined(__APPLE__) +#include <ApplicationServices/ApplicationServices.h> + SpeechChannel speech_channel; #elif defined(SCP_UNIX) #include <fcntl.h> // #include <stdio.h> @@ -56,13 +59,18 @@ (void **)&Voice_device); Speech_init = SUCCEEDED(hr); +#elif defined(__APPLE__) + OSErr err; + err = NewSpeechChannel(NULL, &speech_channel); + if (err) { + return false; + } + Speech_init = true; #else speech_dev = open("/dev/speech", O_WRONLY | O_DIRECT); -// speech_dev = fopen("/dev/speech", "w"); if (speech_dev == -1) { -// if (speech_dev == NULL) { mprintf(("Couldn't open '/dev/speech', turning text-to-speech off...\n")); return false; } @@ -79,9 +87,10 @@ #ifdef _WIN32 Voice_device->Release(); +#elif defined(__APPLE__) + DisposeSpeechChannel(speech_channel); #else close(speech_dev); -// fclose(speech_dev); #endif } @@ -113,6 +122,35 @@ speech_stop(); return SUCCEEDED(Voice_device->Speak(Conversion_buffer, SPF_ASYNC, NULL)); +#elif defined(__APPLE__) + int len = strlen(text); + char Conversion_buffer[MAX_SPEECH_CHAR_LEN]; + + if(len > (MAX_SPEECH_CHAR_LEN - 1)) { + len = MAX_SPEECH_CHAR_LEN - 1; + } + + int count = 0; + for(int i = 0; i < len; i++) { + if(text[i] == '$') { + i++; + continue; + } + if(text[i] == '\n') { + Conversion_buffer[count] = '\n'; + count++; + } + + Conversion_buffer[count] = text[i]; + count++; + } + + Conversion_buffer[count] = '\0'; + + CFStringRef speech_string = CFStringCreateWithCString(NULL, Conversion_buffer, kCFStringEncodingASCII); + OSErr err = SpeakCFString(speech_channel, speech_string, NULL); + CFRelease(speech_string); + return !err; #else int len = strlen(text); char Conversion_buffer[MAX_SPEECH_CHAR_LEN]; @@ -150,6 +188,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Pause()); +#elif defined(__APPLE__) + return !PauseSpeechAt(speech_channel, kEndOfWord); #else STUB_FUNCTION; @@ -162,6 +202,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Resume()); +#elif defined(__APPLE__) + return !ContinueSpeech(speech_channel); #else STUB_FUNCTION; @@ -174,6 +216,8 @@ if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Speak( NULL, SPF_PURGEBEFORESPEAK, NULL )); +#elif defined(__APPLE__) + return !StopSpeechAt(speech_channel, kEndOfWord); #else STUB_FUNCTION; @@ -185,6 +229,10 @@ { #ifdef _WIN32 return SUCCEEDED(Voice_device->SetVolume(volume)); +#elif defined(__APPLE__) + OSErr err = SetSpeechInfo(speech_channel, soVolume, &volume); + if (err) return false; + return true; #else STUB_FUNCTION; @@ -228,9 +276,12 @@ count++; } return false; +#elif defined(__APPLE__) + STUB_FUNCTION; + return true; #else STUB_FUNCTION; - + return true; #endif } @@ -246,6 +297,11 @@ if (FAILED(hr)) return false; return (pStatus.dwRunningState != SPRS_DONE); +#elif defined(__APPLE__) + SpeechStatusInfo status; + OSErr err = GetSpeechInfo(speech_channel, soStatus, &status); + if (err) return false; + return status.outputBusy; #else STUB_FUNCTION; Index: configure.ac =================================================================== --- configure.ac (revision 10859) +++ configure.ac (working copy) @@ -395,6 +395,7 @@ FS2_CXXFLAGS="$FS2_CXXFLAGS -I/System/Library/Frameworks/OpenGL.framework/Headers" FS2_LDFLAGS="$FS2_LDFLAGS -framework OpenGL" AC_DEFINE([SCP_UNIX]) + AC_DEFINE([FS2_SPEECH]) AC_DEFINE([NO_DIRECT3D]) ## don't need the CFLAGS here if recent SDL is used elif test "$fs2_os_solaris" = "yes" ; then @@ -473,7 +474,7 @@ dnl extra OSX frameworks if test "$fs2_os_osx" = "yes" ; then - FS2_LDFLAGS="$FS2_LDFLAGS -framework AppKit -framework Foundation" + FS2_LDFLAGS="$FS2_LDFLAGS -framework AppKit -framework Foundation -framework ApplicationServices" fi Index: projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj =================================================================== --- projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj (revision 10859) +++ projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj (working copy) @@ -4439,6 +4439,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -4486,6 +4487,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); GCC_STRICT_ALIASING = YES; GCC_UNROLL_LOOPS = YES; |
|
I've uploaded a new patch version with tweaked project files. I also added the FS2_SPEECH define to configure.ac, however that file doesn't affect Xcode to my knowledge. That also made me wonder how ApplicationServices is being loaded into the Xcode builds then, or if it was needed at all. This doesn't fix it, it's just a more up to date starting point for anyone looking at it. |
|
Thanks, I'll take another look at the memory corruption here. Looks like another double free. |
|
You shouldn't need to set SpeechGame=1, see further the table of speech types in the array FSSpeech_play_id[] in fsspeech.cpp |
|
Well, I wasn't sure, but removing it doesn't change anything. I don't get any crashes, I just enter the tech room, and I don't hear any TTS. |
|
Same here. I spent some time testing and debugging this evening. Whilst no crashes, also no spoken words on 10.9. I can confirm the text is being passed to the SpeakCFString() API call, just nothing happens after that. |
|
Like I said, I wonder if that's because the ApplicationServices framework isn't actually being added as an App resource in the Xcode4 project. It was added to configure.ac for some reason but that has nothing to do with Xcode builds. But I would probably expect more warnings/errors if that were actually the problem. |
|
I did a quick test with otool -L on the resultant binary, and it looks like ApplicationServices.framework was linked in. |
|
So any other thoughts on this? If the framework is linked in, why is there no speech? Something needs to be configured in System Preferences or something? |
|
I applied the macspeech4.patch to current trunk and tried again, after adjusting some settings in the VoiceOver configuration. Also tried the -query_speech flag. No voice in tech room, nothing from query_speech either. Edit: Attached an updated version of the patch with the chunks in the right places and some whitespace goofs fixed. |
|
macspeech5.patch (5,020 bytes)
diff --git code/sound/speech.cpp code/sound/speech.cpp index 14327a9..a152b57 100644 --- code/sound/speech.cpp +++ code/sound/speech.cpp @@ -29,6 +29,9 @@ #include <sphelper.h> ISpVoice *Voice_device; +#elif defined(__APPLE__) +#include <ApplicationServices/ApplicationServices.h> + SpeechChannel speech_channel; #elif defined(SCP_UNIX) #include <fcntl.h> // #include <stdio.h> @@ -56,13 +59,18 @@ bool speech_init() (void **)&Voice_device); Speech_init = SUCCEEDED(hr); +#elif defined(__APPLE__) + OSErr err; + err = NewSpeechChannel(NULL, &speech_channel); + if (err) { + return false; + } + Speech_init = true; #else speech_dev = open("/dev/speech", O_WRONLY | O_DIRECT); -// speech_dev = fopen("/dev/speech", "w"); if (speech_dev == -1) { -// if (speech_dev == NULL) { mprintf(("Couldn't open '/dev/speech', turning text-to-speech off...\n")); return false; } @@ -79,9 +87,10 @@ void speech_deinit() #ifdef _WIN32 Voice_device->Release(); +#elif defined(__APPLE__) + DisposeSpeechChannel(speech_channel); #else close(speech_dev); -// fclose(speech_dev); #endif } @@ -113,6 +122,35 @@ bool speech_play(const char *text) speech_stop(); return SUCCEEDED(Voice_device->Speak(Conversion_buffer, SPF_ASYNC, NULL)); +#elif defined(__APPLE__) + int len = strlen(text); + char Conversion_buffer[MAX_SPEECH_CHAR_LEN]; + + if(len > (MAX_SPEECH_CHAR_LEN - 1)) { + len = MAX_SPEECH_CHAR_LEN - 1; + } + + int count = 0; + for(int i = 0; i < len; i++) { + if(text[i] == '$') { + i++; + continue; + } + if(text[i] == '\n') { + Conversion_buffer[count] = '\n'; + count++; + } + + Conversion_buffer[count] = text[i]; + count++; + } + + Conversion_buffer[count] = '\0'; + + CFStringRef speech_string = CFStringCreateWithCString(NULL, Conversion_buffer, kCFStringEncodingASCII); + OSErr err = SpeakCFString(speech_channel, speech_string, NULL); + CFRelease(speech_string); + return !err; #else int len = strlen(text); char Conversion_buffer[MAX_SPEECH_CHAR_LEN]; @@ -150,6 +188,8 @@ bool speech_pause() if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Pause()); +#elif defined(__APPLE__) + return !PauseSpeechAt(speech_channel, kEndOfWord); #else STUB_FUNCTION; @@ -162,6 +202,8 @@ bool speech_resume() if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Resume()); +#elif defined(__APPLE__) + return !ContinueSpeech(speech_channel); #else STUB_FUNCTION; @@ -174,6 +216,8 @@ bool speech_stop() if(Speech_init == false) return true; #ifdef _WIN32 return SUCCEEDED(Voice_device->Speak( NULL, SPF_PURGEBEFORESPEAK, NULL )); +#elif defined(__APPLE__) + return !StopSpeechAt(speech_channel, kEndOfWord); #else STUB_FUNCTION; @@ -185,6 +229,10 @@ bool speech_set_volume(unsigned short volume) { #ifdef _WIN32 return SUCCEEDED(Voice_device->SetVolume(volume)); +#elif defined(__APPLE__) + OSErr err = SetSpeechInfo(speech_channel, soVolume, &volume); + if (err) return false; + return true; #else STUB_FUNCTION; @@ -228,6 +276,9 @@ bool speech_set_voice(int voice) count++; } return false; +#elif defined(__APPLE__) + STUB_FUNCTION; + return true; #else STUB_FUNCTION; @@ -246,6 +297,11 @@ bool speech_is_speaking() if (FAILED(hr)) return false; return (pStatus.dwRunningState != SPRS_DONE); +#elif defined(__APPLE__) + SpeechStatusInfo status; + OSErr err = GetSpeechInfo(speech_channel, soStatus, &status); + if (err) return false; + return status.outputBusy; #else STUB_FUNCTION; diff --git configure.ac configure.ac index 88127a9..0dc4429 100644 --- configure.ac +++ configure.ac @@ -396,6 +396,7 @@ elif test "$fs2_os_osx" = "yes" ; then FS2_CXXFLAGS="$FS2_CXXFLAGS -I/System/Library/Frameworks/OpenGL.framework/Headers" FS2_LDFLAGS="$FS2_LDFLAGS -framework OpenGL" AC_DEFINE([SCP_UNIX]) + AC_DEFINE([FS2_SPEECH]) AC_DEFINE([NO_DIRECT3D]) ## don't need the CFLAGS here if recent SDL is used elif test "$fs2_os_solaris" = "yes" ; then @@ -474,7 +475,7 @@ fi dnl extra OSX frameworks if test "$fs2_os_osx" = "yes" ; then - FS2_LDFLAGS="$FS2_LDFLAGS -framework AppKit -framework Foundation" + FS2_LDFLAGS="$FS2_LDFLAGS -framework AppKit -framework Foundation -framework ApplicationServices" fi diff --git projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj index 06a4269..fc79fd3 100755 --- projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj +++ projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj @@ -4447,6 +4447,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -4494,6 +4495,7 @@ SCP_UNIX, USE_OPENAL, APPLE_APP, + FS2_SPEECH, ); GCC_STRICT_ALIASING = YES; GCC_UNROLL_LOOPS = YES; |
|
Log excerpt: ... OpenAL successfully initialized! Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] Why are you trying to free a NULL pointer? [fsmemory.cpp(19)] STUB: speech_set_voice in /Users/cliff.gordon/fs2_open_git/code/sound/speech.cpp at line 280, thread 6729 Initializing OpenGL graphics device at 640x480 with 32-bit color... |
Date Modified | Username | Field | Change |
---|---|---|---|
2012-04-13 04:20 | gereedy | New Issue | |
2012-04-13 04:20 | gereedy | File Added: macspeech.patch | |
2012-04-13 06:16 | niffiwan | Severity | minor => feature |
2012-04-13 19:54 | gereedy | Note Added: 0013464 | |
2012-04-13 19:54 | gereedy | File Added: macspeech2.patch | |
2012-04-23 13:53 | Echelon9 | Assigned To | => Echelon9 |
2012-04-23 13:53 | Echelon9 | Status | new => code review |
2012-04-23 14:08 | Echelon9 | Note Added: 0013479 | |
2012-04-30 04:26 | gereedy | Note Added: 0013490 | |
2012-04-30 15:30 | Echelon9 | Note Added: 0013492 | |
2012-05-04 03:00 | gereedy | Note Added: 0013515 | |
2012-05-09 19:07 | chief1983 | Note Added: 0013530 | |
2012-08-14 13:51 | Echelon9 | Note Added: 0013905 | |
2012-08-14 14:16 | Echelon9 | File Added: macspeech3.patch | |
2012-08-14 14:16 | Echelon9 | Note Added: 0013906 | |
2014-06-30 22:18 | chief1983 | Note Added: 0015977 | |
2014-06-30 22:20 | chief1983 | File Added: macspeech4.patch | |
2014-06-30 22:21 | chief1983 | Note Added: 0015978 | |
2014-06-30 22:22 | chief1983 | Note Edited: 0015978 | |
2014-07-01 00:26 | Echelon9 | Note Added: 0015981 | |
2014-07-01 12:08 | Echelon9 | Note Added: 0016000 | |
2014-07-01 13:57 | chief1983 | Note Added: 0016002 | |
2014-07-01 14:11 | Echelon9 | Note Added: 0016003 | |
2014-07-01 14:36 | chief1983 | Note Added: 0016004 | |
2014-07-01 14:36 | chief1983 | Note Edited: 0016004 | |
2014-07-01 15:09 | Echelon9 | Note Added: 0016005 | |
2015-04-23 15:16 | chief1983 | Note Added: 0016654 | |
2015-04-23 17:06 | chief1983 | Note Added: 0016655 | |
2015-04-23 17:09 | chief1983 | File Added: macspeech5.patch | |
2015-04-23 17:09 | chief1983 | Note Edited: 0016655 | |
2015-04-23 17:39 | chief1983 | Note Added: 0016657 |