Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIDI2.0Workbench keeps sending Get Property Data for DeviceInfo forever #5

Open
atsushieno opened this issue Jan 21, 2024 · 7 comments
Labels
bug Something isn't working

Comments

@atsushieno
Copy link

atsushieno commented Jan 21, 2024

I am trying to get MIDI2.0Workbench to see if it is usable for diagnosing any interoperability issues. Sadly it is currently impossible, because the tools goes into weird "infinite loop" that keeps sending Get Property Data request to the connected device.

It keeps logging the requests and reqponses forever, which makes it impossible to even inspect the messages.

For the same reason, we cannot really debug what is going on with the actual property data, regardless of which property it is, because every time it receives the response, the tool refreshes the property details on the "Resource Data" page and resets the property selection status.

Confirmed with MIDI2.0Workbench 1d293d9, my own MICI-CI tool (atsushieno/ktmidi as of ef03b56), and JUCE CapabilityInquiryDemo (as of 0637f78).

Screenshot 2024-01-21 at 20 27 39 Screenshot 2024-01-21 at 20 29 43
@starfishmod
Copy link
Member

Yeah that's not good -
Can you please send me the debug log (Debug window->Download Log)
If possible can you send me a compiled version of your test app. (Sorry I don't have Kotlin Experience)

@atsushieno
Copy link
Author

Here are the log archives: juce-ci-demo.log.zip / ktmidi-ci-tool.log.zip

On my Kotlin implementation, I can provide an Ubuntu .deb package but not others (it often happens that the Kotlin / Compose Multiplatform toolchains work fine only on occasion): https://drive.google.com/file/d/1oC1vAzyBCoQE9W9jLbB5ydz000dg7vvX/view?usp=sharing

JUCE CapabilityInquiryDemo would be easy for you to build: check out JUCE sources (master release is fine), and run:

cmake . -B cmake-build -DJUCE_BUILD_EXAMPLES=ON -DJUCE_BUILD_EXTRAS=ON
cmake --build cmake-build --target CapabilityInquiryDemo

and run the resulting binary such as ./cmake-build/examples/Audio/CapabilityInquiryDemo_artefacts/CapabilityInquiryDemo (depends on the platform)

I guess that it is dependent on the connection setup. I also have a Kotlin/Wasm version on the web ( https://androidaudioplugin.web.app/misc/ktmidi-ci-tool-wasm-first-preview/ ), but I cannot reproduce the issue. I choose "MIDI 2.0 Workbench" virtual ports on either CapabilityInquiryDemo or my web version, but the infinite loop occurs only on desktop (I confirmed it occurs on Ubuntu and Mac).

@starfishmod
Copy link
Member

@atsushieno I just tried the deb package and I got the following:

@mipex:/opt/dev.atsushieno.ktmidi.citool/lib$ /opt/dev.atsushieno.ktmidi.citool/bin/dev.atsushieno.ktmidi.citool
pure virtual method called
terminate called without an active exception
java.nio.file.NoSuchFileException: ktmidi-ci-tool.settings.json
java.nio.file.NoSuchFileException: ktmidi-ci-tool.settings.json
	at java.base/sun.nio.fs.UnixException.translateToIOException(Unknown Source)
	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(Unknown Source)
	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(Unknown Source)
	at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(Unknown Source)
	at java.base/java.nio.file.Files.newByteChannel(Unknown Source)
	at java.base/java.nio.file.Files.newByteChannel(Unknown Source)
	at java.base/java.nio.file.Files.readAllBytes(Unknown Source)
	at JVMPlatform.loadFileContent(Platform.jvm.kt:10)
	at dev.atsushieno.ktmidi.citool.CIToolRepository.getConfigFromFile(AppModel.kt:52)
	at dev.atsushieno.ktmidi.citool.CIToolRepository.getConfigDefault(AppModel.kt:63)
	at dev.atsushieno.ktmidi.citool.CIToolRepository.<init>(AppModel.kt:40)
	at dev.atsushieno.ktmidi.citool.AppModelKt.initializeAppModel(AppModel.kt:18)
	at MainKt$main$1.invoke(main.kt:15)
	at MainKt$main$1.invoke(main.kt:14)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:117)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.ui.window.Application_desktopKt$application$1$1.invoke(Application.desktop.kt:115)
	at androidx.compose.ui.window.Application_desktopKt$application$1$1.invoke(Application.desktop.kt:114)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:117)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2$1$1.invoke(Application.desktop.kt:227)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2$1$1.invoke(Application.desktop.kt:226)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2$1.invoke(Application.desktop.kt:221)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2$1.invoke(Application.desktop.kt:219)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:39)
	at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3341)
	at androidx.compose.runtime.ComposerImpl.composeContent$runtime(Composer.kt:3274)
	at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:588)
	at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1013)
	at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:520)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:219)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
