Skip to content

Commit

Permalink
Merge pull request craigsapp#24 from zlaski/master
Browse files Browse the repository at this point in the history
Add 'stretch' program; make Visual Studio files usable.
  • Loading branch information
craigsapp authored Oct 20, 2016
2 parents 695eb09 + ad5b5f3 commit 9f494a4
Show file tree
Hide file tree
Showing 9 changed files with 477 additions and 24 deletions.
1 change: 1 addition & 0 deletions include/MidiMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class MidiMessage : public vector<uchar> {
int getMetaType (void) const;
int isTempo (void) const;
void setTempo (double tempo);
void setTempoMicroseconds (int microseconds);
void setMetaTempo (double tempo);
int isEndOfTrack (void) const;

Expand Down
4 changes: 4 additions & 0 deletions src-library/MidiMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,10 @@ void MidiMessage::getSpelling(int& base7, int& accidental) {
void MidiMessage::setMetaTempo(double tempo) {
int microseconds = (int)(60.0 / tempo * 1000000.0 + 0.5);
resize(6);
setTempoMicroseconds( microseconds );
}

void MidiMessage::setTempoMicroseconds( int microseconds ) {
(*this)[0] = 0xff;
(*this)[1] = 0x51;
(*this)[2] = 3;
Expand Down
98 changes: 98 additions & 0 deletions src-programs/stretch.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//
// Programmer: Ziemowit Laski <[email protected]>
// Creation Date: Sun, Jun 12, 2016 11:09:34 AM
// Last Modified: Sun, Jun 12, 2016 11:09:34 AM
// Filename: stretch.cpp
// Syntax: C++
//
// 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 <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

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 *= tick_mult;
if (event.getMetaType() == 0x51) {
int tempo = event.getTempoMicroseconds();
tempo *= bars;
tempo *= duration;
event.setTempoMicroseconds( tempo );
}
}
}
}
20 changes: 10 additions & 10 deletions visual-studio/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
Compiling for Visual Studio
============================

See the commentary on compiling for Visual Studio 2010 in midifile issue #10:
https://github.com/craigsapp/midifile/issues/10

The file [midifile.vcxproj](midifile.vcxproj) created by
[kirbyfan64](https://github.com/kirbyfan64) can be
used to compile the static library for the midifile library.
Run `set PLATFORM=` and `msbuild`.

How to add a static library to a Visual Studio project:
http://stackoverflow.com/questions/10049640/linking-a-static-library-to-my-project-on-visual-studio-2010
The solution file (midifile.sln) contains the project for the static
library in /src-library (midifile.vcxproj) as well as projects for
individual projects for client programs in /src-programs.

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

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

89 changes: 89 additions & 0 deletions visual-studio/binasc.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="midifile.vcxproj">
<Project>{70028d4b-8e0d-4ff2-bd05-d7ab19b66f30}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src-programs\binasc.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{5230AA11-C456-48E6-B19F-23703EC38D80}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../include</IncludePath>
<IntDir>$(Configuration)Exe\</IntDir>
<OutDir>$(SolutionDir)$(Configuration)Exe\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../include</IncludePath>
<IntDir>$(Configuration)Exe\</IntDir>
<OutDir>$(SolutionDir)$(Configuration)Exe\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
89 changes: 89 additions & 0 deletions visual-studio/createmidifile.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="midifile.vcxproj">
<Project>{70028d4b-8e0d-4ff2-bd05-d7ab19b66f30}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src-programs\createmidifile.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{52724792-CD79-4152-984C-DFD7DA570855}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../include</IncludePath>
<IntDir>$(Configuration)Exe\</IntDir>
<OutDir>$(SolutionDir)$(Configuration)Exe\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);../include</IncludePath>
<IntDir>$(Configuration)Exe\</IntDir>
<OutDir>$(SolutionDir)$(Configuration)Exe\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
13 changes: 13 additions & 0 deletions visual-studio/midifile.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "midifile", "midifile.vcxproj", "{70028D4B-8E0D-4FF2-BD05-D7AB19B66F30}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stretch", "stretch.vcxproj", "{1CD9D03A-63D6-46BA-80E2-93AAECD2754B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "binasc", "binasc.vcxproj", "{5230AA11-C456-48E6-B19F-23703EC38D80}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "createmidifile", "createmidifile.vcxproj", "{52724792-CD79-4152-984C-DFD7DA570855}"
EndProject
Loading

0 comments on commit 9f494a4

Please sign in to comment.