My first post here was a question about whether it’s possible to write an SDL2 program to write midi commands to a midi output port under macOS . I wanted to add some text to this question saying that I succeeded a bit and then the whole message went into the orcus due to an editing error that occured to me. So I’m starting over from the point I have reached now:
I asked AI to write a little app under macOS and SDL2 that writes out a midi note (which I then can use as a basis for further development) Goal is to read Midi-OX logfiles and write the Midi Codes in there to the Midi Outputport (using the correct timestamp that’s in the log file).
This is what I got (based on macports rtmidi and SDL2):
seq.cpp:
#include <SDL2/SDL.h> // Header path often varies slightly by system
#include <rtmidi/RtMidi.h>
#include
#include
int main(int argc, char* argv
) {
// 1. Initialize MIDI Output
RtMidiOut *midiout = new RtMidiOut();
if (midiout->getPortCount() == 0) {
std::cerr << “No MIDI ports available!” << std::endl;
delete midiout;
return 1;
}
midiout->openPort(0); // Open first available MIDI port
// 2. Initialize SDL2
if (SDL_Init(SDL_INIT_VIDEO) < 0) return -1;
SDL_Window* window = SDL_CreateWindow("MIDI Sequencer", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);
bool running = true;
SDL_Event event;
std::vector<unsigned char> message;
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) running = false;
// Example: Press 'Space' to send a MIDI Note On
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_SPACE) {
message.clear();
message.push_back(144); // Note On (Channel 1)
message.push_back(60); // Middle C
message.push_back(90); // Velocity
midiout->sendMessage(&message);
std::cout << "Sent: Note On (C3)" << std::endl;
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
// Cleanup
delete midiout;
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Makefile:
# Compiler Settings
CXX := clang++
CXXFLAGS := -std=c++17 -Wall -Wextra -D__MACOSX_CORE__
TARGET := midi_app
# MacPorts Paths
MACPORTS_PATH := /opt/local
INCLUDES := -I$(MACPORTS_PATH)/include
LDFLAGS := -L$(MACPORTS_PATH)/lib
# Libraries
# SDL2 und RtMidi requirements macOS System-Frameworks
LIBS := -lSDL2 -lrtmidi \
-framework CoreMIDI \
-framework CoreAudio \
-framework CoreFoundation \
-framework AudioToolbox \
-framework AudioUnit
# Source Files
SRCS := seq.cpp
OBJS := $(SRCS:.cpp=.o)
# Standard Target
all: $(TARGET)
$(TARGET): $(OBJS)
$(CXX) $(OBJS) -o $(TARGET) $(LDFLAGS) $(LIBS)
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
# Misc
clean:
rm -f $(OBJS) $(TARGET)
run: all
./$(TARGET)
.PHONY: all clean run
I succeeded with the above code and added a slight modification, to find out which output port it was suitable to write to.
#include <SDL2/SDL.h> // Header path often varies slightly by system
#include <rtmidi/RtMidi.h>
#include <vector>
#include <iostream>
int main(int argc, char* argv[]) {
int port_count=0;
// 1. Initialize MIDI Output
RtMidiOut *midiout = new RtMidiOut();
if ((port_count=midiout->getPortCount()) == 0) {
std::cerr << "No MIDI ports available!" << std::endl;
delete midiout;
return 1;
}
std::cout << "# of ports: " << port_count << std::endl;
for(int i=0;i<port_count;i++) {
std::cout << midiout->getPortName(i) << std::endl;
}
midiout->openPort(1); // Open first available MIDI port
// 2. Initialize SDL2
if (SDL_Init(SDL_INIT_VIDEO) < 0) return -1;
SDL_Window* window = SDL_CreateWindow("MIDI Sequencer", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);
bool running = true;
SDL_Event event;
std::vector<unsigned char> message;
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) running = false;
// Example: Press 'Space' to send a MIDI Note On
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_SPACE) {
message.clear();
message.push_back(144); // Note On (Channel 1)
message.push_back(60); // Middle C
message.push_back(90); // Velocity
midiout->sendMessage(&message);
std::cout << "Sent: Note On (C3)" << std::endl;
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
// Cleanup
delete midiout;
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Just wanted to share. No more questions. Thank you.