- Se incorporó
- 17 Marzo 2005
- Mensajes
- 29.450
Este proyecto lo realicé con código creado a medida por Gemini.
Esto nace por una necesidad de controlar los cambios de volumen, especialmente para los sonidos de orquesta. Pero también sirve para controlar otros parámetros.
La idea es hacerlo como al dirigir una orquesta, indicando con la mano cuándo subir o bajar el volumen.
La aplicación es gratis y va sin ninguna garantía de ningún tipo.
## 1. Instalación Inicial (Solo una vez)
* Descarga e instala el cable virtual loopMIDI desde este enlace:
www.tobias-erichsen.de
* Abre loopMIDI, haz clic en el botón "+" (abajo a la izquierda) para crear tu puerto virtual. No cierres la ventana, que quede detrás de los otros procesos.
* Guarda el archivo Cam & Hand.exe en una carpeta de fácil acceso, como tu Escritorio (descarga primero el .rar).
## 2. Orden de Encendido (Cada vez que trabajes)
* Abre loopMIDI para asegurar que el cable virtual esté activo.
* Abre Cam & Hand.exe con doble clic y verifica que el botón en la pantalla de video esté en "ON".
* Abre Reaper de forma normal.
## 3. Configuración en Reaper
* Ve al menú superior, haz clic en "Actions" y selecciona "Show action list...".
* En el buscador superior (Filter), escribe exactamente esto: Adjust last touched parameter
* Selecciona la acción de la lista llamada "FX: Adjust last touched parameter (MIDI CC/OSC only)".
* Haz clic en el botón "Add..." (abajo a la izquierda de la ventana).
* Mueve tu mano frente a la cámara para que el sistema capture el MIDI CC 119 y presiona "OK".
* Cierra la ventana de la lista de acciones.
## 4. Flujo de Trabajo Musical
* Abre el plugin o instrumento virtual en el que vayas a trabajar.
* Haz un clic con el ratón sobre cualquier perilla que desees mover (volumen, modulación, brillo, etc.).
* Mueve tu mano frente a la cámara; ese parámetro te obedecerá al instante.
* Si necesitas detener el control temporalmente, haz clic con el ratón sobre el botón verde "ON" en la ventana de tu cámara para pausarlo.
*Si requiere grabar el volumen, revisar que está todo bien configurado en las automatizaciones:
Esto nace por una necesidad de controlar los cambios de volumen, especialmente para los sonidos de orquesta. Pero también sirve para controlar otros parámetros.
La idea es hacerlo como al dirigir una orquesta, indicando con la mano cuándo subir o bajar el volumen.
La aplicación es gratis y va sin ninguna garantía de ningún tipo.
## 1. Instalación Inicial (Solo una vez)
* Descarga e instala el cable virtual loopMIDI desde este enlace:
loopMIDI | Tobias Erichsen
* Abre loopMIDI, haz clic en el botón "+" (abajo a la izquierda) para crear tu puerto virtual. No cierres la ventana, que quede detrás de los otros procesos.
* Guarda el archivo Cam & Hand.exe en una carpeta de fácil acceso, como tu Escritorio (descarga primero el .rar).
## 2. Orden de Encendido (Cada vez que trabajes)
* Abre loopMIDI para asegurar que el cable virtual esté activo.
* Abre Cam & Hand.exe con doble clic y verifica que el botón en la pantalla de video esté en "ON".
* Abre Reaper de forma normal.
## 3. Configuración en Reaper
* Ve al menú superior, haz clic en "Actions" y selecciona "Show action list...".
* En el buscador superior (Filter), escribe exactamente esto: Adjust last touched parameter
* Selecciona la acción de la lista llamada "FX: Adjust last touched parameter (MIDI CC/OSC only)".
* Haz clic en el botón "Add..." (abajo a la izquierda de la ventana).
* Mueve tu mano frente a la cámara para que el sistema capture el MIDI CC 119 y presiona "OK".
* Cierra la ventana de la lista de acciones.
## 4. Flujo de Trabajo Musical
* Abre el plugin o instrumento virtual en el que vayas a trabajar.
* Haz un clic con el ratón sobre cualquier perilla que desees mover (volumen, modulación, brillo, etc.).
* Mueve tu mano frente a la cámara; ese parámetro te obedecerá al instante.
* Si necesitas detener el control temporalmente, haz clic con el ratón sobre el botón verde "ON" en la ventana de tu cámara para pausarlo.
*Si requiere grabar el volumen, revisar que está todo bien configurado en las automatizaciones:
Python:
import cv2
import mediapipe as mp
import mido
def nada(x):
pass
# Estado global del botón de encendido/apagado
activo = True
# Función para detectar los clics del mouse en la pantalla
def click_raton(evento, x, y, flags, param):
global activo
if evento == cv2.EVENT_LBUTTONDOWN:
# Coordenadas donde estará dibujado nuestro botón
if 10 <= x <= 150 and 40 <= y <= 80:
activo = not activo
puertos = mido.get_output_names()
puerto_correcto = next((p for p in puertos if 'loopMIDI' in p), None)
if not puerto_correcto:
print("Error: No se encontró loopMIDI. Ábrelo y crea el puerto.")
exit()
salida_midi = mido.open_output(puerto_correcto)
print(f"Éxito. Conectado a: {puerto_correcto}")
mp_manos = mp.solutions.hands
mp_dibujo = mp.solutions.drawing_utils
manos = mp_manos.Hands(max_num_hands=1, min_detection_confidence=0.7, min_tracking_confidence=0.7)
cap = cv2.VideoCapture(0)
cv2.namedWindow('Controlador MIDI')
cv2.setWindowProperty('Controlador MIDI', cv2.WND_PROP_TOPMOST, 1)
# Asignar el detector de clics del mouse a nuestra ventana
cv2.setMouseCallback('Controlador MIDI', click_raton)
cv2.createTrackbar('CC Min (Fondo)', 'Controlador MIDI', 0, 127, nada)
cv2.createTrackbar('CC Max (Techo)', 'Controlador MIDI', 127, 127, nada)
cv2.createTrackbar('Tope Arriba', 'Controlador MIDI', 20, 100, nada)
cv2.createTrackbar('Tope Abajo', 'Controlador MIDI', 80, 100, nada)
cv2.createTrackbar('Suavizado', 'Controlador MIDI', 85, 99, nada)
valor_suavizado = 0.0
ultimo_valor_enviado = -1
mano_detectada_previamente = False
while cap.isOpened():
exito, frame = cap.read()
if not exito:
break
frame = cv2.flip(frame, 1)
cc_min = cv2.getTrackbarPos('CC Min (Fondo)', 'Controlador MIDI')
cc_max = cv2.getTrackbarPos('CC Max (Techo)', 'Controlador MIDI')
limite_sup = cv2.getTrackbarPos('Tope Arriba', 'Controlador MIDI') / 100.0
limite_inf = cv2.getTrackbarPos('Tope Abajo', 'Controlador MIDI') / 100.0
suavizado = cv2.getTrackbarPos('Suavizado', 'Controlador MIDI') / 100.0
if limite_sup >= limite_inf:
limite_sup = limite_inf - 0.05
alto, ancho, _ = frame.shape
cv2.line(frame, (0, int(limite_sup * alto)), (ancho, int(limite_sup * alto)), (0, 255, 0), 2)
cv2.line(frame, (0, int(limite_inf * alto)), (ancho, int(limite_inf * alto)), (0, 0, 255), 2)
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
resultados = manos.process(frame_rgb)
# ---------------------------------------------------------
# DIBUJAR EL BOTÓN INTERACTIVO
# ---------------------------------------------------------
color_boton = (0, 200, 0) if activo else (0, 0, 200)
texto_boton = "ON" if activo else "PAUSA"
cv2.rectangle(frame, (10, 40), (150, 80), color_boton, -1)
cv2.rectangle(frame, (10, 40), (150, 80), (255, 255, 255), 2)
cv2.putText(frame, texto_boton, (45, 67), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 2, cv2.LINE_AA)
# ---------------------------------------------------------
if resultados.multi_hand_landmarks:
mano = resultados.multi_hand_landmarks[0]
mp_dibujo.draw_landmarks(frame, mano, mp_manos.HAND_CONNECTIONS)
indice_y = mano.landmark[8].y
rango_fisico = limite_inf - limite_sup
posicion_bruta = (limite_inf - indice_y) / rango_fisico
rango_val = cc_max - cc_min
valor_objetivo = cc_min + (posicion_bruta * rango_val)
if not mano_detectada_previamente:
valor_suavizado = valor_objetivo
mano_detectada_previamente = True
else:
valor_suavizado = (valor_suavizado * suavizado) + (valor_objetivo * (1.0 - suavizado))
v_min_real = min(cc_min, cc_max)
v_max_real = max(cc_min, cc_max)
valor_final = int(max(v_min_real, min(v_max_real, valor_suavizado)))
if activo:
if valor_final != ultimo_valor_enviado:
mensaje = mido.Message('control_change', channel=0, control=119, value=valor_final)
salida_midi.send(mensaje)
ultimo_valor_enviado = valor_final
cv2.putText(frame, f"MIDI ENVIADO: {valor_final}", (170, 67), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
else:
ultimo_valor_enviado = -1
else:
mano_detectada_previamente = False
cv2.imshow('Controlador MIDI', frame)
# También puedes presionar la barra espaciadora en tu teclado para pausar
tecla = cv2.waitKey(1) & 0xFF
if tecla == ord('q'):
break
elif tecla == ord(' '):
activo = not activo
salida_midi.close()
cap.release()
cv2.destroyAllWindows()
Última modificación: