Yeah, put that in this morning, I was just wondering is there was a more formal way, maybe a generic piece of Java or something ....I don't know this specific case; but, generally, I would use a Try-Catch block, setting a property.
I took a look; it does not seem to me that it should be initialized, only "imported" (checked) and used.I don't know this specific case; but
I took a look; it does not seem to me that it should be initialized, only "imported" (checked) and used.
An AudioStreamer object must be inizialized, not the Audio library itself.
I don't know the library; try searching:
https://www.b4x.com/android/forum/pages/results/?query=audiostreamer+audiosource
Posting your code would help.
What were the parameters you used? Not all devices support all possible parameters.
What do you get if you try logging your audiostream object when it fails?
Sub init_stream
Dim p As Phone
Dim mono As Boolean = True
mod_functions.writelog("svc_data(" & Main.APPSET.currentChannel.channel_id & "), init_stream, Sample Rate " & _
Main.APPSET.currentChannel.pcm_samplerate & ", Encoding " & _
Main.APPSET.currentChannel.pcm_endcoding )
' // https://developer.android.com/reference/android/media/MediaRecorder.AudioSource
Try
If p.SdkVersion = 21 Or p.SdkVersion = 22 Then
' // VOICE_COMMUNICATION
If Main.APPSET.ptt_device.connected Then
audioStream.Initialize2(7,"AudioStream", _
Main.APPSET.currentChannel.pcm_samplerate, _
mono, _
Main.APPSET.currentChannel.pcm_endcoding, _
audioStream.VOLUME_VOICE_CALL)
Else
audioStream.Initialize2(7,"AudioStream", _
Main.APPSET.currentChannel.pcm_samplerate, _
mono, _
Main.APPSET.currentChannel.pcm_endcoding, _
audioStream.VOLUME_MUSIC)
End If
Else
' // MIC
audioStream.Initialize2(1,"AudioStream", _
Main.APPSET.currentChannel.pcm_samplerate, _
mono, _
Main.APPSET.currentChannel.pcm_endcoding, _
audioStream.VOLUME_MUSIC)
End If
Catch
mod_functions.writeLog("connector:init_stream() error - " & LastException.Message)
End Try
End Sub
Sub register_listen
Dim failedToPlay As Boolean
Try
audioStream.StartPlaying
Catch
mod_functions.writelog("svc_data(), register_listen(), error - " & LastException.Message)
failedToPlay = True
init_stream
End Try
Try
If failedToPlay Then
audioStream.StartPlaying
End If
listeningForAudio = True
QualityCheck = 0
udpSck.Initialize("udpSocket",0,2048)
Dim data() As Byte
data = Main.APPSET.imei.GetBytes("UTF8")
Dim p As UDPPacket
p.Initialize(data,Main.APPSET.currentChannel.host,Main.APPSET.currentChannel.udp_listener)
udpSck.Send(p)
tmrQualityCheck.Enabled = True
mod_functions.writelog("svc_data(), register_listen() " & Main.APPSET.currentChannel.host & ":" & Main.APPSET.currentChannel.udp_listener)
Catch
mod_functions.writelog("svc_data(), register_listen(), error - " & LastException.Message)
End Try
End Sub
Sub unregister_listen
Try
' // call Quality
tmrQualityCheck.Enabled = False
IsRemoteSpeaker = False
listeningForAudio = False
QualityCheck = 0
udpSck.close
audioStream.StopPlaying
Catch
mod_functions.writeLog("svc_data(), unregister_listen(), error - " & LastException.Message)
End Try
End Sub
No clue if it is related, but looking at the state diagram of MediaRecorder (https://developer.android.com/reference/android/media/MediaRecorder), there are many situations in which reset() seems to be called that reverts the object back to a pre-setAudioSource state (looks like that method part of the Initialize method of AudioStreamer class). Please note that AudioStreamer is a combo of MediaRecorder and AudioTrack.
Is audiostream declared in Process_Globals or Globals?
Sub SendAudio
mod_functions.writelog("svc_data(), SendAudio")
' // check is we are still ptt key down
If Main.APPSET.currentChannel.ptt_state <> 2 Then
Return
End If
Try
udpSckTalk.Initialize("",0,0)
audioStream.StartRecording
sendingAudio = True
Catch
mod_functions.writelog("svc_data(),SendAudio() error - " & LastException.Message )
End Try
End Sub
Sub register_listen
Dim failedToPlay As Boolean
Try
audioStream.StopPlaying
audioStream.StartPlaying
Catch
mod_functions.writelog("svc_data(), register_listen(), error - " & LastException.Message)
failedToPlay = True
init_stream
End Try
Try
If failedToPlay Then
audioStream.StopPlaying
audioStream.StartPlaying
End If
listeningForAudio = True
QualityCheck = 0
udpSck.Initialize("udpSocket",0,2048)
Dim data() As Byte
data = Main.APPSET.imei.GetBytes("UTF8")
Dim p As UDPPacket
p.Initialize(data,Main.APPSET.currentChannel.host,Main.APPSET.currentChannel.udp_listener)
udpSck.Send(p)
tmrQualityCheck.Enabled = True
mod_functions.writelog("svc_data(), register_listen() " & Main.APPSET.currentChannel.host & ":" & Main.APPSET.currentChannel.udp_listener)
Catch
mod_functions.writelog("svc_data(), register_listen(), error - " & LastException.Message)
End Try
End Sub
Public Sub StopSendingAudio
mod_functions.writelog("svc_data(), StopSendingAudio")
Try
udpSckTalk.Close
audioStream.StopRecording
sendingAudio = False
Catch
mod_functions.writelog("svc_data(),StopSendingAudio() error - " & LastException.Message )
End Try
End Sub
Sub unregister_listen
Try
' // call Quality
tmrQualityCheck.Enabled = False
IsRemoteSpeaker = False
listeningForAudio = False
QualityCheck = 0
udpSck.close
audioStream.StopPlaying
Catch
mod_functions.writeLog("svc_data(), unregister_listen(), error - " & LastException.Message)
End Try
End Sub
java.lang.IllegalStateException: play() called on uninitialized AudioTrack
I log everything, it is an unrecoverable error, even if you try to re-init the audiosteam is does not work. So, I will kill the service that uses it, and the service will get started again with the app.Clue from https://stackoverflow.com/a/12380380. It looks like it's something you just have to deal with. You could filter this out in your try catch block and just treat this error as recoverable and not-necessarily an issue to be logged, unless you like to see how often this happens.
So, I will kill the server that uses it, and the service will get started again with the app.
Sub init_stream
Dim p As Phone
Dim mono As Boolean = True
Dim newAudioStream As AudioStreamer
mod_functions.writelog("svc_data(" & Main.APPSET.currentChannel.channel_id & "), init_stream, Sample Rate " & _
Main.APPSET.currentChannel.pcm_samplerate & ", Encoding " & _
Main.APPSET.currentChannel.pcm_endcoding )
' // https://developer.android.com/reference/android/media/MediaRecorder.AudioSource
Try
If p.SdkVersion = 21 Or p.SdkVersion = 22 Then
' // VOICE_COMMUNICATION
If Main.APPSET.ptt_device.connected Then
newAudioStream.Initialize2(7,"AudioStream", _
Main.APPSET.currentChannel.pcm_samplerate, _
mono, _
Main.APPSET.currentChannel.pcm_endcoding, _
audioStream.VOLUME_VOICE_CALL)
Else
newAudioStream.Initialize2(7,"AudioStream", _
Main.APPSET.currentChannel.pcm_samplerate, _
mono, _
Main.APPSET.currentChannel.pcm_endcoding, _
audioStream.VOLUME_MUSIC)
End If
Else
' // MIC
newAudioStream.Initialize2(1,"AudioStream", _
Main.APPSET.currentChannel.pcm_samplerate, _
mono, _
Main.APPSET.currentChannel.pcm_endcoding, _
audioStream.VOLUME_MUSIC)
End If
audioStream = newAudioStream
Catch
mod_functions.writeLog("connector:init_stream() error - " & LastException.Message)
End Try
End Sub
I've noticed that you are re-using the same audiostream object in your init code. Have you tried dim'ing a new one, initializing it and then assigning it to your global variable?
Technically you would also need to know if the previous audioStream was set to recording and maybe try to stop it from recording (this may be futile attempt, since the object is "reset") before initializing a new audioStream object and re-enabling recording with the new audioStream object.B4X:Sub init_stream Dim p As Phone Dim mono As Boolean = True Dim newAudioStream As AudioStreamer mod_functions.writelog("svc_data(" & Main.APPSET.currentChannel.channel_id & "), init_stream, Sample Rate " & _ Main.APPSET.currentChannel.pcm_samplerate & ", Encoding " & _ Main.APPSET.currentChannel.pcm_endcoding ) ' // https://developer.android.com/reference/android/media/MediaRecorder.AudioSource Try If p.SdkVersion = 21 Or p.SdkVersion = 22 Then ' // VOICE_COMMUNICATION If Main.APPSET.ptt_device.connected Then newAudioStream.Initialize2(7,"AudioStream", _ Main.APPSET.currentChannel.pcm_samplerate, _ mono, _ Main.APPSET.currentChannel.pcm_endcoding, _ audioStream.VOLUME_VOICE_CALL) Else newAudioStream.Initialize2(7,"AudioStream", _ Main.APPSET.currentChannel.pcm_samplerate, _ mono, _ Main.APPSET.currentChannel.pcm_endcoding, _ audioStream.VOLUME_MUSIC) End If Else ' // MIC newAudioStream.Initialize2(1,"AudioStream", _ Main.APPSET.currentChannel.pcm_samplerate, _ mono, _ Main.APPSET.currentChannel.pcm_endcoding, _ audioStream.VOLUME_MUSIC) End If audioStream = newAudioStream Catch mod_functions.writeLog("connector:init_stream() error - " & LastException.Message) End Try End Sub
the fact that it reset(), i kind of game over.
Dim'ing a new object should take care of the reset(), since now the old audioStreamer object is just not used anymore. I do not know if the old audioStreamer object would keep the hardware tied up, but I would guess no, since each reset() seems to require a setAudioSource call to use an audio device again. Of course, this is all just speculation, since I really don't know what is happening under the hood and I'm just going by the state diagram in the link above. The only other item to watch out for is an active record session. Before creating the new audioStreamer object an active recording would need to be stopped (if possible) and then re-established with the newly created audioStreamer object.