Chris@301: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
Chris@301: 
Chris@301: /*
Chris@301:     Sonic Visualiser
Chris@301:     An audio file viewer and annotation editor.
Chris@301:     Centre for Digital Music, Queen Mary, University of London.
Chris@301:     
Chris@301:     This program is free software; you can redistribute it and/or
Chris@301:     modify it under the terms of the GNU General Public License as
Chris@301:     published by the Free Software Foundation; either version 2 of the
Chris@301:     License, or (at your option) any later version.  See the file
Chris@301:     COPYING included with this distribution for more information.
Chris@301: */
Chris@301: 
Chris@301: 
Chris@301: /*
Chris@301:    This is a modified version of a source file from the 
Chris@301:    Rosegarden MIDI and audio sequencer and notation editor.
Chris@301:    This file copyright 2000-2007 Richard Bown and Chris Cannam
Chris@301:    and copyright 2007 QMUL.
Chris@301: */
Chris@301: 
Chris@301: #ifndef _MIDI_FILE_WRITER_H_
Chris@301: #define _MIDI_FILE_WRITER_H_
Chris@301: 
Chris@301: #include "base/RealTime.h"
Chris@301: 
Chris@301: #include <QString>
Chris@301: 
Chris@301: #include <vector>
Chris@301: #include <map>
Chris@301: #include <fstream>
Chris@301: 
Chris@301: class MIDIEvent;
Chris@301: class NoteModel;
Chris@301: 
Chris@301: /**
Chris@301:  * Write a MIDI file.  This includes file write code for generic
Chris@301:  * simultaneous-track MIDI files, but the conversion stage only
Chris@301:  * supports a single-track MIDI file with fixed tempo, time signature
Chris@301:  * and timing division.
Chris@301:  */
Chris@301: class MIDIFileWriter 
Chris@301: {
Chris@301: public:
Chris@301:     MIDIFileWriter(QString path, NoteModel *model, float tempo = 120.f);
Chris@301:     virtual ~MIDIFileWriter();
Chris@301: 
Chris@301:     virtual bool isOK() const;
Chris@301:     virtual QString getError() const;
Chris@301: 
Chris@301:     virtual void write();
Chris@301: 
Chris@301: protected:
Chris@301:     typedef std::vector<MIDIEvent *> MIDITrack;
Chris@301:     typedef std::map<unsigned int, MIDITrack> MIDIComposition;
Chris@301: 
Chris@301:     typedef enum {
Chris@301: 	MIDI_SINGLE_TRACK_FILE          = 0x00,
Chris@301: 	MIDI_SIMULTANEOUS_TRACK_FILE    = 0x01,
Chris@301: 	MIDI_SEQUENTIAL_TRACK_FILE      = 0x02,
Chris@301: 	MIDI_FILE_BAD_FORMAT            = 0xFF
Chris@301:     } MIDIFileFormatType;
Chris@301: 
Chris@301:     std::string intToMIDIBytes(int number) const;
Chris@301:     std::string longToMIDIBytes(unsigned long number) const;
Chris@301:     std::string longToVarBuffer(unsigned long number) const;
Chris@301: 
Chris@301:     unsigned long getMIDITimeForTime(RealTime t) const;
Chris@301: 
Chris@301:     bool writeHeader();
Chris@301:     bool writeTrack(int track);
Chris@301:     bool writeComposition();
Chris@301:     
Chris@301:     bool convert();
Chris@301: 
Chris@301:     QString             m_path;
Chris@301:     NoteModel          *m_model;
Chris@301:     bool                m_modelUsesHz;
Chris@301:     float               m_tempo;
Chris@301:     int                 m_timingDivision;   // pulses per quarter note
Chris@301:     MIDIFileFormatType  m_format;
Chris@301:     unsigned int        m_numberOfTracks;
Chris@301: 
Chris@301:     MIDIComposition     m_midiComposition;
Chris@301: 
Chris@301:     std::ofstream      *m_midiFile;
Chris@301:     QString             m_error;
Chris@301: };
Chris@301: 
Chris@301: #endif