Ticket #7920: mididriver.diff

File mididriver.diff, 15.6 KB (added by SF/chuzwuzza, 19 years ago)

midi driver interface patch

  • Makefile

    Common subdirectories: scummvm.orig/CVS and scummvm.new/CVS
    diff -u scummvm.orig/Makefile scummvm.new/Makefile
    old new  
    22
    33CC      = gcc
    44CFLAGS  = -g -Wno-multichar
    5 DEFINES = -DUNIX -DHAVE_READLINE -DUSE_TIMIDITY
     5DEFINES = -DUNIX -DHAVE_READLINE
    66LDFLAGS :=
    77INCLUDES:= `sdl-config --cflags`
    88CPPFLAGS= $(DEFINES) $(INCLUDES)
  • imuse.cpp

    Common subdirectories: scummvm.orig/debian and scummvm.new/debian
    diff -u scummvm.orig/imuse.cpp scummvm.new/imuse.cpp
    old new  
    2626#include "scumm.h"
    2727#include "sound.h"
    2828
    29 #ifdef USE_TIMIDITY
     29/* includes needed for unix midi support through timidity or internal sequencer */
     30#ifndef WIN32
     31
    3032#include <sys/time.h>
    3133#include <unistd.h>
    3234#include <sys/types.h>
     
    4042/* Copy-pasted from Timidity */
    4143#define SEQ_MIDIPUTC            5
    4244
    43 #endif /* USE_TIMIDITY */
     45#endif
    4446
    4547#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
    4648
     
    155157        return 0;
    156158}
    157159
     160void SoundEngine::midiSetDriver(int devicetype, int seq_device) {
     161        _midi_driver.DeviceType = devicetype;
     162        _midi_driver.SeqDevice = seq_device;
     163        _midi_driver.midiInit();
     164}
     165
     166void SoundEngine::midiSetDriver(int devicetype) {
     167        _midi_driver.DeviceType = devicetype;
     168        _midi_driver.midiInit();
     169}
     170
     171int MidiDriver::connect_to_timidity(int port) {
     172        struct hostent *serverhost;
     173        struct sockaddr_in sadd;
     174        int s;
     175       
     176        serverhost = gethostbyname("localhost");
     177        if (serverhost == NULL)
     178                error("Could not resolve host");
     179        sadd.sin_family = serverhost->h_addrtype;
     180        sadd.sin_port = htons(port);
     181        memcpy(&(sadd.sin_addr), serverhost->h_addr_list[0], serverhost->h_length);
     182       
     183        s = socket(AF_INET,SOCK_STREAM,0);
     184        if (s < 0)
     185                error("Could not open socket");
     186        if (connect(s, (struct sockaddr *) &sadd, sizeof(struct sockaddr_in)) < 0)
     187                error("Could not connect to server");
     188       
     189        return s;
     190}
     191
     192int MidiDriver::open_sequencer_device() {
     193        int device;
     194        device = (open("/dev/sequencer", O_RDWR, 0));
     195        if (device < 0) {
     196                        warning("Cannot open sequencer device - using /dev/null (no music will be heard) ");
     197                device = (open(("/dev/null"), O_RDWR, 0));
     198                if (device < 0)
     199                        error("Cannot open /dev/null to dump midi output");
     200        }
     201        return device;
     202}
     203
     204void MidiDriver::midiInitTimidity() {
     205        int s, s2;
     206        int len;
     207        int dummy, newport;
     208        char buf[256];
     209       
     210        SeqDevice = 0;
     211
     212        s = connect_to_timidity(7777);
     213        len = read(s, buf, 256);
     214        buf[len] = '\0';
     215        printf("%s", buf);
     216
     217        sprintf(buf, "SETBUF %f %f\n", 0.1, 0.15);
     218        write(s, buf, strlen(buf));
     219        len = read(s, buf, 256);
     220        buf[len] = '\0';
     221        printf("%s", buf);     
     222       
     223        sprintf(buf, "OPEN lsb\n");
     224        write(s, buf, strlen(buf));
     225        len = read(s, buf, 256);
     226        buf[len] = '\0';
     227        printf("%s", buf);     
     228
     229        sscanf(buf, "%d %d", &dummy, &newport);
     230        printf("         => port = %d\n", newport);
     231       
     232        s2 = connect_to_timidity(newport);
     233        _mo = (void *) s2;
     234}
     235
     236void MidiDriver::midiInitSeq() {
     237        int device;
     238        device = open_sequencer_device();
     239        _mo = (void *) device;
     240}
     241
     242void MidiDriver::midiInitWindows() {
     243        #ifdef WIN32
     244        if (midiOutOpen((HMIDIOUT*)&_mo, MIDI_MAPPER, NULL, NULL, 0) != MMSYSERR_NOERROR)
     245                error("midiOutOpen failed");
     246        #endif
     247}
     248
     249void MidiDriver::midiInitNull() {
     250        warning("Using the NULL midi driver, no music will be heard");
     251}
     252
     253void MidiDriver::midiInit() {
     254        if (MidiInitialized != true) {
     255                switch (DeviceType) {
     256                case MIDI_NULL:
     257                        midiInitNull();
     258                        break;
     259                case MIDI_WINDOWS:
     260                        midiInitWindows();
     261                        break;
     262                case MIDI_TIMIDITY:
     263                        midiInitTimidity();
     264                        break;
     265                case MIDI_SEQ:
     266                        midiInitSeq();
     267                        break;
     268                default:
     269                        #ifdef WIN32
     270                        midiInitWindows();
     271                        #else
     272                        DeviceType = 0;
     273                        midiInitNull();
     274                        #endif
     275                        break;
     276                }
     277                MidiInitialized = true;
     278        } else {
     279                error("Midi driver already initialized");
     280        }
     281}
     282
     283void MidiDriver::MidiOutSeq(void *a, int b) {
     284        int s = (int) a;
     285        unsigned char buf[256];
     286        int position = 0;
     287        switch (b & 0xF0) {
     288        case 0x80:
     289        case 0x90:
     290        case 0xA0:
     291        case 0xB0:
     292        case 0xE0:
     293                buf[position++] = SEQ_MIDIPUTC;
     294                buf[position++] = b;
     295                buf[position++] = SeqDevice;           
     296                buf[position++] = 0;
     297                buf[position++] = SEQ_MIDIPUTC;
     298                buf[position++] = (b >> 8) & 0x7F;
     299                buf[position++] = SeqDevice;           
     300                buf[position++] = 0;
     301                buf[position++] = SEQ_MIDIPUTC;
     302                buf[position++] = (b >> 16) & 0x7F;
     303                buf[position++] = SeqDevice;           
     304                buf[position++] = 0;
     305                break;
     306        case 0xC0:
     307        case 0xD0:
     308                buf[position++] = SEQ_MIDIPUTC;
     309                buf[position++] = b;
     310                buf[position++] = SeqDevice;           
     311                buf[position++] = 0;
     312                buf[position++] = SEQ_MIDIPUTC;
     313                buf[position++] = (b >> 8) & 0x7F;
     314                buf[position++] = SeqDevice;           
     315                buf[position++] = 0;
     316                break;
     317        default:
     318                fprintf(stderr, "Unknown : %08x\n", b);
     319                break;
     320        }
     321        write(s, buf, position);
     322}
     323
     324void MidiDriver::MidiOutWindows(void *a, int b) {
     325        #ifdef WIN32
     326        midiOutShortMsg((HMIDIOUT) a, b);
     327        #endif 
     328}
     329
     330void MidiDriver::MidiOut(void *a, int b) {
     331        if (MidiInitialized != true) {
     332                #ifdef WIN32
     333                DeviceType = MIDI_WINDOWS;
     334                midiInit();
     335                #else
     336                DeviceType = MIDI_NULL;
     337                midiInit();
     338                #endif
     339        }
     340       
     341        if (MidiInitialized == true) {
     342                switch (DeviceType) {
     343                case MIDI_NULL:
     344                        break;
     345                case MIDI_WINDOWS:
     346                        MidiOutWindows(a, b);
     347                        break;
     348                case MIDI_TIMIDITY:
     349                case MIDI_SEQ:
     350                        MidiOutSeq(a, b);
     351                        break;
     352                default:
     353                        error("Invalid midi device type ");
     354                        break;
     355                }
     356        } else {
     357                warning("Trying to write midi data without the driver being initialized");
     358        }
     359}
     360
    158361/**********************************************************************/
    159362
    160363byte *SoundEngine::findTag(int sound, char *tag, int index) {
     
    9141117        init_volume_fader();
    9151118        init_queue();
    9161119        init_parts();
    917         midiInit();
    9181120
    9191121        _initialized = true;
    9201122       
     
    24622664        }
    24632665}
    24642666
    2465 #if defined(WIN32)
    2466 
    2467 void SoundEngine::midiInit() {
    2468         if (midiOutOpen((HMIDIOUT*)&_mo, MIDI_MAPPER, NULL, NULL, 0) != MMSYSERR_NOERROR)
    2469                 error("midiOutOpen failed");
    2470 }
    2471 
    2472 #define MIDI_OUT(a,b) midiOutShortMsg((HMIDIOUT)(a), (b))
    2473 
    2474 #elif defined(USE_TIMIDITY)
    2475 
    2476 static int connect_to_timidity(int port)
    2477 {
    2478         struct hostent *serverhost;
    2479         struct sockaddr_in sadd;
    2480         int s;
    2481        
    2482         serverhost = gethostbyname("localhost");
    2483         if (serverhost == NULL)
    2484                 error("Could not resolve host");
    2485         sadd.sin_family = serverhost->h_addrtype;
    2486         sadd.sin_port = htons(port);
    2487         memcpy(&(sadd.sin_addr), serverhost->h_addr_list[0], serverhost->h_length);
    2488        
    2489         s = socket(AF_INET,SOCK_STREAM,0);
    2490         if (s < 0)
    2491                 error("Could not open socket");
    2492         if (connect(s, (struct sockaddr *) &sadd, sizeof(struct sockaddr_in)) < 0)
    2493                 error("Could not connect to server");
    2494        
    2495         return s;
    2496 }
    2497 
    2498 void SoundEngine::midiInit() {
    2499         int s, s2;
    2500         int len;
    2501         int dummy, newport;
    2502         char buf[256];
    2503 
    2504         s = connect_to_timidity(7777);
    2505         len = read(s, buf, 256);
    2506         buf[len] = '\0';
    2507         printf("%s", buf);
    2508 
    2509         sprintf(buf, "SETBUF %f %f\n", 0.1, 0.15);
    2510         write(s, buf, strlen(buf));
    2511         len = read(s, buf, 256);
    2512         buf[len] = '\0';
    2513         printf("%s", buf);     
    2514        
    2515         sprintf(buf, "OPEN lsb\n");
    2516         write(s, buf, strlen(buf));
    2517         len = read(s, buf, 256);
    2518         buf[len] = '\0';
    2519         printf("%s", buf);     
    2520 
    2521         sscanf(buf, "%d %d", &dummy, &newport);
    2522         printf("         => port = %d\n", newport);
    2523        
    2524         s2 = connect_to_timidity(newport);
    2525         _mo = (void *) s2;
    2526 }
    2527 
    2528 #define DEVICE_NUM 0
    2529 
    2530 static inline void MIDI_OUT(void *a, int b) {
    2531         int s = (int) a;
    2532         unsigned char buf[256];
    2533         int position = 0;
    2534        
    2535         switch (b & 0xF0) {
    2536         case 0x80:
    2537         case 0x90:
    2538         case 0xA0:
    2539         case 0xB0:
    2540         case 0xE0:
    2541                 buf[position++] = SEQ_MIDIPUTC;
    2542                 buf[position++] = b;
    2543                 buf[position++] = DEVICE_NUM;           
    2544                 buf[position++] = 0;
    2545                 buf[position++] = SEQ_MIDIPUTC;
    2546                 buf[position++] = (b >> 8) & 0x7F;
    2547                 buf[position++] = DEVICE_NUM;           
    2548                 buf[position++] = 0;
    2549                 buf[position++] = SEQ_MIDIPUTC;
    2550                 buf[position++] = (b >> 16) & 0x7F;
    2551                 buf[position++] = DEVICE_NUM;           
    2552                 buf[position++] = 0;
    2553                 break;
    2554         case 0xC0:
    2555         case 0xD0:
    2556                 buf[position++] = SEQ_MIDIPUTC;
    2557                 buf[position++] = b;
    2558                 buf[position++] = DEVICE_NUM;           
    2559                 buf[position++] = 0;
    2560                 buf[position++] = SEQ_MIDIPUTC;
    2561                 buf[position++] = (b >> 8) & 0x7F;
    2562                 buf[position++] = DEVICE_NUM;           
    2563                 buf[position++] = 0;
    2564                 break;
    2565         default:
    2566                 fprintf(stderr, "Unknown : %08x\n", b);
    2567                 break;
    2568         }
    2569         write(s, buf, position);
    2570 }
    2571 
    2572 #else
    2573 #define MIDI_OUT(a,b)
    2574 void SoundEngine::midiInit() { }
    2575 #endif
    2576 
    25772667void SoundEngine::midiPitchBend(byte chan, int16 pitchbend) {
    25782668        uint16 tmp;
    25792669
    25802670        if (_midi_pitchbend_last[chan] != pitchbend) {
    25812671                _midi_pitchbend_last[chan] = pitchbend;
    25822672                tmp = (pitchbend<<2) + 0x2000;
    2583                 MIDI_OUT(_mo, ((tmp>>7)&0x7F)<<16 | (tmp&0x7F)<<8 | 0xE0 | chan);
     2673                _midi_driver.MidiOut(_midi_driver._mo, ((tmp>>7)&0x7F)<<16 | (tmp&0x7F)<<8 | 0xE0 | chan);
    25842674        }
    25852675}
    25862676
    25872677void SoundEngine::midiVolume(byte chan, byte volume) {
    25882678        if (_midi_volume_last[chan] != volume) {
    25892679                _midi_volume_last[chan] = volume;
    2590                 MIDI_OUT(_mo, volume<<16 | 7<<8 | 0xB0 | chan);
     2680                _midi_driver.MidiOut(_midi_driver._mo, volume<<16 | 7<<8 | 0xB0 | chan);
    25912681        }
    25922682}
    25932683void SoundEngine::midiPedal(byte chan, bool pedal) {
    25942684        if (_midi_pedal_last[chan] != pedal) {
    25952685                _midi_pedal_last[chan] = pedal;
    2596                 MIDI_OUT(_mo, pedal<<16 | 64<<8 | 0xB0 | chan);
     2686                _midi_driver.MidiOut(_midi_driver._mo, pedal<<16 | 64<<8 | 0xB0 | chan);
    25972687        }
    25982688}
    25992689
    26002690void SoundEngine::midiModWheel(byte chan, byte modwheel) {
    26012691        if (_midi_modwheel_last[chan] != modwheel) {
    26022692                _midi_modwheel_last[chan] = modwheel;
    2603                 MIDI_OUT(_mo, modwheel<<16 | 1<<8 | 0xB0 | chan);
     2693                _midi_driver.MidiOut(_midi_driver._mo, modwheel<<16 | 1<<8 | 0xB0 | chan);
    26042694        }
    26052695}
    26062696
    26072697void SoundEngine::midiEffectLevel(byte chan, byte level) {
    26082698        if (_midi_effectlevel_last[chan] != level) {
    26092699                _midi_effectlevel_last[chan] = level;
    2610                 MIDI_OUT(_mo, level<<16 | 91<<8 | 0xB0 | chan);
     2700                _midi_driver.MidiOut(_midi_driver._mo, level<<16 | 91<<8 | 0xB0 | chan);
    26112701        }
    26122702}
    26132703
    26142704void SoundEngine::midiChorus(byte chan, byte chorus) {
    26152705        if (_midi_chorus_last[chan] != chorus) {
    26162706                _midi_chorus_last[chan] = chorus;
    2617                 MIDI_OUT(_mo, chorus<<16 | 93<<8 | 0xB0 | chan);
     2707                _midi_driver.MidiOut(_midi_driver._mo, chorus<<16 | 93<<8 | 0xB0 | chan);
    26182708        }
    26192709}
    26202710
    26212711void SoundEngine::midiControl0(byte chan, byte value) {
    2622         MIDI_OUT(_mo, value<<16 | 0<<8 | 0xB0 | chan);
     2712        _midi_driver.MidiOut(_midi_driver._mo, value<<16 | 0<<8 | 0xB0 | chan);
    26232713}
    26242714
    26252715void SoundEngine::midiProgram(byte chan, byte program) {
    2626         MIDI_OUT(_mo, program<<8 | 0xC0 | chan);
     2716        _midi_driver.MidiOut(_midi_driver._mo, program<<8 | 0xC0 | chan);
    26272717}
    26282718
    26292719void SoundEngine::midiPan(byte chan, int8 pan) {
    26302720        if (_midi_pan_last[chan] != pan) {
    26312721                _midi_pan_last[chan] = pan;
    2632                 MIDI_OUT(_mo, ((pan-64)&0x7F)<<16 | 10<<8 | 0xB0 | chan);
     2722                _midi_driver.MidiOut(_midi_driver._mo, ((pan-64)&0x7F)<<16 | 10<<8 | 0xB0 | chan);
    26332723        }
    26342724}
    26352725
    26362726void SoundEngine::midiNoteOn(byte chan, byte note, byte velocity) {
    2637         MIDI_OUT(_mo, velocity<<16 | note<<8 | 0x90 | chan);   
     2727        _midi_driver.MidiOut(_midi_driver._mo, velocity<<16 | note<<8 | 0x90 | chan);   
    26382728}
    26392729
    26402730void SoundEngine::midiNoteOff(byte chan, byte note) {
    2641         MIDI_OUT(_mo, note<<8 | 0x80 | chan);   
     2731        _midi_driver.MidiOut(_midi_driver._mo, note<<8 | 0x80 | chan); 
    26422732}
    26432733
    26442734void SoundEngine::midiSilence(byte chan) {
    2645         MIDI_OUT(_mo, (64<<8)|0xB0|chan);
    2646         MIDI_OUT(_mo, (123<<8)|0xB0|chan);
     2735        _midi_driver.MidiOut(_midi_driver._mo, (64<<8)|0xB0|chan);
     2736        _midi_driver.MidiOut(_midi_driver._mo, (123<<8)|0xB0|chan);
    26472737}
  • readme.txt

    diff -u scummvm.orig/readme.txt scummvm.new/readme.txt
    old new  
    4242Ctrl-s shows memory consumption.
    4343
    4444
    45 Playing sound with Timidity:
     45Playing music in Unix with a sound card
     46---------------------------------------
     47*Compile ScummVM as per the instructions above
     48*Start ScummVM as follows:
     49
     50$ scummvm -sX
     51where X is the device number of your midi output (On most cards, 0 is the external midi device and 1 is the internal midi synth. Be warned, very few cards apart from Soundblaster Live and Soundblaster AWE cards actually have an internal synth that works in linux)
     52
     53
     54Playing music in Unix with Timidity:
    4655----------------------------
    47 Start Timidity with the following command line :
     56*Compile ScummVM as per the instructions above
     57*Make sure you have timidity set up with a set of sounds (see the timidity docs for this)
     58*Start timidity with the following command line:
    4859
    4960$ timidity -irv 7777
     61If you get errors about invalid interfaces, make sure you have compiled timidity with the configure option "--enable-server"
    5062
    51 Then just start ScummVM and you should have sound.
     63*Start ScummVM and you should have music.
    5264
    5365
    5466Good Luck,
    5567Ludvig Strigeus
    56 
    57 
    58 
    59 
    60 
    61 
    62 
    63 
    64 
    65 
    66 
  • scumm.h

    diff -u scummvm.orig/scumm.h scummvm.new/scumm.h
    old new  
    357357        RF_USAGE_MAX = RF_USAGE
    358358};
    359359
     360enum {
     361        MIDI_NULL = 0,
     362        MIDI_WINDOWS = 1,
     363        MIDI_TIMIDITY = 2,
     364        MIDI_SEQ = 3,
     365};
     366
    360367#define _maxRooms res.num[rtRoom]
    361368#define _maxScripts res.num[rtScript]
    362369#define _maxCostumes res.num[rtCostume]
     
    686693
    687694        int _keyPressed;
    688695
     696        int _midi_driver;
     697        int _midi_seq_device;
    689698        void *_soundDriver;
    690699
    691700        uint16 *_inventory;
  • scummvm.cpp

    diff -u scummvm.orig/scummvm.cpp scummvm.new/scummvm.cpp
    old new  
    382382                        s++;
    383383                        while (*s) {
    384384                                switch(tolower(*s)) {
     385                                #ifndef WIN32
     386                                case 't':
     387                                        _midi_driver = MIDI_TIMIDITY;
     388                                        goto NextArg;
     389                                case 's':
     390                                        _midi_driver = MIDI_SEQ;
     391                                        _midi_seq_device = atoi(s+1);
     392                                        goto NextArg;
     393                                #endif
    385394                                case 'b':
    386395                                        _bootParam = atoi(s+1);
    387396                                        goto NextArg;
     
    396405                                                "\tscummvm [-b<num>] game\n"
    397406                                                "Flags:\n"
    398407                                                "\tb<num> - start in that room\n"
     408                                                #ifndef WIN32
     409                                                "\tt - use timidity for music output\n"
     410                                                "\ts<num> - use a midi sequencer device <num> for music output\n"
     411                                                #endif
    399412                                                "\tf - fullscreen mode\n");
    400413                                        exit(1);
    401414                                }
  • sdl.cpp

    diff -u scummvm.orig/sdl.cpp scummvm.new/sdl.cpp
    old new  
    565565
    566566        scumm._gui = &gui;
    567567        scumm.scummMain(argc, argv);
    568 
     568       
     569        if (scumm._midi_driver == MIDI_SEQ)
     570                sound.midiSetDriver(scumm._midi_driver, scumm._midi_seq_device);
     571        else
     572                sound.midiSetDriver(scumm._midi_driver);
     573               
    569574        gui.init(&scumm);
    570575
    571576        last_time = SDL_GetTicks();
  • sound.h

    diff -u scummvm.orig/sound.h scummvm.new/sound.h
    old new  
    3030struct HookDatas;
    3131struct SoundEngine;
    3232
     33struct MidiDriver {
     34        bool MidiInitialized;
     35        int DeviceType;
     36        int SeqDevice;
     37        void *_mo; /* midi out */
     38       
     39        void midiInit();
     40        void midiInitTimidity();
     41        void midiInitSeq();
     42        void midiInitWindows();
     43        void midiInitNull();
     44       
     45        void MidiOut(void *a, int b);
     46        void MidiOutSeq(void *a, int b);
     47        void MidiOutWindows(void *a, int b);
     48       
     49        int connect_to_timidity(int port);
     50        int open_sequencer_device();
     51};
     52
    3353struct Part {
    3454        SoundEngine *_se;
    3555        Part *_next, *_prev;
     
    236256};
    237257
    238258struct SoundEngine {
    239         void *_mo; /* midi out */
    240 
    241259        byte **_base_sounds;
    242260
    243261        Scumm *_s;
     
    268286        uint16 _channel_volume_eff[8]; /* NoSave */
    269287        uint16 _volchan_table[8];
    270288       
     289        MidiDriver _midi_driver;
    271290        Player _players[8];
    272291        SustainingNotes _sustaining_notes[24];
    273292        VolumeFader _volume_fader[8];
     
    341360        void midiNoteOn(byte chan, byte note, byte velocity);
    342361        void midiNoteOff(byte chan, byte note);
    343362        void midiSilence(byte chan);
    344         void midiInit();
    345363
     364        void midiSetDriver(int devicetype);
     365        void midiSetDriver(int devicetype, int seq_device);
     366       
    346367        void adjust_priorities();
    347368
    348369        void fix_parts_after_load();