Reply To: How to deallocate OpenEars singleton (2.0) ?

Home Forums OpenEars How to deallocate OpenEars singleton (2.0) ? Reply To: How to deallocate OpenEars singleton (2.0) ?

#1026677
pizigi
Participant

Yes, I can understand that. If destroying the singleton is not officially supported, I won’t insist on asking about it any further.

By the way, I must mention that OpenEars works well with Unity as long as I keep it listening. Once StopListening is called though, things can get quirky – and that’s why I avoid calling it during my application’s lifetime. However, plugging the headphones is causing StopListening to be called without my consent, so I’m trying to find a way to deal with it.

About the audio usage in the app, it continuously plays music and sound effects – nothing out of the ordinary at all.
It could be that Unity is also reacting to the plugging of the headphones, causing some race condition on the audio session.

About my logs, I’m sorry I totally forgot to turn on verbosePocketsphinx.
I’ve now turned it on, here are the detailed logs when I plug in the headphones:

2015-08-30 18:47:12.624 mathcommand[517:53825] Audio route has changed for the following reason:
2015-08-30 18:47:12.626 mathcommand[517:53825] A new device is available
2015-08-30 18:47:12.627 mathcommand[517:53825] The audio input is available
2015-08-30 18:47:12.627 mathcommand[517:54064] A request has been made to start a listening session using startListeningWithLanguageModelAtPath:dictionaryAtPath:acousticModelAtPath:languageModelIsJSGF:, however, there is already a listening session in progress which has not been stopped. Please stop this listening session first with [[OEPocketsphinxController sharedInstance] stopListening]; and wait to receive the OEEventsObserver callback pocketsphinxDidStopListening before starting a new session. You can still change models in the existing session by using OEPocketsphinxController's method changeLanguageModelToFile:withDictionary:
2015-08-30 18:47:12.629 mathcommand[517:53825] This is a case for performing a route change. Before the route change, the current route was HeadphonesMicrophoneWired. Performing route change.
2015-08-30 18:47:12.636 mathcommand[517:53825] Audio route change. The new audio route is HeadphonesMicrophoneWired
2015-08-30 18:47:12.636 mathcommand[517:53825] Stopping listening.
2015-08-30 18:47:14.054 mathcommand[517:53825] 18:47:14.053 ERROR:     [0x359209dc] AVAudioSession.mm:646: -[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.
2015-08-30 18:47:14.055 mathcommand[517:53825] Error: couldn't set session inactive.: '!act'
2015-08-30 18:47:14.064 mathcommand[517:53825] Error: there was a problem tearing down the audio session: Error Domain=NSOSStatusErrorDomain Code=560030580 "The operation couldn’t be completed. (OSStatus error 560030580.)".
2015-08-30 18:47:14.065 mathcommand[517:53825] Unable to stop listening because because an utterance is still in progress; trying again.
2015-08-30 18:47:14.116 mathcommand[517:53825] Attempting to stop an unstopped utterance so listening can stop.
INFO: cmn_prior.c(131): cmn_prior_update: from < 59.69 -4.47 -10.29 -7.20 -17.60  2.49 -8.36 -10.72  1.61  1.11 -9.08  3.88  2.02 >
INFO: cmn_prior.c(149): cmn_prior_update: to   < 59.87 -4.03 -10.01 -6.71 -17.52  2.57 -8.13 -10.16  1.73  1.15 -8.93  3.75  1.99 >
INFO: ngram_search_fwdtree.c(1553):      159 words recognized (8/fr)
INFO: ngram_search_fwdtree.c(1555):     3443 senones evaluated (181/fr)
INFO: ngram_search_fwdtree.c(1559):     1586 channels searched (83/fr), 270 1st, 762 last
INFO: ngram_search_fwdtree.c(1562):      264 words for which last channels evaluated (13/fr)
INFO: ngram_search_fwdtree.c(1564):      110 candidate words for entering last phone (5/fr)
INFO: ngram_search_fwdtree.c(1567): fwdtree 1.10 CPU 5.797 xRT
INFO: ngram_search_fwdtree.c(1570): fwdtree 3.63 wall 19.090 xRT
INFO: ngram_search_fwdflat.c(302): Utterance vocabulary contains 3 words
INFO: ngram_search_fwdflat.c(948):      123 words recognized (6/fr)
INFO: ngram_search_fwdflat.c(950):      534 senones evaluated (28/fr)
INFO: ngram_search_fwdflat.c(952):      153 channels searched (8/fr)
INFO: ngram_search_fwdflat.c(954):      153 words searched (8/fr)
INFO: ngram_search_fwdflat.c(957):       54 word transitions (2/fr)
INFO: ngram_search_fwdflat.c(960): fwdflat 0.00 CPU 0.020 xRT
INFO: ngram_search_fwdflat.c(963): fwdflat 0.00 wall 0.024 xRT
INFO: ngram_search_fwdtree.c(432): TOTAL fwdtree 6.36 CPU 1.545 xRT
INFO: ngram_search_fwdtree.c(435): TOTAL fwdtree 17.69 wall 4.293 xRT
INFO: ngram_search_fwdflat.c(176): TOTAL fwdflat 0.15 CPU 0.037 xRT
INFO: ngram_search_fwdflat.c(179): TOTAL fwdflat 0.21 wall 0.050 xRT
INFO: ngram_search.c(307): TOTAL bestpath 0.04 CPU 0.011 xRT
INFO: ngram_search.c(310): TOTAL bestpath 0.05 wall 0.012 xRT
2015-08-30 18:47:14.134 mathcommand[517:53825] No longer listening.
2015-08-30 18:47:14.136 mathcommand[517:53825] Pocketsphinx has stopped listening.
2015-08-30 18:47:14.137 mathcommand[517:54064] A request has been made to start a listening session using startListeningWithLanguageModelAtPath:dictionaryAtPath:acousticModelAtPath:languageModelIsJSGF:, however, there is already a listening session in progress which has not been stopped. Please stop this listening session first with [[OEPocketsphinxController sharedInstance] stopListening]; and wait to receive the OEEventsObserver callback pocketsphinxDidStopListening before starting a new session. You can still change models in the existing session by using OEPocketsphinxController's method changeLanguageModelToFile:withDictionary:
2015-08-30 18:47:14.145 mathcommand[517:53825] Audio route has changed for the following reason:
2015-08-30 18:47:14.146 mathcommand[517:53825] There was a category change. The new category is AVAudioSessionCategoryPlayAndRecord
2015-08-30 18:47:14.149 mathcommand[517:53825] This is not a case in which OpenEars notifies of a route change. At the close of this function, the new audio route is ---Headphones---. The previous route before changing to this route was <AVAudioSessionRouteDescription: 0x1632ea90, 
inputs = (
    "<AVAudioSessionPortDescription: 0x163b2a20, type = MicrophoneWired; name = Headset Microphone; UID = Wired Microphone; selectedDataSource = (null)>"
); 
outputs = (
    "<AVAudioSessionPortDescription: 0x16393a10, type = Headphones; name = Headphones; UID = Wired Headphones; selectedDataSource = (null)>"
)>.

It doesn’t look like it prints much more information than what we already had before, though.
Here’s a full log of my OpenEars initialization, at application startup:

2015-08-30 19:13:07.257 mathcommand[542:57739] Creating shared instance of OEPocketsphinxController
2015-08-30 19:13:07.260 mathcommand[542:57739] Attempting to start listening session from startListeningWithLanguageModelAtPath:
[PocketSphinx] Recognition Setup Completed
 
(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)

2015-08-30 19:13:07.265 mathcommand[542:57739] User gave mic permission for this app.
2015-08-30 19:13:07.266 mathcommand[542:57739] Valid setSecondsOfSilence value of 0.100000 will be used.
2015-08-30 19:13:07.267 mathcommand[542:57749] Starting listening.
2015-08-30 19:13:07.267 mathcommand[542:57749] about to set up audio session
2015-08-30 19:13:07.269 mathcommand[542:57739] Successfully started listening session from startListeningWithLanguageModelAtPath:
2015-08-30 19:13:07.817 mathcommand[542:57749] Creating audio session with default settings.
2015-08-30 19:13:07.819 mathcommand[542:57601] Audio route has changed for the following reason:
2015-08-30 19:13:07.821 mathcommand[542:57601] There was a category change. The new category is AVAudioSessionCategoryPlayAndRecord
2015-08-30 19:13:07.855 mathcommand[542:57601] This is not a case in which OpenEars notifies of a route change. At the close of this function, the new audio route is ---SpeakerMicrophoneBuiltIn---. The previous route before changing to this route was <AVAudioSessionRouteDescription: 0x18344430, 
inputs = (null); 
outputs = (
    "<AVAudioSessionPortDescription: 0x16fd5270, type = Speaker; name = Speaker; UID = Speaker; selectedDataSource = (null)>"
)>.
2015-08-30 19:13:07.863 mathcommand[542:57601] Audio route has changed for the following reason:
2015-08-30 19:13:07.863 mathcommand[542:57601] There was a category change. The new category is AVAudioSessionCategoryPlayAndRecord
2015-08-30 19:13:07.865 mathcommand[542:57601] This is not a case in which OpenEars notifies of a route change. At the close of this function, the new audio route is ---SpeakerMicrophoneBuiltIn---. The previous route before changing to this route was <AVAudioSessionRouteDescription: 0x182f9250, 
inputs = (
    "<AVAudioSessionPortDescription: 0x1828cca0, type = MicrophoneBuiltIn; name = iPhone Microphone; UID = Built-In Microphone; selectedDataSource = Bottom>"
); 
outputs = (
    "<AVAudioSessionPortDescription: 0x182ade70, type = Receiver; name = Receiver; UID = Built-In Receiver; selectedDataSource = (null)>"
)>.
2015-08-30 19:13:07.876 mathcommand[542:57749] done starting audio unit
INFO: cmd_ln.c(703): Parsing command line:
\
	-lm /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/LanguageModels.bundle/LanguageModel.dmp \
	-vad_prespeech 10 \
	-vad_postspeech 10 \
	-vad_threshold 2.500000 \
	-remove_noise yes \
	-remove_silence yes \
	-bestpath yes \
	-lw 6.500000 \
	-dict /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/LanguageModels.bundle/EnglishLanguageModel.dic \
	-hmm /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle 

Current configuration:
[NAME]			[DEFLT]		[VALUE]
-agc			none		none
-agcthresh		2.0		2.000000e+00
-allphone				
-allphone_ci		no		no
-alpha			0.97		9.700000e-01
-argfile				
-ascale			20.0		2.000000e+01
-aw			1		1
-backtrace		no		no
-beam			1e-48		1.000000e-48
-bestpath		yes		yes
-bestpathlw		9.5		9.500000e+00
-ceplen			13		13
-cmn			current		current
-cmninit		8.0		8.0
-compallsen		no		no
-debug					0
-dict					/private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/LanguageModels.bundle/EnglishLanguageModel.dic
-dictcase		no		no
-dither			no		no
-doublebw		no		no
-ds			1		1
-fdict					
-feat			1s_c_d_dd	1s_c_d_dd
-featparams				
-fillprob		1e-8		1.000000e-08
-frate			100		100
-fsg					
-fsgusealtpron		yes		yes
-fsgusefiller		yes		yes
-fwdflat		yes		yes
-fwdflatbeam		1e-64		1.000000e-64
-fwdflatefwid		4		4
-fwdflatlw		8.5		8.500000e+00
-fwdflatsfwin		25		25
-fwdflatwbeam		7e-29		7.000000e-29
-fwdtree		yes		yes
-hmm					/private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle
-input_endian		little		little
-jsgf					
-keyphrase				
-kws					
-kws_delay		10		10
-kws_plp		1e-1		1.000000e-01
-kws_threshold		1		1.000000e+00
-latsize		5000		5000
-lda					
-ldadim			0		0
-lifter			0		0
-lm					/private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/LanguageModels.bundle/LanguageModel.dmp
-lmctl					
-lmname					
-logbase		1.0001		1.000100e+00
-logfn					
-logspec		no		no
-lowerf			133.33334	1.333333e+02
-lpbeam			1e-40		1.000000e-40
-lponlybeam		7e-29		7.000000e-29
-lw			6.5		6.500000e+00
-maxhmmpf		30000		30000
-maxwpf			-1		-1
-mdef					
-mean					
-mfclogdir				
-min_endfr		0		0
-mixw					
-mixwfloor		0.0000001	1.000000e-07
-mllr					
-mmap			yes		yes
-ncep			13		13
-nfft			512		512
-nfilt			40		40
-nwpen			1.0		1.000000e+00
-pbeam			1e-48		1.000000e-48
-pip			1.0		1.000000e+00
-pl_beam		1e-10		1.000000e-10
-pl_pbeam		1e-10		1.000000e-10
-pl_pip			1.0		1.000000e+00
-pl_weight		3.0		3.000000e+00
-pl_window		5		5
-rawlogdir				
-remove_dc		no		no
-remove_noise		yes		yes
-remove_silence		yes		yes
-round_filters		yes		yes
-samprate		16000		1.600000e+04
-seed			-1		-1
-sendump				
-senlogdir				
-senmgau				
-silprob		0.005		5.000000e-03
-smoothspec		no		no
-svspec					
-tmat					
-tmatfloor		0.0001		1.000000e-04
-topn			4		4
-topn_beam		0		0
-toprule				
-transform		legacy		legacy
-unit_area		yes		yes
-upperf			6855.4976	6.855498e+03
-uw			1.0		1.000000e+00
-vad_postspeech		50		10
-vad_prespeech		20		10
-vad_startspeech	10		10
-vad_threshold		2.0		2.500000e+00
-var					
-varfloor		0.0001		1.000000e-04
-varnorm		no		no
-verbose		no		no
-warp_params				
-warp_type		inverse_linear	inverse_linear
-wbeam			7e-29		7.000000e-29
-wip			0.65		6.500000e-01
-wlen			0.025625	2.562500e-02

INFO: cmd_ln.c(703): Parsing command line:
\
	-nfilt 25 \
	-lowerf 130 \
	-upperf 6800 \
	-feat 1s_c_d_dd \
	-svspec 0-12/13-25/26-38 \
	-agc none \
	-cmn current \
	-varnorm no \
	-transform dct \
	-lifter 22 \
	-cmninit 40 

Current configuration:
[NAME]			[DEFLT]		[VALUE]
-agc			none		none
-agcthresh		2.0		2.000000e+00
-alpha			0.97		9.700000e-01
-ceplen			13		13
-cmn			current		current
-cmninit		8.0		40
-dither			no		no
-doublebw		no		no
-feat			1s_c_d_dd	1s_c_d_dd
-frate			100		100
-input_endian		little		little
-lda					
-ldadim			0		0
-lifter			0		22
-logspec		no		no
-lowerf			133.33334	1.300000e+02
-ncep			13		13
-nfft			512		512
-nfilt			40		25
-remove_dc		no		no
-remove_noise		yes		yes
-remove_silence		yes		yes
-round_filters		yes		yes
-samprate		16000		1.600000e+04
-seed			-1		-1
-smoothspec		no		no
-svspec					0-12/13-25/26-38
-transform		legacy		dct
-unit_area		yes		yes
-upperf			6855.4976	6.800000e+03
-vad_postspeech		50		10
-vad_prespeech		20		10
-vad_startspeech	10		10
-vad_threshold		2.0		2.500000e+00
-varnorm		no		no
-verbose		no		no
-warp_params				
-warp_type		inverse_linear	inverse_linear
-wlen			0.025625	2.562500e-02

INFO: acmod.c(252): Parsed model-specific feature parameters from /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle/feat.params
INFO: feat.c(715): Initializing feature stream to type: '1s_c_d_dd', ceplen=13, CMN='current', VARNORM='no', AGC='none'
INFO: cmn.c(143): mean[0]= 12.00, mean[1..12]= 0.0
INFO: acmod.c(171): Using subvector specification 0-12/13-25/26-38
INFO: mdef.c(518): Reading model definition: /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle/mdef
INFO: mdef.c(531): Found byte-order mark BMDF, assuming this is a binary mdef file
INFO: bin_mdef.c(336): Reading binary model definition: /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle/mdef
INFO: bin_mdef.c(516): 46 CI-phone, 168344 CD-phone, 3 emitstate/phone, 138 CI-sen, 6138 Sen, 32881 Sen-Seq
INFO: tmat.c(206): Reading HMM transition probability matrices: /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle/transition_matrices
INFO: acmod.c(124): Attempting to use PTM computation module
INFO: ms_gauden.c(198): Reading mixture gaussian parameter: /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle/means
INFO: ms_gauden.c(292): 1 codebook, 3 feature, size: 
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(198): Reading mixture gaussian parameter: /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle/variances
INFO: ms_gauden.c(292): 1 codebook, 3 feature, size: 
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(354): 0 variance values floored
INFO: ptm_mgau.c(805): Number of codebooks doesn't match number of ciphones, doesn't look like PTM: 1 != 46
INFO: acmod.c(126): Attempting to use semi-continuous computation module
INFO: ms_gauden.c(198): Reading mixture gaussian parameter: /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle/means
INFO: ms_gauden.c(292): 1 codebook, 3 feature, size: 
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(198): Reading mixture gaussian parameter: /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle/variances
INFO: ms_gauden.c(292): 1 codebook, 3 feature, size: 
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(294):  512x13
INFO: ms_gauden.c(354): 0 variance values floored
INFO: s2_semi_mgau.c(904): Loading senones from dump file /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle/sendump
INFO: s2_semi_mgau.c(928): BEGIN FILE FORMAT DESCRIPTION
INFO: s2_semi_mgau.c(991): Rows: 512, Columns: 6138
INFO: s2_semi_mgau.c(1023): Using memory-mapped I/O for senones
INFO: s2_semi_mgau.c(1294): Maximum top-N: 4 Top-N beams: 0 0 0
INFO: phone_loop_search.c(114): State beam -225 Phone exit beam -225 Insertion penalty 0
INFO: dict.c(320): Allocating 4224 * 20 bytes (82 KiB) for word entries
INFO: dict.c(333): Reading main dictionary: /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/LanguageModels.bundle/EnglishLanguageModel.dic
INFO: dict.c(213): Allocated 0 KiB for strings, 1 KiB for phones
INFO: dict.c(336): 119 words read
INFO: dict.c(358): Reading filler dictionary: /private/var/mobile/Containers/Bundle/Application/47CE4D3C-BB6B-4309-B0BA-A800D6160E30/mathcommand.app/AcousticModelEnglish.bundle/noisedict
INFO: dict.c(213): Allocated 0 KiB for strings, 0 KiB for phones
INFO: dict.c(361): 9 words read
INFO: dict2pid.c(396): Building PID tables for dictionary
INFO: dict2pid.c(406): Allocating 46^3 * 2 bytes (190 KiB) for word-initial triphones
INFO: dict2pid.c(132): Allocated 25576 bytes (24 KiB) for word-final triphones
INFO: dict2pid.c(196): Allocated 25576 bytes (24 KiB) for single-phone word triphones
INFO: ngram_model_arpa.c(77): No \data\ mark in LM file
INFO: ngram_model_dmp.c(166): Will use memory-mapped I/O for LM file
INFO: ngram_model_dmp.c(220): ngrams 1=119, 2=234, 3=117
INFO: ngram_model_dmp.c(266):      119 = LM.unigrams(+trailer) read
INFO: ngram_model_dmp.c(312):      234 = LM.bigrams(+trailer) read
INFO: ngram_model_dmp.c(338):      117 = LM.trigrams read
INFO: ngram_model_dmp.c(363):        3 = LM.prob2 entries read
INFO: ngram_model_dmp.c(383):        3 = LM.bo_wt2 entries read
INFO: ngram_model_dmp.c(403):        2 = LM.prob3 entries read
INFO: ngram_model_dmp.c(431):        1 = LM.tseg_base entries read
INFO: ngram_model_dmp.c(487):      119 = ascii word strings read
INFO: ngram_search_fwdtree.c(99): 18 unique initial diphones
INFO: ngram_search_fwdtree.c(148): 0 root, 0 non-root channels, 17 single-phone words
INFO: ngram_search_fwdtree.c(186): Creating search tree
INFO: ngram_search_fwdtree.c(192): before: 0 root, 0 non-root channels, 17 single-phone words
INFO: ngram_search_fwdtree.c(326): after: max nonroot chan increased to 441
INFO: ngram_search_fwdtree.c(339): after: 18 root, 313 non-root channels, 16 single-phone words
INFO: ngram_search_fwdflat.c(157): fwdflat: min_ef_width = 4, max_sf_win = 25
2015-08-30 19:13:08.014 mathcommand[542:57749] There was no previous CMN value in the plist so we are using the fresh CMN value 42.000000.
2015-08-30 19:13:08.015 mathcommand[542:57749] Listening.
2015-08-30 19:13:08.016 mathcommand[542:57749] Project has these words or phrases in its dictionary:
0
1
10
100
11
12
13
14
15
16
17
18
19
2
20
200
21
22
23
24
25
26
27
28
29
3
30
300
31
32
33
...and 89 more.
2015-08-30 19:13:08.016 mathcommand[542:57749] Recognition loop has started
2015-08-30 19:13:08.018 mathcommand[542:57601] Pocketsphinx is now listening.

After this initialization sequence is complete, OpenEars is up and running and working just fine.

Lastly, I didn’t mention that I have a way to deal with most AudioSession woes by asking Unity to reset the audio system. That’s what I do if I ever need to call StopListening, and it basically reconfigures the AVAudioSession to a clean state.
So if I call StopListening() and reset the audio system in the pocketsphinxDidStopListening() callback, I’m usually fine.
However this solution is not working at the moment because of the locked state OEPocketSphinxController finds itself in after the user plugs in the headphones.

It would be great if I could get OEPocketSphinx to unlock itself somehow.