初始化内容
This commit is contained in:
Vendored
+112
@@ -0,0 +1,112 @@
|
||||
//
|
||||
// Programmer: Ziemowit Laski <zlaski@ziemas.net>
|
||||
// Creation Date: Sun, Jun 12, 2016 11:09:34 AM
|
||||
// Last Modified: Sun, Jun 12, 2016 11:09:34 AM
|
||||
// Filename: tools/stretch.cpp
|
||||
// URL: https://github.com/craigsapp/midifile/blob/master/tools/stretch.cpp
|
||||
// Syntax: C++11
|
||||
// vim: ts=3
|
||||
//
|
||||
// Description: Stretches (or shrinks):
|
||||
// 1. The position of bars (measures) in tracks,
|
||||
// without affecting tempo, and/or
|
||||
// 2. The tempo (BPM) itself.
|
||||
//
|
||||
// This is useful when working with MIDI files
|
||||
// that were automatically generated from audio
|
||||
// (MP3, WAV) files. Conversion software often
|
||||
// has difficulty in correct placement of
|
||||
// bars, and also sometimes does not preserve
|
||||
// the tempo of the original.
|
||||
//
|
||||
|
||||
#include "MidiFile.h"
|
||||
#include "Options.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace smf;
|
||||
|
||||
|
||||
void doStretch (MidiFile& midifile, double bars, double duration);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Options options;
|
||||
options.define("b|bars|m|measures=d:1.0",
|
||||
"Stretch width of bars (measures) by factor specified (WITHOUT affecting tempo)");
|
||||
options.define("d|duration|t|tempo=d:1.0",
|
||||
"Stretch duration of track(s) by factor specified");
|
||||
options.process(argc, argv);
|
||||
if (options.getArgCount() != 2) {
|
||||
cerr << "two MIDI filenames are required.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
MidiFile midifile;
|
||||
midifile.read(options.getArg(1));
|
||||
if (!midifile.status()) {
|
||||
cerr << "Error reading MIDI file " << options.getArg(1) << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (options.getBoolean("bars") || options.getBoolean("duration")) {
|
||||
double bars = options.getDouble("bars");
|
||||
double duration = options.getDouble("duration");
|
||||
if (bars < 0.1 || bars > 10.0 || duration < 0.1 || duration > 10.0) {
|
||||
cerr << "stretch parameters must be between 0.1 and 10.\n";
|
||||
exit(1);
|
||||
}
|
||||
doStretch(midifile, bars, duration);
|
||||
}
|
||||
|
||||
midifile.write(options.getArg(2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////
|
||||
//
|
||||
// doStretch -- Stretch size of all bars (measures) in the file
|
||||
// by a specified 'bars' factor. (Values lower than 1.0 will result
|
||||
// in shrinking). Note that bars (measures) are not encoded in MIDI
|
||||
// directly as an event type. Instead, they are computed from the
|
||||
// Pulse Per Quarter Note (PPQN) value in the file header; PPQN
|
||||
// multiplied by the number of quarter notes in a measure (as
|
||||
// determined by the time signature contained in the FF 58
|
||||
// message) gives the number of ticks in each measure. The
|
||||
// 'duration' parameter specifies the factor by which the
|
||||
// duration of the track(s) should be stretched (or shrunk,
|
||||
// if less than 1.0).
|
||||
|
||||
void doStretch(MidiFile& midifile, double bars, double duration) {
|
||||
int ppqn = midifile.getTicksPerQuarterNote();
|
||||
int new_ppqn = max( 24576, ppqn );
|
||||
midifile.setTicksPerQuarterNote( new_ppqn );
|
||||
double tick_mult = (double)new_ppqn / (double)ppqn;
|
||||
tick_mult /= bars;
|
||||
|
||||
for (int t = 0; t < midifile.size(); ++t) {
|
||||
MidiEventList &track = midifile[t];
|
||||
for (int e = 0; e < track.size(); ++e) {
|
||||
MidiEvent &event = track[e];
|
||||
event.tick *= (int)(event.tick * tick_mult);
|
||||
if (event.getMetaType() == 0x51) {
|
||||
double tempo = event.getTempoMicroseconds();
|
||||
tempo *= bars;
|
||||
tempo *= duration;
|
||||
event.setTempoMicroseconds( (int)tempo );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user