Sysex broken on Android with Juce 5.4.3

#1

Hi All,

I’m working on a cross-platform app that uses sysex to configure MIDI devices. Since we last pushed an update, Jan 2nd (using JUCE 5.4.1) it seems that something’s changed in the JUCE backend and sysex messages over around 20 bytes are being truncated - breaking our communication protocol completely.

I stripped back the functionality of our app so it just connects to available midi ports and prints sent/received midi data as raw hex bytes. I’m unable to receive longer sysex messages without truncation, but I can send the same exact message out just fine. Other messages (Note, CC, Program Change) seem to be unaffected when this is happening.

I’ve tried rolling our app code back to the last stable release with identical results, but installing the same release version from the play store still works perfectly on all devices i’ve tested - which is what makes me think it must be a change in JUCE.

I’ve tested on multiple devices (API 24 and API 27), building using Juce 5.4.3, AS 3.3.2, Gradle 4.10.1 on Mac.

Have there been any changes recently that could explain this behaviour, or do you have any ideas on how I can debug this further?

Best,
Luke

0 Likes

#2

Just to add to this - using 3rd party apps (midi monitor in Midi Commander) I can see messages are being transmitted correctly from the MIDI devices

0 Likes

#3

To help narrow this down, you said the last working release you did was in January - was this using the tagged 5.4.1 release and not the develop branch? And the tests that you are doing now are with the tagged 5.4.3 release?

Can you try reverting this commit and see if it fixes your issue?

0 Likes

#4

Yes, sorry. Working build was with the tagged 5.4.1 release and currently testing with the tagged 5.4.3 release, not on develop branch.

Thanks - I’ll give that a go.

0 Likes

#5

I’ve spent the afternoon trying to test this but have been running into some roadblocks: reversing that linked commit gives me build errors in the projucer:

In file included from /Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp:34:
/Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h:1496:89: error: no viable conversion from 'RelativePath' to 'const juce::File'
            if ((! projectItem.shouldBeCompiled()) || (! shouldFileBeCompiledByDefault (file))
                                                                                        ^~~~
In file included from /Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp:27:
In file included from /Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/../Application/jucer_Headers.h:29:
In file included from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:17:
In file included from ../../../../modules/juce_analytics/juce_analytics.h:55:
In file included from ../../../../modules/juce_gui_basics/juce_gui_basics.h:57:
In file included from ../../../../modules/juce_graphics/juce_graphics.h:57:
In file included from ../../../../modules/juce_core/juce_core.h:294:
../../../../modules/juce_core/files/juce_File.h:63:5: note: candidate constructor not viable: no known conversion from 'RelativePath' to 'const juce::String &' for 1st argument
    File (const String& absolutePath);
    ^
../../../../modules/juce_core/files/juce_File.h:66:5: note: candidate constructor not viable: no known conversion from 'RelativePath' to 'const juce::File &' for 1st argument
    File (const File&);
    ^
../../../../modules/juce_core/files/juce_File.h:87:5: note: candidate constructor not viable: no known conversion from 'RelativePath' to 'juce::File &&' for 1st argument
    File (File&&) noexcept;
    ^
In file included from /Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp:28:
/Users/lukesaxton/Documents/dev/JUCE/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h:81:61: note: passing argument to parameter 'path' here
    virtual bool shouldFileBeCompiledByDefault (const File& path) const;
                                                            ^
1 error generated.

I also tried seeing if I can roll the whole branch back to v5.4.1. tagged commit but am just getting an extremely opaque gradle error:

SIMPLE: Error configuring error.

My process was rebuilding the projucer, deleting all files in android directory and re-saving the project. I’ve also tried creating a new android studio project - same problem.

I also tried resetting the whole juce branch back to 5.4.1 and rebuilding the projucer etc. - same results.

Rolling android studio back to 3.2.1 with juce 5.4.1 yeilded a slightly different error message:

org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':app'.
	at org.gradle.configuration.project.LifecycleProjectEvaluator.wrapException(LifecycleProjectEvaluator.java:79)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:73)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.access$400(LifecycleProjectEvaluator.java:54)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:200)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:110)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:68)
	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:687)
	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:140)
	at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
	at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
	at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:41)
	at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:274)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:182)
	at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:141)
	at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:124)
	at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:77)
	at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:74)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:154)
	at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:38)
	at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:96)
	at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:74)
	at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:55)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.run(RunAsBuildOperationBuildActionRunner.java:50)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:44)
	at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:79)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:44)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:80)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:53)
	at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:62)
	at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:34)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:59)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:44)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:46)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
	at org.gradle.util.Swapper.swap(Swapper.java:38)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:81)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:745)
