Changeset 0529a19 in buchla-emu


Ignore:
Timestamp:
10/26/2017 08:04:09 PM (7 years ago)
Author:
Alexander Heinrich <alex.heinrich@…>
Branches:
master
Children:
5326a5e
Parents:
0d83ce8
Message:

Add basic handling of midi input.

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    r0d83ce8 r0529a19  
    33ifndef WIN
    44GCC :=                  gcc
     5GPP :=                  g++
    56SDL2 :=                 /opt/sdl2
     7RTMIDI :=               /opt/rtmidi
    68EXT :=
    79else
     
    1416SDL2_LIB :=             $(SDL2)/lib
    1517
     18RTMIDI_INC :=   $(RTMIDI)/include
     19RTMIDI_LIB :=   $(RTMIDI)/lib
     20
    1621FLAGS :=                -std=c99 -O2 -gdwarf-4
    1722
     
    2328                                -Wpedantic -Wconversion -Wsign-conversion -Wshadow \
    2429                                -Wstrict-prototypes -Wmissing-declarations -Wredundant-decls \
    25                                 -I cpu -I emu -I build -I $(SDL2_INC)
     30                                -I cpu -I emu -I build -I $(SDL2_INC) -I $(RTMIDI_INC)
    2631
    2732FLAGS_AUX :=    $(FLAGS) -Wall -Wextra \
     
    3742                                $(SDL2_LIB)/libSDL2_ttf.a \
    3843                                $(SDL2_LIB)/libfreetype.a \
     44                                $(RTMIDI_LIB)/librtmidi.a \
    3945                                -ldl -lm
    4046endif
     
    4753                                $(SDL2_LIB)/libSDL2_ttf.a \
    4854                                $(SDL2_LIB)/libfreetype.a \
     55                                $(RTMIDI_LIB)/librtmidi.a \
    4956                                -framework AppKit \
    5057                                -framework AudioToolbox \
    5158                                -framework Carbon \
     59                                -framework CoreMIDI \
    5260                                -framework CoreAudio \
    5361                                -framework CoreFoundation \
     
    116124
    117125buchla$(EXT):   $(CPU_OP) $(GEN_OP)     $(EMU_OP)
    118                                 $(GCC) $(FLAGS_LNK) -o buchla$(EXT) \
     126                                $(GPP) $(FLAGS_LNK) -o buchla$(EXT) \
    119127                                $(CPU_OP) $(GEN_OP) $(EMU_OP) \
    120128                                $(LIBS)
  • emu/cpu.c

    r0d83ce8 r0529a19  
    9191        { 0x3a4001, 0x3a8001, 0, lcd_init, lcd_quit, lcd_exec, lcd_read, lcd_write },
    9292        { 0x3a8001, 0x3ac001, 5, ser_init, ser_quit, ser_exec, ser_read, ser_write },
    93         { 0x3ac001, 0x3b0001, 0, mid_init, mid_quit, mid_exec, mid_read, mid_write },
     93        { 0x3ac001, 0x3b0001, 5, mid_init, mid_quit, mid_exec, mid_read, mid_write },
    9494        { 0x3b0001, 0x3b4001, 0, fdd_init, fdd_quit, fdd_exec, fdd_read, fdd_write },
    9595        { 0x3b4001, 0x3b8001, 0, snd_init, snd_quit, snd_exec, snd_read, snd_write },
  • emu/mid.c

    r0d83ce8 r0529a19  
    1717
    1818#include <all.h>
     19#include <rtmidi/rtmidi_c.h>
    1920
    2021#define ver(...) _ver(mid_verbose, 0, __VA_ARGS__)
    2122#define ver2(...) _ver(mid_verbose, 1, __VA_ARGS__)
    2223#define ver3(...) _ver(mid_verbose, 2, __VA_ARGS__)
    23 
    24 int32_t mid_verbose = 0;
    2524
    2625#define REG_IER_ISR 0
     
    2928#define REG_TDR_RDR 3
    3029
     30#define BUF_SZ 128
     31
     32typedef struct {
     33        int32_t buf_hd;
     34        int32_t buf_tl;
     35        uint8_t buf[BUF_SZ];
     36        bool irq_r;
     37        bool irq_t;
     38        bool rdr_ok;
     39        uint8_t rdr;
     40} state_t;
     41
     42static state_t state[] = {
     43        { .buf_hd = 0, .buf_tl = 0, .irq_r = false, .irq_t = false, .rdr_ok = false, .rdr = 0x00 },
     44        { .buf_hd = 0, .buf_tl = 0, .irq_r = false, .irq_t = false, .rdr_ok = false, .rdr = 0x00 }
     45};
     46
     47int32_t mid_verbose = 0;
     48
     49struct RtMidiWrapper* midiin;
     50
     51static void xmit(int32_t un)
     52{
     53        int32_t i = state[un].buf_tl;
     54        ver2("mid xmit %d %d", i, state[un].buf_hd);
     55
     56        if (i >= state[un].buf_hd) {
     57                return;
     58        }
     59
     60        uint8_t byte = state[un].buf[i % BUF_SZ];
     61        ver2("mid xmit 0x%02x", byte);
     62
     63        state[un].rdr = byte;
     64        state[un].rdr_ok = true;
     65        state[un].irq_r = true;
     66
     67        state[un].buf_tl = i + 1;
     68
     69        if (state[un].buf_tl >= BUF_SZ) {
     70                state[un].buf_hd -= BUF_SZ;
     71                state[un].buf_tl -= BUF_SZ;
     72                ver2("mid adj %d %d", state[un].buf_tl, state[un].buf_hd);
     73        }
     74}
     75
     76static void out_lk(int32_t un, uint8_t c)
     77{
     78        int32_t i = state[un].buf_hd;
     79        ver2("mid out %d %d 0x%02x", state[un].buf_tl, i, c);
     80
     81        if (i >= state[un].buf_tl + BUF_SZ) {
     82                err("midi port %d losing data", un);
     83                return;
     84        }
     85
     86        state[un].buf[i % BUF_SZ] = c;
     87        state[un].buf_hd = i + 1;
     88
     89        if (!state[un].irq_r && !state[un].rdr_ok) {
     90                xmit(un);
     91        }
     92}
     93
     94static void out(int32_t un, uint8_t c)
     95{
     96        if (SDL_LockMutex(cpu_mutex) < 0) {
     97                fail("SDL_LockMutex() failed: %s", SDL_GetError());
     98        }
     99
     100        out_lk(un, c);
     101
     102        if (SDL_UnlockMutex(cpu_mutex) < 0) {
     103                fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
     104        }
     105}
     106
     107static void midi_callback(double timeStamp, const unsigned char* message, void *userData) {
     108        ver2("Timestamp %f\n", timeStamp);
     109
     110        for (uint8_t i = 0; i < sizeof(message); i++) {
     111                ver2("Message %i %u", i, (uint8_t) message[i]);
     112                out(0, message[i]);
     113        }
     114}
     115
    31116void mid_init(void)
    32117{
    33118        ver("mid init");
     119
     120        midiin = rtmidi_in_create_default();
     121        ver2("%p", midiin->ptr);
     122        // check if null
     123        uint32_t portcount = rtmidi_get_port_count(midiin);
     124        ver2("%d", midiin->ok);
     125
     126        if (portcount == 0) {
     127                midiin = NULL;
     128                ver2("no midi ports\n");
     129                return;
     130        }
     131
     132        for (uint32_t i = 0; i < portcount; i++) {
     133                ver2("Port %d: %s", i, rtmidi_get_port_name(midiin, i));
     134        }
     135
     136        rtmidi_open_port(midiin, 0, rtmidi_get_port_name(midiin, 0));
     137        if(!midiin->ok) {
     138                fail("Failed to open Midi port");
     139        }
     140
     141        rtmidi_in_set_callback(midiin, midi_callback, midiin->data);
     142        if(!midiin->ok) {
     143                fail("Failed to set Midi Callback");
     144        }
    34145}
    35146
    36147void mid_quit(void)
    37148{
     149        if(midiin) {
     150                rtmidi_close_port(midiin);
     151                rtmidi_in_free(midiin);
     152        }
     153
    38154        ver("mid quit");
    39155}
     
    42158{
    43159        ver3("mid exec");
    44         return false;
     160        return state[0].irq_r || state[0].irq_t || state[1].irq_r || state[1].irq_t;
    45161}
    46162
     
    48164{
    49165        ver2("mid rd %u:%d", off, sz * 8);
    50         return 0;
     166
     167        if (sz != 1 || off > 7) {
     168                fail("invalid mid rd %u:%d", off, sz * 8);
     169        }
     170
     171        int32_t rg = (int32_t)(off % 4);
     172        int32_t un = (int32_t)(off / 4);
     173
     174        uint32_t rv;
     175
     176        switch (rg) {
     177        case REG_IER_ISR:
     178                rv = (uint32_t)(0xc0 | (state[un].rdr_ok ? 0x01 : 0x00));
     179                state[un].irq_r = false;
     180                state[un].irq_t = false;
     181                ver2("ISR[%d] 0x%02x", un, rv);
     182                break;
     183
     184        case REG_TDR_RDR:
     185                rv = state[un].rdr;
     186                state[un].rdr_ok = false;
     187                ver2("RDR[%d] 0x%02x", un, rv);
     188                break;
     189
     190        default:
     191                rv = 0x00;
     192                break;
     193        }
     194
     195        if (!state[un].irq_r && !state[un].rdr_ok) {
     196                xmit(un);
     197        }
     198
     199        return rv;
    51200}
    52201
  • readme.txt

    r0d83ce8 r0529a19  
    9191  ../configure --prefix=/opt/sdl2 --with-sdl-prefix=/opt/sdl2
    9292
     93  make
     94  make install
     95 
     96  # Build and install rtmidi
     97 
     98  tar zxvf rtmidi-3.0.0.tar.gz
     99  cd rtmidi-3.0.0
     100  mkdir build
     101  cd build
     102 
     103  ../configure --prefix=/opt/rtmidi
     104 
    93105  make
    94106  make install
Note: See TracChangeset for help on using the changeset viewer.