mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-10 16:43:33 +02:00
Update portsmf to SVN r227.
This commit is contained in:
137
lib-src/portsmf/apps/allegroconvert.cpp
Executable file
137
lib-src/portsmf/apps/allegroconvert.cpp
Executable file
@@ -0,0 +1,137 @@
|
||||
/* allegroconvert.cpp -- convert from allegro to standard midi files */
|
||||
|
||||
/* CHANGE LOG
|
||||
04 apr 03 -- added options to remove tempo track, retaining either
|
||||
the original beats or original timing (RBD)
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include "allegro.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
void midi_fail(char *msg)
|
||||
{
|
||||
printf("Failure: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void *midi_alloc(size_t s) { return malloc(s); }
|
||||
void midi_free(void *a) { free(a); }
|
||||
|
||||
|
||||
void print_help()
|
||||
{
|
||||
printf("%s%s%s%s%s%s%s%s",
|
||||
"Usage: allegroconvert [-m] [-a] [-t tempo] [-f] <filename>\n",
|
||||
" Use -m for midifile->allegro, -a for allegro->midifile.\n",
|
||||
" .mid extension implies -m, .gro implies -a\n",
|
||||
" If tempo (a float) is specified after -t, the tempo track\n",
|
||||
" is deleted and replaced by a fixed tempo.\n",
|
||||
" If -f (flatten) is specified, output a flat tempo=60,\n",
|
||||
" preserving the original timing of all midi events.\n",
|
||||
" Do not use both -t and -f.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
// process -- perform tempo changing and flattening operations
|
||||
//
|
||||
void process(Alg_seq_ptr seq, bool tempo_flag, double tempo,
|
||||
bool flatten_flag)
|
||||
{
|
||||
// the tempo changing operation replaces the tempo track with
|
||||
// a fixed tempo. This changes the timing of the result.
|
||||
if (tempo_flag) {
|
||||
seq->convert_to_beats(); // preserve beats
|
||||
} else if (flatten_flag) {
|
||||
seq->convert_to_seconds(); // preserve timing
|
||||
} else return;
|
||||
// the following finishes both tempo and flatten processing...
|
||||
seq->get_time_map()->beats.len = 1; // remove contents of tempo map
|
||||
seq->get_time_map()->last_tempo = tempo / 60.0; // set the new fixed tempo
|
||||
// (allegro uses beats/second so divide bpm by 60)
|
||||
seq->get_time_map()->last_tempo_flag = true;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
print_help();
|
||||
}
|
||||
char *filename = argv[argc - 1];
|
||||
char outfilename[256];
|
||||
bool midifile = false;
|
||||
bool allegrofile = false;
|
||||
bool flatten_flag = false;
|
||||
double tempo = 60.0; // default is used for -f (flatten)
|
||||
bool tempo_flag = false;
|
||||
char *ext = NULL;
|
||||
|
||||
int i = 1;
|
||||
while (i < argc - 1) {
|
||||
if (argv[i][0] != '-') print_help();
|
||||
if (argv[i][1] == 'm') midifile = true;
|
||||
else if (argv[i][1] == 'a') allegrofile = true;
|
||||
else if (argv[i][1] == 't') {
|
||||
i++;
|
||||
if (i >= argc - 1) print_help(); // expected tempo
|
||||
tempo = atof(argv[i]);
|
||||
tempo_flag = true;
|
||||
} else if (argv[i][1] == 'f') {
|
||||
flatten_flag = true;
|
||||
} else print_help();
|
||||
i++;
|
||||
}
|
||||
// Do not use both -t and -f:
|
||||
if (tempo_flag & flatten_flag) print_help();
|
||||
|
||||
int len = strlen(filename);
|
||||
if (!midifile && !allegrofile) {
|
||||
if (len < 4) print_help(); // no extension, need -m or -a
|
||||
ext = filename + len - 4;
|
||||
if (strcmp(ext, ".mid") == 0) midifile = true;
|
||||
else if (strcmp(ext, ".gro") == 0) allegrofile = true;
|
||||
else print_help();
|
||||
} else if (len > 4) {
|
||||
ext = filename + len - 4;
|
||||
}
|
||||
Alg_seq_ptr seq;
|
||||
strcpy(outfilename, filename);
|
||||
if (midifile) {
|
||||
seq = new Alg_seq(filename, true);
|
||||
process(seq, tempo_flag, tempo, flatten_flag);
|
||||
if (ext && strcmp(ext, ".mid") == 0) {
|
||||
ext = outfilename + strlen(outfilename) - 4;
|
||||
} else {
|
||||
ext = outfilename + strlen(outfilename);
|
||||
}
|
||||
strcpy(ext, ".gro");
|
||||
seq->write(outfilename);
|
||||
} else if (allegrofile) {
|
||||
seq = new Alg_seq(filename, false);
|
||||
process(seq, tempo_flag, tempo, flatten_flag);
|
||||
if (ext && strcmp(ext, ".gro") == 0) {
|
||||
ext = outfilename + strlen(outfilename) - 4;
|
||||
} else {
|
||||
ext = outfilename + strlen(outfilename);
|
||||
}
|
||||
strcpy(ext, ".mid");
|
||||
seq->smf_write(outfilename);
|
||||
}
|
||||
|
||||
int events = 0;
|
||||
for (i = 0; i < seq->track_list.length(); i++) {
|
||||
events += seq->track_list[i].length();
|
||||
}
|
||||
printf("%ld tracks, %d events\n", seq->track_list.length(), events);
|
||||
printf("wrote %s\n", outfilename);
|
||||
|
||||
/* DELETE THE DATA */
|
||||
delete seq;
|
||||
|
||||
return 0;
|
||||
}
|
197
lib-src/portsmf/apps/allegroconvert.vcproj
Normal file
197
lib-src/portsmf/apps/allegroconvert.vcproj
Normal file
@@ -0,0 +1,197 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="allegroconvert"
|
||||
ProjectGUID="{3CF9F99C-ADB3-4CD2-A6F9-2472C2083324}"
|
||||
RootNamespace="allegroconvert"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=".."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="../Debug/portsmf.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=".."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="../Release/portsmf.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\allegroconvert.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
89
lib-src/portsmf/apps/allegroplay.cpp
Executable file
89
lib-src/portsmf/apps/allegroplay.cpp
Executable file
@@ -0,0 +1,89 @@
|
||||
|
||||
//#include "stdlib.h"
|
||||
//#include "stdio.h"
|
||||
//#include "memory.h"
|
||||
//#include "assert.h"
|
||||
#include <fstream>
|
||||
#include "allegro.h"
|
||||
#include "mfmidi.h"
|
||||
#include "portmidi.h"
|
||||
#include "seq2midi.h"
|
||||
//#include "string.h"
|
||||
//#include "strparse.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include "crtdbg.h" // for memory allocation debugging
|
||||
#endif
|
||||
|
||||
void midi_fail(char *msg)
|
||||
{
|
||||
printf("Failure: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void *midi_alloc(size_t s) { return malloc(s); }
|
||||
void midi_free(void *a) { free(a); }
|
||||
|
||||
|
||||
void print_help()
|
||||
{
|
||||
printf("Usage: allegroplay [-m] [-a] <filename> [-n]\n");
|
||||
printf(" use -m for midifile, -a for allegro file.\n");
|
||||
printf(" .mid extension implies -m, .gro implies -a\n");
|
||||
printf(" use -n for non-interactive use (no prompts)\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
print_help();
|
||||
}
|
||||
char *filename = NULL;
|
||||
bool midifile = false;
|
||||
bool allegrofile = false;
|
||||
bool interactive = true;
|
||||
int i = 1; // scan the command line
|
||||
while (i < argc) {
|
||||
if (argv[i][0] == '-') {
|
||||
if (argv[1][1] == 'm') midifile = true;
|
||||
else if (argv[i][1] == 'a') allegrofile = true;
|
||||
else if (argv[i][1] == 'n') interactive = false;
|
||||
} else {
|
||||
filename = argv[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!filename) {
|
||||
print_help();
|
||||
}
|
||||
|
||||
if (!midifile && !allegrofile) {
|
||||
int len = strlen(filename);
|
||||
if (len < 4) print_help(); // no extension, need -m or -a
|
||||
char *ext = filename + len - 4;
|
||||
if (strcmp(ext, ".mid") == 0) midifile = true;
|
||||
else if (strcmp(ext, ".gro") == 0) allegrofile = true;
|
||||
else print_help();
|
||||
}
|
||||
Alg_seq seq(filename, midifile);
|
||||
|
||||
int events = 0;
|
||||
for (i = 0; i < seq.tracks(); i++) {
|
||||
events += seq.track(i)->length();
|
||||
}
|
||||
if (interactive) {
|
||||
printf("%d tracks, %d events\n", seq.tracks(), events);
|
||||
}
|
||||
/* PLAY THE FILE VIA MIDI: */
|
||||
if (interactive) {
|
||||
printf("type return to play midi file: ");
|
||||
char input[80];
|
||||
fgets(input, 80, stdin);
|
||||
}
|
||||
seq_play(seq);
|
||||
|
||||
return 0;
|
||||
}
|
62
lib-src/portsmf/apps/midicode.h
Executable file
62
lib-src/portsmf/apps/midicode.h
Executable file
@@ -0,0 +1,62 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* Midi codes
|
||||
* Copyright 1989 Carnegie Mellon University
|
||||
*
|
||||
*************************************************************************
|
||||
* Change Log
|
||||
* Date | Change
|
||||
*-----------+------------------------------------------------------------
|
||||
* 11-Mar-94 | PLu : Port to IRI
|
||||
************************************************************************/
|
||||
|
||||
#define MIDI_DATA(d) (0x7f & (d))
|
||||
#define MIDI_CHANNEL(c) (0x0f & ((c) - 1))
|
||||
#define MIDI_PORT(c) (((c) - 1) >> 4)
|
||||
#define MIDI_PROGRAM(p) MIDI_DATA((p) - 1)
|
||||
|
||||
#define MIDI_STATUS_BIT 0x80
|
||||
#define MIDI_COMMON 0x70
|
||||
#define MIDI_CODE_MASK 0xf0
|
||||
#define MIDI_CHN_MASK 0x0f
|
||||
#define MIDI_REALTIME 0xf8
|
||||
#define MIDI_CHAN_MODE 0xfa
|
||||
|
||||
#define MIDI_OFF_NOTE 0x80
|
||||
#define MIDI_ON_NOTE 0x90
|
||||
#define MIDI_POLY_TOUCH 0xa0
|
||||
#define MIDI_CTRL 0xb0
|
||||
#define MIDI_CH_PROGRAM 0xc0
|
||||
#define MIDI_TOUCH 0xd0
|
||||
#define MIDI_BEND 0xe0
|
||||
|
||||
#ifdef UNIX_IRIX_MIDIFNS
|
||||
#define CMT_MIDI_SYSEX 0xf0
|
||||
#define CMT_MIDI_EOX 0xf7
|
||||
#else
|
||||
#define MIDI_SYSEX 0xf0
|
||||
#define MIDI_EOX 0xf7
|
||||
#endif
|
||||
#define MIDI_Q_FRAME 0xf1
|
||||
#define MIDI_SONG_POINTER 0xf2
|
||||
#define MIDI_SONG_SELECT 0xf3
|
||||
#define MIDI_F4 0xf4
|
||||
#define MIDI_F5 0xf5
|
||||
#define MIDI_TUNE_REQ 0xf6
|
||||
#define MIDI_TIME_CLOCK 0xf8
|
||||
#define MIDI_F9 0xf9
|
||||
#define MIDI_START 0xfa
|
||||
#define MIDI_CONTINUE 0xfb
|
||||
#define MIDI_STOP 0xfc
|
||||
#define MIDI_FD 0xfd
|
||||
#define MIDI_ACTIVE_SENSING 0xfe
|
||||
#define MIDI_SYS_RESET 0xff
|
||||
|
||||
#define MIDI_LOCAL 0x7a
|
||||
#define MIDI_LOCAL_OFF 0x00
|
||||
#define MIDI_LOCAL_ON 0x7f
|
||||
#define MIDI_ALL_OFF 0x7b
|
||||
#define MIDI_OMNI_OFF 0x7c
|
||||
#define MIDI_OMNI_ON 0x7d
|
||||
#define MIDI_MONO_ON 0x7e
|
||||
#define MIDI_POLY_ON 0x7f
|
166
lib-src/portsmf/apps/seq2midi.cpp
Normal file
166
lib-src/portsmf/apps/seq2midi.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
// seq2midi.cpp -- simple sequence player, intended to help test/demo
|
||||
// the allegro code
|
||||
|
||||
#include <fstream>
|
||||
#include "allegro.h"
|
||||
#include "porttime.h"
|
||||
#include "portmidi.h"
|
||||
#include "midicode.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define ROUND(x) (int) ((x)+0.5)
|
||||
|
||||
|
||||
double time_elapsed()
|
||||
{
|
||||
return Pt_Time() * 0.001;
|
||||
}
|
||||
|
||||
|
||||
void wait_until(double time)
|
||||
{
|
||||
// print "." to stdout while waiting
|
||||
static double last_time = 0.0;
|
||||
double now = time_elapsed();
|
||||
if (now < last_time) last_time = now;
|
||||
while (now < time) {
|
||||
Pt_Sleep(1);
|
||||
now = time_elapsed();
|
||||
long now_sec = (long) now;
|
||||
long last_sec = (long) last_time;
|
||||
if (now_sec > last_sec) {
|
||||
fprintf(stdout, ".");
|
||||
fflush(stdout);
|
||||
last_time = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define never 1000000 // represents infinite time
|
||||
|
||||
void midi_note_on(PortMidiStream *midi, double when, int chan, int key, int loud)
|
||||
{
|
||||
unsigned long timestamp = (unsigned long) (when * 1000);
|
||||
chan = chan & 15;
|
||||
if (key > 127) key = 127;
|
||||
if (key < 0) key = 0;
|
||||
if (loud > 127) loud = 127;
|
||||
if (loud < 0) loud = 0;
|
||||
unsigned long data = Pm_Message(0x90 + chan, key, loud);
|
||||
Pm_WriteShort(midi, timestamp, data);
|
||||
}
|
||||
|
||||
|
||||
static void midi_channel_message_2(PortMidiStream *midi, double when,
|
||||
int status, int chan, int data)
|
||||
{
|
||||
unsigned long timestamp = (unsigned long) (when * 1000);
|
||||
chan = chan & 15;
|
||||
if (data > 127) data = 127;
|
||||
if (data < 0) data = 0;
|
||||
unsigned long msg = Pm_Message(status + chan, data, 0);
|
||||
Pm_WriteShort(midi, timestamp, msg);
|
||||
}
|
||||
|
||||
|
||||
static void midi_channel_message(PortMidiStream *midi, double when,
|
||||
int status, int chan, int data, int data2)
|
||||
{
|
||||
unsigned long timestamp = (unsigned long) (when * 1000);
|
||||
chan = chan & 15;
|
||||
if (data > 127) data = 127;
|
||||
if (data < 0) data = 0;
|
||||
if (data2 > 127) data2 = 127;
|
||||
if (data2 < 0) data2 = 0;
|
||||
unsigned long msg = Pm_Message(status + chan, data, data2);
|
||||
Pm_WriteShort(midi, timestamp, msg);
|
||||
}
|
||||
|
||||
|
||||
static const char *pressure_attr;
|
||||
static const char *bend_attr;
|
||||
static const char *program_attr;
|
||||
|
||||
|
||||
void send_midi_update(Alg_update_ptr u, PortMidiStream *midi)
|
||||
{
|
||||
if (u->get_attribute() == pressure_attr) {
|
||||
if (u->get_identifier() < 0) {
|
||||
midi_channel_message_2(midi, u->time, MIDI_TOUCH, u->chan,
|
||||
(int) (u->get_real_value() * 127));
|
||||
} else {
|
||||
midi_channel_message(midi, u->time, MIDI_POLY_TOUCH, u->chan,
|
||||
u->get_identifier(),
|
||||
(int) (u->get_real_value() * 127));
|
||||
}
|
||||
} else if (u->get_attribute() == bend_attr) {
|
||||
int bend = ROUND((u->get_real_value() + 1) * 8192);
|
||||
if (bend > 8191) bend = 8191;
|
||||
if (bend < 0) bend = 0;
|
||||
midi_channel_message(midi, u->time, MIDI_BEND, u->chan,
|
||||
bend >> 7, bend & 0x7F);
|
||||
} else if (u->get_attribute() == program_attr) {
|
||||
midi_channel_message_2(midi, u->time, MIDI_CH_PROGRAM,
|
||||
u->chan, u->get_integer_value());
|
||||
} else if (strncmp("control", u->get_attribute(), 7) == 0 &&
|
||||
u->get_update_type() == 'r') {
|
||||
int control = atoi(u->get_attribute() + 7);
|
||||
int val = ROUND(u->get_real_value() * 127);
|
||||
midi_channel_message(midi, u->time, MIDI_CTRL, u->chan, control, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void seq2midi(Alg_seq &seq, PortMidiStream *midi)
|
||||
{
|
||||
// prepare by doing lookup of important symbols
|
||||
pressure_attr = symbol_table.insert_string("pressurer") + 1;
|
||||
bend_attr = symbol_table.insert_string("bendr") + 1;
|
||||
program_attr = symbol_table.insert_string("programi") + 1;
|
||||
|
||||
Alg_iterator iterator(&seq, true);
|
||||
iterator.begin();
|
||||
bool note_on;
|
||||
Alg_event_ptr e = iterator.next(¬e_on);
|
||||
Pt_Start(1, NULL, NULL); // initialize time
|
||||
while (e) {
|
||||
double next_time = (note_on ? e->time : e->get_end_time());
|
||||
wait_until(next_time);
|
||||
if (e->is_note() && note_on) { // process notes here
|
||||
// printf("Note at %g: chan %d key %d loud %d\n",
|
||||
// next_time, e->chan, e->key, (int) e->loud);
|
||||
midi_note_on(midi, next_time, e->chan, e->get_identifier(),
|
||||
(int) e->get_loud());
|
||||
} else if (e->is_note()) { // must be a note off
|
||||
midi_note_on(midi, next_time, e->chan, e->get_identifier(), 0);
|
||||
} else if (e->is_update()) { // process updates here
|
||||
Alg_update_ptr u = (Alg_update_ptr) e; // coerce to proper type
|
||||
send_midi_update(u, midi);
|
||||
}
|
||||
// add next note
|
||||
e = iterator.next(¬e_on);
|
||||
}
|
||||
iterator.end();
|
||||
}
|
||||
|
||||
|
||||
void seq_play(Alg_seq &seq)
|
||||
{
|
||||
PortMidiStream *mo;
|
||||
Pm_Initialize();
|
||||
PmDeviceID dev = Pm_GetDefaultOutputDeviceID();
|
||||
// note that the Pt_Time type cast is required because Pt_Time does
|
||||
// not take an input parameter, whereas for generality, PortMidi
|
||||
// passes in a void * so the time function can get some context.
|
||||
// It is safe to call Pt_Time with a parameter -- it will just be ignored.
|
||||
if (Pm_OpenOutput(&mo, dev, NULL, 256,
|
||||
(PmTimestamp (*)(void *))&Pt_Time, NULL, 100) == pmNoError) {
|
||||
seq2midi(seq, mo);
|
||||
wait_until(time_elapsed() + 1);
|
||||
Pm_Close(mo);
|
||||
}
|
||||
Pm_Terminate();
|
||||
return;
|
||||
}
|
5
lib-src/portsmf/apps/seq2midi.h
Normal file
5
lib-src/portsmf/apps/seq2midi.h
Normal file
@@ -0,0 +1,5 @@
|
||||
// play a sequence to a midi stream
|
||||
void seq2midi(Alg_seq &seq, PortMidiStream *midi);
|
||||
|
||||
// open a stream, play a sequence, close the stream
|
||||
void seq_play(Alg_seq &seq);
|
Reference in New Issue
Block a user