You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
After passing an AudioQueuePtr into AudioQueue.newInput, the iOS app crashes hard when I then call ptr.get(). There is no stack trace in the java console. I get the same error when attempting ptr.get() after passing an AudioFilePtr into AudioFile.createWithURL.
Main Class:
import java.lang.reflect.Method;
import org.robovm.apple.audiotoolbox.AudioQueue;
import org.robovm.apple.audiotoolbox.AudioQueueError;
import org.robovm.apple.audiotoolbox.AudioQueue.AudioQueuePtr;
import org.robovm.apple.audiotoolbox.AudioQueueBuffer.AudioQueueBufferPtr;
import org.robovm.apple.coreaudio.AudioFormat;
import org.robovm.apple.coreaudio.AudioStreamBasicDescription;
import org.robovm.apple.coreaudio.CoreAudio;
import org.robovm.apple.coreaudio.AudioStreamPacketDescription.AudioStreamPacketDescriptionPtr;
import org.robovm.apple.coreaudio.AudioTimeStamp.AudioTimeStampPtr;
import org.robovm.apple.corefoundation.CoreFoundation;
import org.robovm.apple.coregraphics.*;
import org.robovm.apple.foundation.*;
import org.robovm.apple.uikit.*;
import org.robovm.rt.bro.Bro;
import org.robovm.rt.bro.Struct;
import org.robovm.rt.bro.annotation.Callback;
import org.robovm.rt.bro.ptr.FunctionPtr;
import org.robovm.rt.bro.ptr.VoidPtr;
public class TestAudioQueueCrash extends UIApplicationDelegateAdapter
{
private UIWindow window = null;
private int clickCount = 0;
@Override
public boolean didFinishLaunching(UIApplication application, UIApplicationLaunchOptions launchOptions)
{
final UIButton button = UIButton.create(UIButtonType.RoundedRect);
button.setFrame(new CGRect(115.0f, 121.0f, 91.0f, 37.0f));
button.setTitle("Click me!", UIControlState.Normal);
button.addOnTouchUpInsideListener(new UIControl.OnTouchUpInsideListener()
{
@Override
public void onTouchUpInside(UIControl control, UIEvent event)
{
double mSampleRate = 44100;
AudioFormat mFormatID = AudioFormat.LinearPCM;
int mFormatFlags = CoreAudio.AudioFormatFlagIsBigEndian | CoreAudio.AudioFormatFlagIsPacked | CoreAudio.AudioFormatFlagIsSignedInteger;
int mBytesPerPacket = 2;
int mFramesPerPacket = 1;
int mBytesPerFrame = 2;
int mChannelsPerFrame = 1;
int mBitsPerChannel = 16;
AudioStreamBasicDescription asbd = new AudioStreamBasicDescription(mSampleRate, mFormatID, mFormatFlags, mBytesPerPacket, mFramesPerPacket, mBytesPerFrame, mChannelsPerFrame, mBitsPerChannel, 0);
AudioQueuePtr mQueuePtr = new AudioQueuePtr();
int kNumberBuffers = 3;
AudioQueueBufferPtr mBuffers = Struct.allocate(AudioQueueBufferPtr.class, kNumberBuffers);
AQRecorderState aqData = new AQRecorderState(asbd, mQueuePtr, mBuffers , null, 1024, 0, false);
Method callbackMethod = null;
Method[] methods = TestAudioQueueCrash.class.getMethods();
int i = methods.length;
while (i-->0) if (methods[i].getName().equals("callbackMethod")) { callbackMethod = methods[i]; break; }
System.out.println(callbackMethod);
FunctionPtr fp = new FunctionPtr(callbackMethod );
AudioQueueError aqe = AudioQueue.newInput(asbd, fp, aqData.as(VoidPtr.class), null, CoreFoundation.RunLoopCommonModes().toString(), 0, mQueuePtr);
System.out.println(aqe.name());
System.out.println("wait for it...");
AudioQueue queue = mQueuePtr.get();
System.out.println("never gets here");
button.setTitle("Click #" + (++clickCount), UIControlState.Normal);
}
});
window = new UIWindow(UIScreen.getMainScreen().getBounds());
window.setBackgroundColor(UIColor.lightGray());
window.addSubview(button);
window.makeKeyAndVisible();
return true;
}
/*<bind>*/static { Bro.bind(TestAudioQueueCrash.class); }/*</bind>*/
/*<constants>*//*</constants>*/
/*<constructors>*//*</constructors>*/
/*<properties>*//*</properties>*/
/*<members>*//*</members>*/
@Callback
public static void callbackMethod(AQRecorderState.AQRecorderStatePtr aqDataPtr, AudioQueuePtr inAQ, AudioQueueBufferPtr inBuffer, AudioTimeStampPtr inStartTime, int inNumPackets, AudioStreamPacketDescriptionPtr inPacketDesc)
{
System.out.println("RECORDING YAY!");
}
public static void main(String[] args)
{
try (NSAutoreleasePool pool = new NSAutoreleasePool())
{
UIApplication.main(args, null, TestAudioQueueCrash.class);
}
}
}
Support Struct class:
/*<imports>*/
import org.robovm.rt.bro.*;
import org.robovm.rt.bro.annotation.*;
import org.robovm.rt.bro.ptr.*;
import org.robovm.apple.audiotoolbox.AudioFile;
import org.robovm.apple.audiotoolbox.AudioQueue.AudioQueuePtr;
import org.robovm.apple.audiotoolbox.AudioQueueBuffer.AudioQueueBufferPtr;
import org.robovm.apple.coreaudio.*;
/*</imports>*/
/*<javadoc>*/
/*</javadoc>*/
/*<annotations>*//*</annotations>*/
/*<visibility>*/public/*</visibility>*/ class /*<name>*/AQRecorderState/*</name>*/
extends /*<extends>*/Struct<AQRecorderState>/*</extends>*/
/*<implements>*//*</implements>*/ {
/*<ptr>*/public static class AQRecorderStatePtr extends Ptr<AQRecorderState, AQRecorderStatePtr> {}/*</ptr>*/
/*<bind>*/
/*</bind>*/
/*<constants>*//*</constants>*/
/*<constructors>*/
public AQRecorderState() {}
public AQRecorderState(AudioStreamBasicDescription mDataFormat, AudioQueuePtr mQueue, AudioQueueBufferPtr mBuffers, AudioFile mAudioFile, int bufferByteSize, long mCurrentPacket, boolean mIsRunning) {
this.mDataFormat(mDataFormat);
this.mQueue(mQueue);
this.mBuffers(mBuffers);
this.mAudioFile(mAudioFile);
this.bufferByteSize(bufferByteSize);
this.mCurrentPacket(mCurrentPacket);
this.mIsRunning(mIsRunning);
}
/*</constructors>*/
/*<properties>*//*</properties>*/
/*<members>*/
@StructMember(0) public native @ByVal AudioStreamBasicDescription mDataFormat();
@StructMember(0) public native AQRecorderState mDataFormat(@ByVal AudioStreamBasicDescription mDataFormat);
@StructMember(1) public native AudioQueuePtr mQueue();
@StructMember(1) public native AQRecorderState mQueue(AudioQueuePtr mQueue);
@StructMember(2) public native @Array({3}) AudioQueueBufferPtr mBuffers();
@StructMember(2) public native AQRecorderState mBuffers(@Array({3}) AudioQueueBufferPtr mBuffers);
@StructMember(3) public native AudioFile mAudioFile();
@StructMember(3) public native AQRecorderState mAudioFile(AudioFile mAudioFile);
@StructMember(4) public native int bufferByteSize();
@StructMember(4) public native AQRecorderState bufferByteSize(int bufferByteSize);
@StructMember(5) public native long mCurrentPacket();
@StructMember(5) public native AQRecorderState mCurrentPacket(long mCurrentPacket);
@StructMember(6) public native boolean mIsRunning();
@StructMember(6) public native AQRecorderState mIsRunning(boolean mIsRunning);
/*</members>*/
/*<methods>*//*</methods>*/
}
Java Console:
2014-12-03 13:14:14.309 TestAudioQueueCrash[2172:60b] Application windows are expected to have a root view controller at the end of application launch
public static void TestAudioQueueCrash.callbackMethod(AQRecorderState$AQRecorderStatePtr,org.robovm.apple.audiotoolbox.AudioQueue$AudioQueuePtr,org.robovm.apple.audiotoolbox.AudioQueueBuffer$AudioQueueBufferPtr,org.robovm.apple.coreaudio.AudioTimeStamp$AudioTimeStampPtr,int,org.robovm.apple.coreaudio.AudioStreamPacketDescription$AudioStreamPacketDescriptionPtr)
WARN: Failed to call getClassTypeID() for the CFType subclass org.robovm.apple.audiotoolbox.AudioFileStream
WARN: Failed to call getClassTypeID() for the CFType subclass org.robovm.apple.audiotoolbox.AudioQueueTimeline
WARN: Failed to call getClassTypeID() for the CFType subclass org.robovm.apple.audiotoolbox.AudioFile
WARN: Failed to call getClassTypeID() for the CFType subclass org.robovm.apple.audiotoolbox.AudioQueue
No
wait for it...
RoboVM Console:
12/3/14 1:14:11 PM: [DEBUG] Launching app...
12/3/14 1:14:11 PM: [DEBUG] App Path: /private/var/mobile/Applications/73C91F8D-2C1C-46EA-A37B-2800780398A8/TestAudioQueueCrash.app
12/3/14 1:20:25 PM: [ERROR] AppLauncher failed with an exception:
12/3/14 1:20:25 PM: [ERROR] java.lang.RuntimeException: Unexpected response from debugserver: $X00#00
12/3/14 1:20:25 PM: [ERROR] at org.robovm.libimobiledevice.util.AppLauncher.pipeStdOut(AppLauncher.java:761)
12/3/14 1:20:25 PM: [ERROR] at org.robovm.libimobiledevice.util.AppLauncher.launchInternal(AppLauncher.java:691)
12/3/14 1:20:25 PM: [ERROR] at org.robovm.libimobiledevice.util.AppLauncher.launch(AppLauncher.java:965)
12/3/14 1:20:25 PM: [ERROR] at org.robovm.compiler.target.ios.AppLauncherProcess$1.run(AppLauncherProcess.java:67)
Thanks for the detailed bug report! I've looked into this and it seems like we have a bug in our bindings.
@BlueRiverInteractive: The AudioFile should not extend from CFType but rather be a NativeObject. It's defined like this in the AudioFile.h header:
typedef struct OpaqueAudioFileID *AudioFileID;
So nothing that indicates that it's a CFType "subclass". Better look through other classes in that framework as well and make sure they don't extend from CFType unless needed.
I can confirm that the replacing the org.robovm.apple.audiotoolbox package with the one in the latest version of robovm-1.0.0-beta-01 fixes both crashes. Many, many thanks!
After passing an
AudioQueuePtr
intoAudioQueue.newInput
, the iOS app crashes hard when I then callptr.get()
. There is no stack trace in the java console. I get the same error when attemptingptr.get()
after passing anAudioFilePtr
intoAudioFile.createWithURL
.Main Class:
Support Struct class:
Java Console:
RoboVM Console:
Symbolicated XCode Organizer Device Log:
The text was updated successfully, but these errors were encountered: