Open Grumpy-Mike opened 3 years ago
@todbot @jedgarpark Have you used ProgramChange at all?
Corresponding forum post: https://forums.adafruit.com/viewtopic.php?f=60&t=181219
ProgramChange MIDI messages work for me via USB MIDI using adafruit_midi
on one of the latest CP7 builds Adafruit CircuitPython 7.0.0-alpha.4-51-gc18c33050 on 2021-07-13; Adafruit Rotary Trinkey M0 with samd21e18
.
This script I'm using is:
import time, usb_midi, adafruit_midi
from adafruit_midi.note_on import NoteOn
from adafruit_midi.note_off import NoteOff
from adafruit_midi.program_change import ProgramChange
midi = adafruit_midi.MIDI( midi_in=usb_midi.ports[0], midi_out=usb_midi.ports[1] )
i=0
while True:
midi.send(NoteOn("A4",10))
time.sleep(1)
midi.send(NoteOff("A4"))
time.sleep(1)
midi.send(ProgramChange(i))
i = (i+1) % 127
time.sleep(1)
The output I see is this:
And VSTs in Ableton Live respond appropriately to the Program Change messages.
I just verified the problem @Grumpy-Mike is seeing is related to the recently-closed https://github.com/adafruit/circuitpython/issues/4895 This problem exists in 7.0.0-alpha4 but not in the latest builds.
@Grumpy-Mike, I suggest going to https://circuitpython.org/downloads, finding your board, then scrolling down to the "Absolute Newest / Browse S3" section. From there you can download a latest build that fixes this issue.
Thanks. I did try what you said but was a little lost as to what I found there. It was a list of language options all zero sized. I followed it up to https://adafruit-circuit-python.s3.amazonaws.com / where some of them stopped being zero size and actually had content. Sorry but I have no idea what to do next with these files, non of which seemed to have relevant names. I can confirm I was using 6.3.0 as it was the latest stable version and my board is a Pico.
@Grumpy-Mike apologies, I forget not everyone is familar with old-timey web directory displays. For the Pico, you'll end up with a page that looks like this:
Those are all directories. Pick the one for your language & region. I pick "en_US" because I speak English in the USA. And then you'll see a page that looks like this:
Those are all CircuitPython UF2 install files, like you normally use to install CircuitPython. They are arranged newest-first, with the newest one in the above screenshot being made on 2021-07-14 @ 19:21 GMT. Unless I need a specific build, I always pick the top (most recent) one.
When you click on it, it downloads a UF2 file, and you can use it to install CircuitPython on your device just like normal.
Thanks for that but sadly it did not work, I still get the invalid message even with todbot's code. I used the latest build adafruit-circuitpython-raspberry_pi_pico-en_GB-20210714-e3bc800.uf2 and got the error message about updating the .mpy so I think that proves that the update was working. I did that with the latest bundle for version 7. The to double check I used adafruit-circuitpython-raspberry_pi_pico-en_GB-7.0.0-alpha.4.uf2 with the same results, shown below.
Just to verify what version CircuitPython you're running, when you go into the REPL and press Ctrl-C what CircuitPython version is printed? It will look something like:
Adafruit CircuitPython 7.0.0-alpha.4-65-ge2888cba6 on 2021-07-13; Adafruit MagTag with ESP32S2
Nothing happens when I press Ctrl-C, but I am using Thonny. When it connects to the Pico I get this message:- Adafruit CircuitPython 7.0.0-alpha.4-67-ge3bc800bb on 2021-07-14; Raspberry Pi Pico with rp2040
I also tried other things like:- Adafruit CircuitPython 7.0.0-alpha.4-15-g22e8a5058 on 2021-07-11; Raspberry Pi Pico with rp2040 with the same effect.
I am normally just running this into the MIDI monitor, but I get the same behavior when I use Garage Band ( even though it dose nothing with a Program Change message) and I have just tried it with Ableton 10.
Is it the case that you can no longer see this problem with your builds? I tried build adafruit-circuitpython-raspberry_pi_pico-en_GB-20210718-40b0857.uf2 yesterday and was still getting the same problem. @todbot do you have the exact build you used to get the result you posted? Thanks
Hi @Grumpy-Mike, Apologies for not responding to you specifically. The build I was using was quoted above. I just did a new test using production CircuitPython 7.0. The code is basically yours quoted above but has a loop to increment the program change.
From what I can tell USB MIDI Program Change works fine on CircuitPython 7 and has worked since the fix tested back in July. Here's a video showing what I'm seeing. It uses MIDI Monitor on MacOS, Ableton Live, and the free MG-1 VST from Cherry Audio. Note that many VSTs don't do Program Change and some require Bank Select commands (which are Control Change). But the MG-1 is simple enough to just do standard PC.
https://user-images.githubusercontent.com/274093/138509026-e3627f5e-e93c-468e-a70c-441d09f3a6eb.mp4
Here's the code in the video:
import usb_midi
import adafruit_midi
from adafruit_midi.note_off import NoteOff
from adafruit_midi.note_on import NoteOn
from adafruit_midi.program_change import ProgramChange
import time
midi = adafruit_midi.MIDI(midi_in=usb_midi.ports[0], in_channel=0,
midi_out=usb_midi.ports[1], out_channel=0 )
print("MIDI program change test!")
prog_chg_num = 0x07
while True:
midi.send(NoteOn(65,100))
time.sleep(0.6)
midi.send(NoteOff(65,0))
time.sleep(0.6)
print("sending program change:", prog_chg_num)
midi.send(ProgramChange( prog_chg_num ))
time.sleep(1)
prog_chg_num = (prog_chg_num + 1 ) % 127
In my opinion, this issue can be closed.
Thanks for the work you have put into this Tod.
Unfortunately I do not find this fixed for me. I used the code in your email, exactly as is.
This morning I downloaded al the files again:- That is Circuit Python 7.0 adafruit-circuitpython-raspberry_pi_pico-en_GB-7.0.0.uf2 and flashed it in. I also downloaded the adafruit-circuitpython-bundle-7.x-mpy-20211023 and updated all the libraries I use. But I still get the same results as I always did, see screen shot at the end of this email.
I looked at your video and saw three differences. First of all the code is not identical to the code you posted. I did change from by looking at the code in your video but as you say they are nearly identical so it was no surprise that the results were the same. Second I see you are using a qtpy processor and I am using the Pico processor. So the uf2 files used to flash in Circuit Python might / will be different. Could it be that the fix in not in the Pico version of circuit python 7? I know you automate things so it should not happen, but otherwise I am at a loss to see why your version works and mine does not. Third I am using Thonny on a Mac to upload the software.
I also I was surprised that circuit python 7 broke the code I had written for the project. I get the error message:-
Traceback (most recent call last):
File "
I guess the OLED code has changed somewhere. But it is not worth trying to fix until the MIDI issue is sorted.
So sorry, for me the issue is still not fixed.
Cheers Mike
On 22 Oct 2021, at 20:02, Tod E. Kurt @.***> wrote:
Hi @Grumpy-Mike https://github.com/Grumpy-Mike, Apologies for not responding to you specifically. The build I was using was quoted above. I just did a new test using production CircuitPython 7.0. The code is basically yours quoted above but has a loop to increment the program change.
From what I can tell USB MIDI Program Change works fine on CircuitPython 7 and has worked since the fix tested back in July. Here's a video showing what I'm seeing. It uses MIDI Monitor on MacOS, Ableton Live, and the free MG-1 VST from Cherry Audio https://cherryaudio.com/products/surrealistic-mg-1-plus. Note that many VSTs don't do Program Change and some require Bank Select commands (which are Control Change). But the MG-1 is simple enough to just do standard PC.
https://user-images.githubusercontent.com/274093/138509026-e3627f5e-e93c-468e-a70c-441d09f3a6eb.mp4 https://user-images.githubusercontent.com/274093/138509026-e3627f5e-e93c-468e-a70c-441d09f3a6eb.mp4 Here's the code in the video:
`import usb_midi import adafruit_midi from adafruit_midi.note_off import NoteOff from adafruit_midi.note_on import NoteOn from adafruit_midi.program_change import ProgramChange import time
midi = adafruit_midi.MIDI( midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0 )
midi.send(NoteOn(65,100)) time.sleep(0.6) midi.send(NoteOff(65,0)) time.sleep(0.6) midi.send(ProgramChange(0x7))` In my opinion, this issue can be closed.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/adafruit/Adafruit_CircuitPython_MIDI/issues/37#issuecomment-949891336, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABADP3UIVV6NKHJT25PVW53UIGYKRANCNFSM5AK6XT3Q. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
Hi @Grumpy-Mike,
A few comments:
code.py
I included in the above comment is different than the code in my video. (Perhaps you are not seeing my edit? I inadvertently pasted in your original code when I first posted but that was corrected within minutes)cp -X
) And no need to download the Library Bundle!As for your OLED error, CircuitPython is a rapidly-changing platform. APIs are constantly in flux so the kind of error you experienced is pretty common. A quick scan of the docs for the library in question will usually sort out what the changes are. It's frustrating but common in fast-paced open-source projects.
Please describe how the code.py I included in the above comment is different than the code in my video. I worked from the email GitHub sent me not GitHub itself. I never got an update email so I never saw your update, so I just copied your code from the screen in your video. Later when I went on GitHub and scrolled down
Can you make a quick video that shows what you're experiencing? Well its hardly worth it. I am just running Midi monitor nothing else. I just load that code into Thonny and hit run and got the result in the screen dump. When I ran your code I got exactly what I expected, the first three lines of the screen dump, with the number following the invalid message starting at 7 and increasing by one every second while the first two lines were repeated.
I recommend using circup https://learn.adafruit.com/keep-your-circuitpython-libraries-on-devices-up-to-date-with-circup/install-circup to install the latest version of libraries on a CircuitPython device. Well I tried and got into all sorts of a mess trying to update pip, lots of deprecated warnings. Then git could not be found neither could homebrew. I did have homebrew on my mac many years ago and deleted it because it was useless. I could never get it to work correctly. I was trying to load inkscape at the time. It took an age and then didn't work in the end. But would this actually make any difference? I have to get the files into the lib folder in the first place in order to update them. As I only updated them this morning then I assume circup would not update them anyway.
I will try with a totally fresh Pico in the morning and see how that works.
On 23 Oct 2021, at 18:53, Tod E. Kurt @.***> wrote:
Hi @Grumpy-Mike https://github.com/Grumpy-Mike,
A few comments:
Please describe how the code.py I included in the above comment is different than the code in my video. (Perhaps you are not seeing my edit? I inadvertently pasted in your original code when I first posted but that was corrected within minutes) The demo I showed was using the QTPy RP2040, which is using the same chip as the Raspberry Pi Pico. In fact, I reflashed my QTPy RP2040 with the Pico build of CircuitPython 7 and the code works identically What is the error you are seeing when you run this demo code? Can you make a quick video that shows what you're experiencing? I recommend using circup https://learn.adafruit.com/keep-your-circuitpython-libraries-on-devices-up-to-date-with-circup/install-circup to install the latest version of libraries on a CircuitPython device. (Copying files by hand on MacOS can cause problems because of the metadata files MacOS creates, unless you're doing it in Terminal with cp -X) And no need to download the Library Bundle! The choice of editor (Thonny for your, Emacs + tio for me) does not matter. All we're doing is editing a text file on a USB drive As for your OLED error, CircuitPython is a rapidly-changing platform. APIs are constantly in flux so the kind of error you experienced is pretty common. A quick scan of the docs for the library in question will usually sort out what the changes are. It's frustrating but common in fast-paced open-source projects.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/adafruit/Adafruit_CircuitPython_MIDI/issues/37#issuecomment-950188829, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABADP3WSUXG3I2E24B6AFHTUILZAPANCNFSM5AK6XT3Q. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
Sorry but just realised that my screen dump I sent in the email reply did not seem to make it. Here it is:-
Hi, For completeness' sake, I tried both @Grumpy-Mike's original code and my looping version on a fresh Raspberry Pi Pico running Adafruit CircuitPython 7.0.0 on 2021-09-20; Raspberry Pi Pico with rp2040
. Both versions work as expected. The screenshot below is MIDI Monitor showing a run of Mike's original code.
Trying a new Pico sounds like a good idea. It almost seems like you're board is running an old version of CircuitPython or libraries. I periodically do rm -rf /Volumes/CIRCUITPY/lib
to remove any random libraries just in case (or in case I copied libraries by hand and didn't use cp -X
). I've also had to entirely clean the Pico's flash using flash_nuke.uf2
as described here or here.
Also, for more completeness' sake: which version of MacOS are you running? I've tested on Mac OS 11.6 ("Big Sur") on 2015 Intel MacBook Pro and a 2020 M1 MacBook Pro. Similarly, what version of MIDI Monitor are you running? Current version is 1.4.1.
OK Got it to work with only a handful of hair to go.
Basically it will not work correctly on my Laptop which is running macOS Mojave V10.14.6 but it does work on my new iMac running macOS Big Sur V11.6, I had not transferred much over to that as i don't want to use it as a hardware development platform. So I had install all the software to it to test this.
In order to get it to work on my iMac I had to upgrade Thonny from 3.3.3 to 3.3.13 tried the same on my laptop with no effect.
Also upgraded MIDI monitor to latest but made no difference. I nuked the flash and installed Circuit Python and the Library files on a Raspberry Pi. Again to no effect on the laptop.
macOS Mojave is the last Mac OS that supports 32 bit applications so I have to keep the laptop at that otherwise too much stuff will stop working.
It is odd that so much else in circuit python seems to work. Dose this give any clue as to what is wrong, or do you just want to sack it of and add in the documentation that MIDI through USB dosn't work on older Mac OS?
Thank you, @Grumpy-Mike. This is a good result! I was able to recreate your issue on an old Mac Mini running MacOS 10.13 ("High Sierra").
I discovered the issue also exists in Arduino when using the Adafruit_TinyUSB_Arduino library on current MacOS. See the above linked issue and this gist.
CircuitPython, the Adafruit_TinyUSB_Arduino library, and many other projects use TinyUSB (it's really good). I think this issue is in TinyUSB, but I don't have a good test case yet for just TinyUSB, only via CP or Arduino. I'm looking into that now but that will take longer.
Suffice to say, I think this issue is not with this library ("Adafruit_CircuitPython_MIDI") nor with CircuitPython directly, but both are affected by it.
After further investigation, I've been able to replicate this issue on recent MacOS in both CircuitPython and in a TinyUSB C-only program. In CircuitPython, first let's eliminate this library entirely and send raw MIDI messages like this:
import usb_midi
import time
midi_out = usb_midi.ports[1]
midi_ch = 0
while True:
note_on = bytearray( (0x90 | midi_ch, 65, 100) )
midi_out.write( note_on, len(note_on) )
time.sleep(0.6)
note_off = bytearray( (0x80 | midi_ch, 65, 23) )
midi_out.write( note_off, len(note_off) )
time.sleep(0.6)
prog_chg = bytearray( (0xC0 | midi_ch, 7) )
midi_out.write( prog_chg, len(prog_chg) )
time.sleep(1.6)
This works fine and all three MIDI messages are sent correctly. But if you change it to single-byte writes like this:
import usb_midi
import time
midi_out = usb_midi.ports[1]
midi_ch = 0
while True:
note_on = bytearray( (0x90 | midi_ch, 65, 100) )
midi_out.write( note_on[0:1], 1)
midi_out.write( note_on[1:2], 1)
midi_out.write( note_on[2:3], 1)
time.sleep(0.6)
note_off = bytearray( (0x80 | midi_ch, 65, 23) )
midi_out.write( note_off[0:1], 1)
midi_out.write( note_off[1:2], 1)
midi_out.write( note_off[2:3], 1)
time.sleep(0.6)
prog_chg = bytearray( (0xC0 | midi_ch, 7) )
midi_out.write( prog_chg[0:1], 1 )
midi_out.write( prog_chg[1:2], 1 )
time.sleep(1.6)
Then the Note On & Note Off messages are sent correctly, but the Program Change message is corrupted (first by 0x00 instead of 0xC0). Sending a byte a time is what the MIDI Library in Arduino does, which is why it is having the same issue.
Thanks Tod, I did try that last example of sending the bytes one at a time when I was investigating the problem and got exactly the same as you. By the way did you know that this problem applies to MIDI message with the first number 0xD. So that is the little used Channel Pressure (After-touch). Again the single byte at a time method produces 0x00 as the first byte. I did try the method you say works `prog_chg = bytearray( (0xC0 | midi_ch, 7) )
midi_out.write( prog_chg, len(prog_chg) )`
But that didn't work on my laptop. Nether did using 0xD0 but 0xE0 (with an extra byte of data) did produce the correct Pitch Wheel message.
When using the Program Change call it sends 0x0 followed by the patch number. Example code:-
I notice in the unit test test_MIDI_unittests.py this call is not tested despite the import list described as the "full monty". Is there a temporary fix to send this message? I have been tying to specify the data bytes and sent those, but I keep getting error messages like "AttributeError: 'NoneType' object has no attribute 'channel'".