Skip to content

Commit ad5b5f3

Browse files
committed
Add 'stretch' program; make Visual Studio files usable.
The 'stretch' program allows for stretching/shrinking of spaces between bars (measures) in tracks (without affecting tempo), as well as for stretching/shrinking the duration (tempo) of the tracks themselves. Also, added a Visual Studio solution containing the project file for the midifile library as well as several projects for client programs (including 'stretch'). More project files for programs can be added later.
1 parent 2e09678 commit ad5b5f3

File tree

9 files changed

+477
-24
lines changed

9 files changed

+477
-24
lines changed

include/MidiMessage.h

+1
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class MidiMessage : public vector<uchar> {
125125
int getMetaType (void) const;
126126
int isTempo (void) const;
127127
void setTempo (double tempo);
128+
void setTempoMicroseconds (int microseconds);
128129
void setMetaTempo (double tempo);
129130
int isEndOfTrack (void) const;
130131

src-library/MidiMessage.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,10 @@ void MidiMessage::getSpelling(int& base7, int& accidental) {
11631163
void MidiMessage::setMetaTempo(double tempo) {
11641164
int microseconds = (int)(60.0 / tempo * 1000000.0 + 0.5);
11651165
resize(6);
1166+
setTempoMicroseconds( microseconds );
1167+
}
1168+
1169+
void MidiMessage::setTempoMicroseconds( int microseconds ) {
11661170
(*this)[0] = 0xff;
11671171
(*this)[1] = 0x51;
11681172
(*this)[2] = 3;

src-programs/stretch.cpp

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//
2+
// Programmer: Ziemowit Laski <zlaski@ziemas.net>
3+
// Creation Date: Sun, Jun 12, 2016 11:09:34 AM
4+
// Last Modified: Sun, Jun 12, 2016 11:09:34 AM
5+
// Filename: stretch.cpp
6+
// Syntax: C++
7+
//
8+
// Description: Stretches (or shrinks):
9+
// 1. The position of bars (measures) in tracks,
10+
// without affecting tempo, and/or
11+
// 2. The tempo (BPM) itself.
12+
//
13+
// This is useful when working with MIDI files
14+
// that were automatically generated from audio
15+
// (MP3, WAV) files. Conversion software often
16+
// has difficulty in correct placement of
17+
// bars, and also sometimes does not preserve
18+
// the tempo of the original.
19+
//
20+
#include "MidiFile.h"
21+
#include "Options.h"
22+
#include <iostream>
23+
#include <cmath>
24+
#include <algorithm>
25+
26+
using namespace std;
27+
28+
void doStretch (MidiFile& midifile, double bars, double duration);
29+
30+
int main(int argc, char** argv) {
31+
Options options;
32+
options.define("b|bars|m|measures=d:1.0",
33+
"Stretch width of bars (measures) by factor specified (WITHOUT affecting tempo)");
34+
options.define("d|duration|t|tempo=d:1.0",
35+
"Stretch duration of track(s) by factor specified");
36+
options.process(argc, argv);
37+
if (options.getArgCount() != 2) {
38+
cerr << "two MIDI filenames are required.\n";
39+
exit(1);
40+
}
41+
42+
MidiFile midifile;
43+
midifile.read(options.getArg(1));
44+
if (!midifile.status()) {
45+
cerr << "Error reading MIDI file " << options.getArg(1) << endl;
46+
exit(1);
47+
}
48+
49+
if (options.getBoolean("bars") || options.getBoolean("duration")) {
50+
double bars = options.getDouble("bars");
51+
double duration = options.getDouble("duration");
52+
if (bars < 0.1 || bars > 10.0 || duration < 0.1 || duration > 10.0) {
53+
cerr << "stretch parameters must be between 0.1 and 10.\n";
54+
exit(1);
55+
}
56+
doStretch(midifile, bars, duration);
57+
}
58+
59+
midifile.write(options.getArg(2));
60+
return 0;
61+
}
62+
63+
64+
//////////////////////////////
65+
//
66+
// doStretch -- Stretch size of all bars (measures) in the file
67+
// by a specified 'bars' factor. (Values lower than 1.0 will result
68+
// in shrinking). Note that bars (measures) are not encoded in MIDI
69+
// directly as an event type. Instead, they are computed from the
70+
// Pulse Per Quarter Note (PPQN) value in the file header; PPQN
71+
// multiplied by the number of quarter notes in a measure (as
72+
// determined by the time signature contained in the FF 58
73+
// message) gives the number of ticks in each measure. The
74+
// 'duration' parameter specifies the factor by which the
75+
// duration of the track(s) should be stretched (or shrunk,
76+
// if less than 1.0).
77+
78+
void doStretch(MidiFile& midifile, double bars, double duration) {
79+
int ppqn = midifile.getTicksPerQuarterNote();
80+
int new_ppqn = max( 24576, ppqn );
81+
midifile.setTicksPerQuarterNote( new_ppqn );
82+
double tick_mult = (double)new_ppqn / (double)ppqn;
83+
tick_mult /= bars;
84+
85+
for (int t = 0; t < midifile.size(); ++t) {
86+
MidiEventList &track = midifile[t];
87+
for (int e = 0; e < track.size(); ++e) {
88+
MidiEvent &event = track[e];
89+
event.tick *= tick_mult;
90+
if (event.getMetaType() == 0x51) {
91+
int tempo = event.getTempoMicroseconds();
92+
tempo *= bars;
93+
tempo *= duration;
94+
event.setTempoMicroseconds( tempo );
95+
}
96+
}
97+
}
98+
}

visual-studio/README.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
Compiling for Visual Studio
22
============================
33

4-
See the commentary on compiling for Visual Studio 2010 in midifile issue #10:
5-
https://github.com/craigsapp/midifile/issues/10
6-
7-
The file [midifile.vcxproj](midifile.vcxproj) created by
8-
[kirbyfan64](https://github.com/kirbyfan64) can be
9-
used to compile the static library for the midifile library.
10-
Run `set PLATFORM=` and `msbuild`.
11-
12-
How to add a static library to a Visual Studio project:
13-
http://stackoverflow.com/questions/10049640/linking-a-static-library-to-my-project-on-visual-studio-2010
4+
The solution file (midifile.sln) contains the project for the static
5+
library in /src-library (midifile.vcxproj) as well as projects for
6+
individual projects for client programs in /src-programs.
147

8+
The projects are configured for the v140 (Visual Studio 2015) toolset
9+
by default, but this can be changed.
1510

11+
As new programs are added to /src-programs, corresponding project
12+
files should be created for them in this directory, and then added
13+
to midifile.sln. The easiest was of creating a new project file
14+
is to copy an existing project file and then rename all occurrences
15+
of the old name with the new one.
1616

visual-studio/binasc.vcxproj

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup Label="ProjectConfigurations">
4+
<ProjectConfiguration Include="Debug|Win32">
5+
<Configuration>Debug</Configuration>
6+
<Platform>Win32</Platform>
7+
</ProjectConfiguration>
8+
<ProjectConfiguration Include="Release|Win32">
9+
<Configuration>Release</Configuration>
10+
<Platform>Win32</Platform>
11+
</ProjectConfiguration>
12+
</ItemGroup>
13+
<ItemGroup>
14+
<ProjectReference Include="midifile.vcxproj">
15+
<Project>{70028d4b-8e0d-4ff2-bd05-d7ab19b66f30}</Project>
16+
</ProjectReference>
17+
</ItemGroup>
18+
<ItemGroup>
19+
<ClCompile Include="..\src-programs\binasc.cpp" />
20+
</ItemGroup>
21+
<PropertyGroup Label="Globals">
22+
<ProjectGuid>{5230AA11-C456-48E6-B19F-23703EC38D80}</ProjectGuid>
23+
<Keyword>Win32Proj</Keyword>
24+
</PropertyGroup>
25+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
26+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
27+
<ConfigurationType>Application</ConfigurationType>
28+
<UseDebugLibraries>true</UseDebugLibraries>
29+
<PlatformToolset>v140</PlatformToolset>
30+
</PropertyGroup>
31+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
32+
<ConfigurationType>Application</ConfigurationType>
33+
<UseDebugLibraries>false</UseDebugLibraries>
34+
<PlatformToolset>v140</PlatformToolset>
35+
<WholeProgramOptimization>true</WholeProgramOptimization>
36+
</PropertyGroup>
37+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
38+
<ImportGroup Label="ExtensionSettings">
39+
</ImportGroup>
40+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
41+
<PropertyGroup Label="UserMacros" />
42+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
43+
<LinkIncremental>true</LinkIncremental>
44+
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../include</IncludePath>
45+
<IntDir>$(Configuration)Exe\</IntDir>
46+
<OutDir>$(SolutionDir)$(Configuration)Exe\</OutDir>
47+
</PropertyGroup>
48+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
49+
<LinkIncremental>false</LinkIncremental>
50+
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../include</IncludePath>
51+
<IntDir>$(Configuration)Exe\</IntDir>
52+
<OutDir>$(SolutionDir)$(Configuration)Exe\</OutDir>
53+
</PropertyGroup>
54+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
55+
<ClCompile>
56+
<PrecompiledHeader>
57+
</PrecompiledHeader>
58+
<WarningLevel>Level3</WarningLevel>
59+
<Optimization>Disabled</Optimization>
60+
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
61+
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
62+
</ClCompile>
63+
<Link>
64+
<SubSystem>Console</SubSystem>
65+
<GenerateDebugInformation>true</GenerateDebugInformation>
66+
</Link>
67+
</ItemDefinitionGroup>
68+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
69+
<ClCompile>
70+
<WarningLevel>Level3</WarningLevel>
71+
<PrecompiledHeader>
72+
</PrecompiledHeader>
73+
<Optimization>MaxSpeed</Optimization>
74+
<FunctionLevelLinking>true</FunctionLevelLinking>
75+
<IntrinsicFunctions>true</IntrinsicFunctions>
76+
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
77+
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
78+
</ClCompile>
79+
<Link>
80+
<SubSystem>Console</SubSystem>
81+
<GenerateDebugInformation>true</GenerateDebugInformation>
82+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
83+
<OptimizeReferences>true</OptimizeReferences>
84+
</Link>
85+
</ItemDefinitionGroup>
86+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
87+
<ImportGroup Label="ExtensionTargets">
88+
</ImportGroup>
89+
</Project>

visual-studio/createmidifile.vcxproj

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup Label="ProjectConfigurations">
4+
<ProjectConfiguration Include="Debug|Win32">
5+
<Configuration>Debug</Configuration>
6+
<Platform>Win32</Platform>
7+
</ProjectConfiguration>
8+
<ProjectConfiguration Include="Release|Win32">
9+
<Configuration>Release</Configuration>
10+
<Platform>Win32</Platform>
11+
</ProjectConfiguration>
12+
</ItemGroup>
13+
<ItemGroup>
14+
<ProjectReference Include="midifile.vcxproj">
15+
<Project>{70028d4b-8e0d-4ff2-bd05-d7ab19b66f30}</Project>
16+
</ProjectReference>
17+
</ItemGroup>
18+
<ItemGroup>
19+
<ClCompile Include="..\src-programs\createmidifile.cpp" />
20+
</ItemGroup>
21+
<PropertyGroup Label="Globals">
22+
<ProjectGuid>{52724792-CD79-4152-984C-DFD7DA570855}</ProjectGuid>
23+
<Keyword>Win32Proj</Keyword>
24+
</PropertyGroup>
25+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
26+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
27+
<ConfigurationType>Application</ConfigurationType>
28+
<UseDebugLibraries>true</UseDebugLibraries>
29+
<PlatformToolset>v140</PlatformToolset>
30+
</PropertyGroup>
31+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
32+
<ConfigurationType>Application</ConfigurationType>
33+
<UseDebugLibraries>false</UseDebugLibraries>
34+
<PlatformToolset>v140</PlatformToolset>
35+
<WholeProgramOptimization>true</WholeProgramOptimization>
36+
</PropertyGroup>
37+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
38+
<ImportGroup Label="ExtensionSettings">
39+
</ImportGroup>
40+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
41+
<PropertyGroup Label="UserMacros" />
42+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
43+
<LinkIncremental>true</LinkIncremental>
44+
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../include</IncludePath>
45+
<IntDir>$(Configuration)Exe\</IntDir>
46+
<OutDir>$(SolutionDir)$(Configuration)Exe\</OutDir>
47+
</PropertyGroup>
48+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
49+
<LinkIncremental>false</LinkIncremental>
50+
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../include</IncludePath>
51+
<IntDir>$(Configuration)Exe\</IntDir>
52+
<OutDir>$(SolutionDir)$(Configuration)Exe\</OutDir>
53+
</PropertyGroup>
54+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
55+
<ClCompile>
56+
<PrecompiledHeader>
57+
</PrecompiledHeader>
58+
<WarningLevel>Level3</WarningLevel>
59+
<Optimization>Disabled</Optimization>
60+
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
61+
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
62+
</ClCompile>
63+
<Link>
64+
<SubSystem>Console</SubSystem>
65+
<GenerateDebugInformation>true</GenerateDebugInformation>
66+
</Link>
67+
</ItemDefinitionGroup>
68+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
69+
<ClCompile>
70+
<WarningLevel>Level3</WarningLevel>
71+
<PrecompiledHeader>
72+
</PrecompiledHeader>
73+
<Optimization>MaxSpeed</Optimization>
74+
<FunctionLevelLinking>true</FunctionLevelLinking>
75+
<IntrinsicFunctions>true</IntrinsicFunctions>
76+
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
77+
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
78+
</ClCompile>
79+
<Link>
80+
<SubSystem>Console</SubSystem>
81+
<GenerateDebugInformation>true</GenerateDebugInformation>
82+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
83+
<OptimizeReferences>true</OptimizeReferences>
84+
</Link>
85+
</ItemDefinitionGroup>
86+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
87+
<ImportGroup Label="ExtensionTargets">
88+
</ImportGroup>
89+
</Project>

visual-studio/midifile.sln

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.25123.0
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "midifile", "midifile.vcxproj", "{70028D4B-8E0D-4FF2-BD05-D7AB19B66F30}"
7+
EndProject
8+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stretch", "stretch.vcxproj", "{1CD9D03A-63D6-46BA-80E2-93AAECD2754B}"
9+
EndProject
10+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "binasc", "binasc.vcxproj", "{5230AA11-C456-48E6-B19F-23703EC38D80}"
11+
EndProject
12+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "createmidifile", "createmidifile.vcxproj", "{52724792-CD79-4152-984C-DFD7DA570855}"
13+
EndProject

0 commit comments

Comments
 (0)