Weird. The bufferSizeInBytes should be logged...
Here's the full function with the traces:
Code: Select all
{$IFDEF CPU64}
function AudioCallback(P : pointer): Int64;
{$ELSE}
function AudioCallback(P : pointer): LongInt;
{$ENDIF}
const
OnePassSize = 512;
var
Env : PJNIEnv;
cAudioTrack : jclass;
mGetMinBufferSize, mAudioTrack, mPlay, mStop, mRelease, mWrite : JMethodID;
bufferSizeInBytes : integer;
track : jobject;
buffer : jarray;
Params : array[0..10] of integer;
PBuffer : pointer;
IsCopy : JBoolean;
CurrentFrameNumber: Integer; // Add frame number variable
function C(const args : array of const) : pointer;
var
I : integer;
begin
for I := 0 to High(args) do
Params[I] := args[I].vinteger;
Result := @Params;
end;
begin
Platform_error('AudioCallback: Audio callback started');
Result := 0;
if CurVM = nil then
begin
Platform_error('AudioCallback: CurVM is not initialized in AudioCallback');
Exit;
end;
if CurVM^.AttachCurrentThread(CurVM, @Env, nil) <> 0 then
begin
Platform_error('AudioCallback: Error attaching thread to JVM');
Exit;
end;
env^.PushLocalFrame(env, 2);
cAudioTrack := env^.FindClass(env, 'android/media/AudioTrack');
if cAudioTrack = nil then
begin
Platform_error('AudioCallback: no audiotrack');
Exit;
end
else
begin
Platform_error(PChar('AudioCallback: AudioTrack class found'));
end;
mGetMinBufferSize := env^.GetStaticMethodID(env, cAudioTrack, 'getMinBufferSize', '(III)I');
if mGetMinBufferSize = nil then
begin
Platform_error('AudioCallback: getMinBufferSize method not found');
Exit;
end
else
begin
Platform_error(PChar('AudioCallback: getMinBufferSize method found'));
end;
mAudioTrack := env^.GetMethodID(env, cAudioTrack, '<init>', '(IIIIII)V');
mPlay := env^.GetMethodID(env, cAudioTrack, 'play', '()V');
mStop := env^.GetMethodID(env, cAudioTrack, 'stop', '()V');
mRelease := env^.GetMethodID(env, cAudioTrack, 'release', '()V');
mWrite := env^.GetMethodID(env, cAudioTrack, 'write', '([BII)I');
Platform_error(PChar('AudioCallback: AudioRate: ' + IntToStr(AudioPlayer.AudioRate) + ', Params: 3, 2'));
bufferSizeInBytes := Env^.CallStaticIntMethodV(env, cAudioTrack, mGetMinBufferSize, C([AudioPlayer.AudioRate, 3, 2]));
Platform_error(PChar('!!!!!!!!! AudioCallback: Buffer size in bytes: ' + IntToStr(bufferSizeInBytes)));
if bufferSizeInBytes < 0 then
begin
Platform_error(PChar('AudioCallback: Error: getMinBufferSize returned a negative value: ' + IntToStr(bufferSizeInBytes)));
end
else
begin
Platform_error(PChar('AudioCallback: Buffer size in bytes: ' + IntToStr(bufferSizeInBytes)));
end;
track := env^.NewObjectV(env, cAudioTrack, mAudioTrack, C([3, AudioPlayer.AudioRate, 3, 2, bufferSizeInBytes, 1]));
if track = nil then
begin
Platform_error('AudioCallback: could not create track');
Exit;
end
else
begin
env^.CallNonvirtualVoidMethod(env, track, cAudioTrack, mPlay);
buffer := env^.NewByteArray(env, bufferSizeInBytes);
CurrentFrameNumber := 0; // Initialize frame number
while not AudioTerminated do
begin
PBuffer := env^.GetPrimitiveArrayCritical(env, buffer, IsCopy);
if PBuffer = nil then
begin
Platform_error('AudioCallback: Could not get primitive array critical');
Break; // Exit the loop if critical array retrieval fails
end;
// Mix audio data
MixAndCopyData(PBuffer, OnePassSize);
// Release the primitive array
env^.ReleasePrimitiveArrayCritical(env, buffer, PBuffer, 0);
// Write the audio data to the track
env^.CallNonvirtualIntMethodV(env, track, cAudioTrack, mWrite, C([buffer, 0, OnePassSize]));
// Check for JNI exceptions
if env^.ExceptionCheck(env) <> 0 then
begin
env^.ExceptionDescribe(env); // Log the exception
env^.ExceptionClear(env); // Clear the exception
Platform_error('AudioCallback: Error writing audio data due to an exception');
Break; // Exit the loop on error
end;
// Log the current frame number
Platform_error(PChar('AudioCallback: Processed audio frame: ' + IntToStr(CurrentFrameNumber)));
Inc(CurrentFrameNumber); // Increment the frame number for the next log entry
// Sleep briefly to prevent sound breaking up
Platform_Sleep(1);
end;
env^.CallNonvirtualVoidMethod(env, track, cAudioTrack, mStop);
env^.CallNonvirtualVoidMethod(env, track, cAudioTrack, mRelease);
end;
Env^.PopLocalFrame(Env, nil);
CurVM^.DetachCurrentThread(CurVM);
end;
If I use:
bufferSizeInBytes := Env^.CallStaticIntMethodV(env, cAudioTrack, mGetMinBufferSize, C([AudioPlayer.AudioRate, 3, 2]));
track := env^.NewObjectV(env, cAudioTrack, mAudioTrack, C([3, AudioPlayer.AudioRate, 3, 2, bufferSizeInBytes, 1]));
It only logs:
Code: Select all
10-08 12:25:40.322 26588 26639 E ZgeAndroid: AudioCallback: Audio callback started
10-08 12:25:40.323 26588 26639 E ZgeAndroid: AudioCallback: AudioTrack class found
10-08 12:25:40.323 26588 26639 E ZgeAndroid: AudioCallback: getMinBufferSize method found
10-08 12:25:40.323 26588 26639 E ZgeAndroid: AudioCallback: AudioRate: 44100, Params: 3, 2
But if I use:
bufferSizeInBytes := Env^.CallStaticIntMethodV(env, cAudioTrack, mGetMinBufferSize, C([AudioPlayer.AudioRate, 3, 12]));
track := env^.NewObjectV(env, cAudioTrack, mAudioTrack, C([3, AudioPlayer.AudioRate, 3, 12, bufferSizeInBytes, 1]));
It doesn't log anything regarding AudioCallback...
I also tried setting
env^.PushLocalFrame(env, 12); (instead of 2)
But I don't know if that's related