Thread: Playing a Midi. (win32 console) (MSVC++)

  1. #1
    0x01
    Join Date
    Sep 2001
    Posts
    88

    Playing a Midi. (win32 console) (MSVC++)

    Anyone know how to play a Midi or know where I can find a Midi class or..... anything similiar?

    To play a ".wav" file, its PlaySound() with the header "mmsystem.h" and winmm.lib linked.

    However; I want to play a Midi and NOT a wav file....

    Compiler: MSVC++ OS: Windows XP

  2. #2
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    look up midi functions at msdn esp. midiOutOpen()
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  3. #3
    Cat
    Guest
    Here's an old .cpp file I wrote, which creates a window (invisible) that does MIDI playing. You can probably take excerpts from it. The purpose of the separate window was to have a separate message queue dedicated to MIDI messages only; you can easily put this in any class you like, and simply intercept the relevant messages. I think you only need to handle the MM_MCINOTIFY message.

    It was written for Borland C++, so the window objects are OWL, not MFC, but you could easily port this, I'm sure.

    .h file:

    Code:
    #ifndef _MIDIWIN_H
    #define _MIDIWIN_H
    
    #include <windows.h>
    #include <owl\window.h>
    
    #include <mmsystem.h>
    
    class MidiWindow : public TWindow{
    public:
       MidiWindow(TWindow*,const char *);
       ~MidiWindow();
       int Play(const char *,bool loop = false);
       //void WaitPlay(const char *, bool loop = false);
       void Stop();
       bool IsPlaying();
    
       void EvSetFocus(THandle);
    
       LRESULT MciNotify(WPARAM, LPARAM);
       DECLARE_RESPONSE_TABLE(MidiWindow);
    private:
       void PlayAgain(bool loop = true);
       bool isOpen;
       bool repeat;
       MCI_OPEN_PARMS	midiParams;
    } *MIDI;
    
    #endif

    .cpp file:
    Code:
    #include "midiwin.h"
    
    DEFINE_RESPONSE_TABLE1(MidiWindow,TWindow)
         EV_MESSAGE(MM_MCINOTIFY, MciNotify),
         EV_WM_SETFOCUS,
    END_RESPONSE_TABLE;
    
    MidiWindow::MidiWindow(TWindow * twp, const char * ccp) : TWindow(twp,ccp){
       isOpen = false;
    }
    
    MidiWindow::~MidiWindow(){
       Stop();
    }
    
    LRESULT MidiWindow::MciNotify(WPARAM, LPARAM){          // this is called whenever a MIDI stops.
       if (IsPlaying()) return 0;  // If we've started playing between message generation and message processing, quit.
       if (repeat) PlayAgain();
       return 0;
    }
    
    int MidiWindow::Play(const char * file, bool rep){
       // Stop/close the device
       Stop();
       // Set parameters for playback
       midiParams.dwCallback = (unsigned long)HWindow;
       midiParams.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_SEQUENCER;
       midiParams.lpstrElementName = file;
       //Open the device
       if ((mciSendCommand(0, MCI_OPEN, MCI_WAIT|MCI_OPEN_ELEMENT|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, (DWORD)(LPVOID)&midiParams))){
          return 1;
       }
       isOpen = true;
       //Start the MIDI, set the notify flag to tell us when we stop.
       if ((mciSendCommand(midiParams.wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID)&midiParams))){
          Stop();
          return 1;
       }
       //Set repeat flag
       repeat = rep;
       return 0;
    }
    
    void MidiWindow::Stop(){   // Stops playback + closes device
       repeat = false;
       if (isOpen) mciSendCommand(midiParams.wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)(LPVOID)&midiParams);
       isOpen = false;
    }
    
    void MidiWindow::PlayAgain(bool rep){
       // Stop/close the device
       Stop();
       // Open the device
       if ((mciSendCommand(0, MCI_OPEN, MCI_WAIT|MCI_OPEN_ELEMENT|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, (DWORD)(LPVOID)&midiParams))){
          return;
       }
       isOpen = true;
       // Play the MIDI
       if ((mciSendCommand(midiParams.wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID)&midiParams))){
          Stop();
          return;
       }
       // Set repeat flag
       repeat = rep;
    }
    
    
    void MidiWindow::EvSetFocus(THandle){     // Make sure we DON'T receive the focus, because we don't want it.
       Parent->SetFocus();
    }
    
    bool MidiWindow::IsPlaying(){
       if (!isOpen) return false;  // if we don't have a MIDI device open, we can't be playing
       // Set up structures to query device
       DWORD flags = MCI_WAIT | MCI_STATUS_ITEM;
       MCI_STATUS_PARMS statusParms;
       statusParms.dwItem = MCI_STATUS_MODE;
       // Ask the device what it's doing
       mciSendCommand(midiParams.wDeviceID, MCI_STATUS, flags, (DWORD)(LPVOID) &statusParms);
       return (statusParms.dwReturn == MCI_MODE_PLAY);
    }

  4. #4
    Cat
    Guest
    As a side note, much of this code is irrelevant if you don't care when the MIDI stops. In this case, I wanted a MIDI that could loop forever, so I told the system to notify me when it stopped, and then I would restart it immediately. The notification message (which is sent when the MIDI ends) doesn't have to be sent unless you want it to be.

    For simply playing a MIDI once, just look at the Play() function; the 2 mciSendCommand() calls are the important ones.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Adding a console window to a Win32 app
    By VirtualAce in forum Game Programming
    Replies: 7
    Last Post: 02-01-2009, 01:09 PM
  2. What you do while playing console
    By glo in forum A Brief History of Cprogramming.com
    Replies: 30
    Last Post: 10-30-2007, 05:14 PM
  3. Win32 Console - Simple graphical problem
    By INFERNO2K in forum C++ Programming
    Replies: 0
    Last Post: 12-09-2005, 09:34 AM
  4. Playing Flash files(swf) in Win32 window
    By maxorator in forum Windows Programming
    Replies: 16
    Last Post: 11-29-2005, 11:00 PM