Caused by: org.gradle.api.GradleException: executing external native build for cmake /Users/lukesaxton/Documents/dev/AndroidSysexTest/Builds/Android/app/CMakeLists.txt
	at com.android.build.gradle.internal.errors.SyncIssueHandlerImpl.reportIssue(SyncIssueHandlerImpl.kt:53)
	at com.android.builder.errors.EvalIssueReporter$DefaultImpls.reportError(EvalIssueReporter.kt:122)
	at com.android.build.gradle.internal.errors.SyncIssueHandler$DefaultImpls.reportError(SyncIssueHandler.kt)
	at com.android.build.gradle.internal.errors.SyncIssueHandlerImpl.reportError(SyncIssueHandlerImpl.kt:30)
	at com.android.build.gradle.tasks.ExternalNativeJsonGenerator.build(ExternalNativeJsonGenerator.java:203)
	at com.android.build.gradle.BasePlugin.lambda$createAndroidTasks$7(BasePlugin.java:818)
	at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
	at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:806)
	at com.android.build.gradle.BasePlugin.lambda$null$4(BasePlugin.java:652)
	at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
	at com.android.build.gradle.BasePlugin.lambda$createTasks$5(BasePlugin.java:648)
	at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1$1.run(DefaultListenerBuildOperationDecorator.java:155)
	at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:58)
	at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1.run(DefaultListenerBuildOperationDecorator.java:152)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
	at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction.execute(DefaultListenerBuildOperationDecorator.java:149)
	at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
	at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
	at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
	at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
	at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
	at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
	at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
	at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
	at com.sun.proxy.$Proxy27.afterEvaluate(Unknown Source)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:187)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:184)
	at org.gradle.api.internal.project.DefaultProject.stepEvaluationListener(DefaultProject.java:1418)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:193)
	... 95 more

Any thoughts?

0 Likes

#6

I’m able to get Android Studio projects building after rolling back to 5.4.1. My steps were as follows:

  • Check out the 5.4.1 tagged commit
  • Rebuild the Projucer
  • Open the .jucer file
  • Re-save the project and open it in Android Studio
  • Don’t update Gradle when asked
  • Build and run

I’m not sure what those errors that you’re seeing are from, but it looks like you’re mismatching versions of JUCE somewhere.

0 Likes

#7

Ok, so i’ve had another bash at this today: Following your steps and addtionally deleting the generated AndroidStudio directory (to force gradle to reconfigure), and cleaning the AS project, I managed to roll back as far as the 5.4.2 tagged commit - the sysex problem still persists there. I guess that narrows it down a bit… But I cannot convince 5.4.1 to build - just getting the SIMPLE: Error configuring error.

At this point i’ve gone nuclear on my JUCE and Android Studio installs and re-downloaded/installed everything so i’m really not sure what is going with my build environment that’s stopping me from testing with older JUCE versions on Android

Where do we go from here? I’m open to any suggestions.

0 Likes

#8

Had use a different machine in the end…

Confirmed that the problem is caused by commit 0ae5e233c

0 Likes

#9

OK, can you see if this commit fixes the issue?

0 Likes

#10

Yep, that seems to have done the trick! Thanks for taking a look.

What exactly was the problem there?

0 Likes

#11

The check added in 0ae5e233c was to guard against malformed sysex messages getting through in some ROLI products, but the check was a little heavy-handed and resulted in some messages being truncated or ignored in MidiDataConcatenator::processSysex() like you were seeing.

0 Likes