kotlin.Unit
Warning: Version of dev.atsushieno:alsakt could not be found.
ALSA lib conf.c:4579:(snd_config_update_r) Cannot access file /sources/KtMidi/alsakt/external/alsa-lib/../../alsa-dist/share/alsa/alsa.conf
ALSA lib seq.c:935:(snd_seq_open_noupdate) Unknown SEQ default
Exception in thread "main" java.lang.ExceptionInInitializerError
	at MainKt$main$1.invoke(main.kt:17)
	at MainKt$main$1.invoke(main.kt:14)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:117)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.ui.window.Application_desktopKt$application$1$1.invoke(Application.desktop.kt:115)
	at androidx.compose.ui.window.Application_desktopKt$application$1$1.invoke(Application.desktop.kt:114)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:117)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2$1$1.invoke(Application.desktop.kt:227)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2$1$1.invoke(Application.desktop.kt:226)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2$1.invoke(Application.desktop.kt:221)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2$1.invoke(Application.desktop.kt:219)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:108)
	at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:35)
	at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:39)
	at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3341)
	at androidx.compose.runtime.ComposerImpl.composeContent$runtime(Composer.kt:3274)
	at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:588)
	at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1013)
	at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:520)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:219)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Caused by: dev.atsushieno.alsakt.AlsaException: ALSA error: No such file or directory (error code -2)
	at dev.atsushieno.alsakt.AlsaSequencer.<init>(AlsaSequencer.kt:388)
	at dev.atsushieno.alsakt.AlsaSequencer.<init>(AlsaSequencer.kt:19)
	at dev.atsushieno.ktmidi.AlsaMidiAccess.<clinit>(AlsaMidiAccess.kt:13)
	... 39 more

@starfishmod
Copy link
Member

@atsushieno I think I might have a clue to the reason.

It seems that neither ResourceList from either ktmidi and juce demos have "deviceInfo" in the ResourceList. (Juce demo has it as "DeviceInfo" with a capital D).

Because deviceInfo is a foundational Resource it is expecting it to be there. I have added some extra checks to hopefully stop looping. Can you please add "deviceInfo" to your ResourceList and see if it works?

I'll push the changes in a few days (it's NAMM time) so you can see the changes.

@starfishmod starfishmod added the bug Something isn't working label Jan 23, 2024
@atsushieno
Copy link
Author

uh, oh, I was not aware of those ALSA related errors. Thanks for the heads up. (The other error stack trace is intended so far, at least I am aware of it.)

Because deviceInfo is a foundational Resource it is expecting it to be there. I have added some extra checks to hopefully stop looping. Can you please add "deviceInfo" to your ResourceList and see if it works?

Yes it stops looping once I rename it to "deviceInfo". However, the correct name is "DeviceInfo" according to Common Rules for MIDI-CI Property Exchange version 1.1 (M2-103-UM_v1-1_Common_Rules_for_MIDI-CI_Property_Exchange.pdf) as well as MIDI-CI Property Exchange Foundational Resources version 1.1.1 (M2-105-UM_v1-1-1_Property_Exchange_Foundational_Resources.pdf). I believe juce_midi_ci is implemented based on these specifications as well.

@starfishmod
Copy link
Member

However, the correct name is "DeviceInfo" according to Common Rules

You are correct - sorry I'm doing this late at night and I am tired 😪
My changes should fix the looping in anycase

atsushieno added a commit to atsushieno/ktmidi that referenced this issue Jan 23, 2024
@atsushieno
Copy link
Author

I noticed that DeviceInfo is not enlisted in the ResourceList from the latest ktmidi-ci-tool. It returned DeviceInfo JSON regardless when it received Get Property Data Inquiry for this resource, but that might have triggered the issue. I just fixed it at my side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants