MIDI Note-On to show image?

Is there a way to change the code from ‘Eyesy Mode - Basic Image’ that the image you trigger will be as long as the duration of a midi note? Now it triggers the image and I want control of the duration that the image is shown.

If someone knows how to change this code, that would be great! New to coding. :alien:

import os
import pygame
import glob

#important! make sure images are scaled to display resolution beforehand; smaller is faster
images = []
image_index = 0
fall = 0
scoot = 0
bg = pygame.Surface((656,416))
waiting = 0
xr = 320
yr = 240

def setup(screen, etc) :
global images, fall, bg, xr, yr
xr = etc.xres
yr = etc.yres

bg = pygame.Surface((xr,yr))

for filepath in sorted(glob.glob(etc.mode_root + '/Images/*.png')):
    filename = os.path.basename(filepath)
    print 'loading image file: ' + filename
    img = pygame.image.load(filepath)
    images.append(img)

def draw(screen, etc) :
global images, image_index, fall, bg, scoot, waiting, xr, yr
etc.color_picker_bg(etc.knob5)
above = False

if waiting == 0 :
    for i in range(0, 100) :
        if abs(etc.audio_in[i]) > 1000 :
            above = True
            waiting = 4
else :
    waiting -= 1

if etc.audio_trig or etc.midi_note_new :
    image_index += 1
    if image_index == len(images) : image_index = 0
    img = images[image_index]
    ximg = int(img.get_width() * etc.knob3)
    yimg = int(img.get_height() * etc.knob3)
    img = pygame.transform.scale(img, (ximg, yimg) )
    
    img.fill((255, 255, 255, etc.knob4 * 255), None, pygame.BLEND_RGBA_MULT)

    y = int(etc.knob2 * yr) - int(img.get_height() * .5)
    x = int(etc.knob1 * xr) - int(img.get_width() * .5)
    screen.blit(img, (x,y))

On this line the code is checking the trigger flag and the note new flag:

if etc.audio_trig or etc.midi_note_new :

Both of these flags get cleared after each frame is drawn. If you want to display the image every frame while the note is down you have to use etc.midi_notes. This is a list of the 127 MIDI notes, a 0 means the note is not playing any other value it is playing. So you could replace this:

if etc.audio_trig or etc.midi_note_new :

with this:

# loop through notes to see if any are held down
note_down = False
for note in etc.midi_notes :
    if note != 0 : note_down = True

# display image if down
if note_down :

Thanks for helping out! Unfortunately it doesn’t work, the mode is really buggy now and doesn’t respond very well. Here is how the code looks like now. Maybe I did something wrong?

import os

import pygame
import glob

#important! make sure images are scaled to display resolution beforehand; smaller is faster
images = []
image_index = 0
fall = 0
scoot = 0
bg = pygame.Surface((656,416))
waiting = 0
xr = 320
yr = 240

def setup(screen, etc) :
global images, fall, bg, xr, yr
xr = etc.xres
yr = etc.yres

bg = pygame.Surface((xr,yr))

for filepath in sorted(glob.glob(etc.mode_root + '/Images/*.png')):
    filename = os.path.basename(filepath)
    print 'loading image file: ' + filename
    img = pygame.image.load(filepath)
    images.append(img)

def draw(screen, etc) :
global images, image_index, fall, bg, scoot, waiting, xr, yr
etc.color_picker_bg(etc.knob5)
above = False

if waiting == 0 :
    for i in range(0, 100) :
        if abs(etc.audio_in[i]) > 1000 :
            above = True
            waiting = 4
else :
    waiting -= 1

# loop through notes to see if any are held down
note_down = False
for note in etc.midi_notes :
    if note != 0 : note_down = True
    
    # display image if down
    if note_down : 
        image_index += 1
    if image_index == len(images) : image_index = 0
    img = images[image_index]
    ximg = int(img.get_width() * etc.knob3)
    yimg = int(img.get_height() * etc.knob3)
    img = pygame.transform.scale(img, (ximg, yimg) )
    
    img.fill((255, 255, 255, etc.knob4 *255), None, pygame.BLEND_RGBA_MULT)

    y = int(etc.knob2 * yr) - int(img.get_height() * .5)
    x = int(etc.knob1 * xr) - int(img.get_width() * .5)
    screen.blit(img, (x,y))

Looks like something is a little mixed up, hard to tell from pasted code. (btw, try using``` to start and end a block of code)

Try this one:

import os
import pygame
import glob

#important! make sure images are scaled to display resolution beforehand; smaller is faster
images = []
image_index = 0
fall = 0
scoot = 0
bg = pygame.Surface((656,416))
waiting = 0
xr = 320
yr = 240

def setup(screen, etc) :
    global images, fall, bg, xr, yr
    xr = etc.xres
    yr = etc.yres

    bg = pygame.Surface((xr,yr))

    for filepath in sorted(glob.glob(etc.mode_root + '/Images/*.png')):
        filename = os.path.basename(filepath)
        print 'loading image file: ' + filename
        img = pygame.image.load(filepath)
        images.append(img)

def draw(screen, etc) :
    global images, image_index, fall, bg, scoot, waiting, xr, yr
    etc.color_picker_bg(etc.knob5)
    above = False
    
    if waiting == 0 :
        for i in range(0, 100) :
            if abs(etc.audio_in[i]) > 1000 :
                above = True
                waiting = 4
    else :
        waiting -= 1
    
    # loop through notes to see if any are held down
    note_down = False
    for note in etc.midi_notes :
        if note != 0 : note_down = True
    
    # display image if down
    if note_down :
        
    #if etc.audio_trig or etc.midi_note_new :
        image_index += 1
        if image_index == len(images) : image_index = 0
        img = images[image_index]
        ximg = int(img.get_width() * etc.knob3)
        yimg = int(img.get_height() * etc.knob3)
        img = pygame.transform.scale(img, (ximg, yimg) )
        
        img.fill((255, 255, 255, etc.knob4 * 255), None, pygame.BLEND_RGBA_MULT)
    
        y = int(etc.knob2 * yr) - int(img.get_height() * .5)
        x = int(etc.knob1 * xr) - int(img.get_width() * .5)
        screen.blit(img, (x,y))

Yes this works! Great, thanks!!