Update MIDI loading and parsing
portsmf fixes: * Fix allegro warnings as errors * Fix msvc missing max. Use MAX macro instead
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include <QProgressDialog>
|
||||
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "MidiImport.h"
|
||||
#include "TrackContainer.h"
|
||||
@@ -305,7 +306,7 @@ public:
|
||||
|
||||
bool MidiImport::readSMF( TrackContainer* tc )
|
||||
{
|
||||
|
||||
const int MIDI_CC_COUNT = 128 + 1; // 0-127 (128) + pitch bend
|
||||
const int preTrackSteps = 2;
|
||||
QProgressDialog pd( TrackContainer::tr( "Importing MIDI-file..." ),
|
||||
TrackContainer::tr( "Cancel" ), 0, preTrackSteps, gui->mainWindow() );
|
||||
@@ -315,10 +316,7 @@ bool MidiImport::readSMF( TrackContainer* tc )
|
||||
|
||||
pd.setValue( 0 );
|
||||
|
||||
std::stringstream stream;
|
||||
QByteArray arr = readAllData();
|
||||
stream.str(std::string(arr.constData(), arr.size()));
|
||||
|
||||
std::istringstream stream(readAllData().toStdString());
|
||||
Alg_seq_ptr seq = new Alg_seq(stream, true);
|
||||
seq->convert_to_beats();
|
||||
|
||||
@@ -326,8 +324,12 @@ bool MidiImport::readSMF( TrackContainer* tc )
|
||||
pd.setValue( 1 );
|
||||
|
||||
// 128 CC + Pitch Bend
|
||||
smfMidiCC ccs[129];
|
||||
smfMidiChannel chs[256];
|
||||
smfMidiCC ccs[MIDI_CC_COUNT];
|
||||
|
||||
// channels can be set out of 256 range
|
||||
// using unordered_map should fix most invalid loads and crashes while loading
|
||||
std::unordered_map<long, smfMidiChannel> chs;
|
||||
// NOTE: unordered_map::operator[] creates a new element if none exists
|
||||
|
||||
MeterModel & timeSigMM = Engine::getSong()->getTimeSigModel();
|
||||
AutomationTrack * nt = dynamic_cast<AutomationTrack*>(
|
||||
@@ -407,7 +409,7 @@ bool MidiImport::readSMF( TrackContainer* tc )
|
||||
Alg_track_ptr trk = seq->track( t );
|
||||
pd.setValue( t + preTrackSteps );
|
||||
|
||||
for( int c = 0; c < 129; c++ )
|
||||
for( int c = 0; c < MIDI_CC_COUNT; c++ )
|
||||
{
|
||||
ccs[c].clear();
|
||||
}
|
||||
@@ -423,7 +425,10 @@ bool MidiImport::readSMF( TrackContainer* tc )
|
||||
if( evt->is_update() )
|
||||
{
|
||||
QString attr = evt->get_attribute();
|
||||
if( attr == "tracknames" && evt->get_update_type() == 's' ) {
|
||||
// seqnames is a track0 identifier (see allegro code)
|
||||
if (attr == (t == 0 ? "seqnames" : "tracknames")
|
||||
&& evt->get_update_type() == 's')
|
||||
{
|
||||
trackName = evt->get_string_value();
|
||||
handled = true;
|
||||
}
|
||||
@@ -444,7 +449,7 @@ bool MidiImport::readSMF( TrackContainer* tc )
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
else if( evt->is_note() && evt->chan < 256 )
|
||||
else if (evt->is_note())
|
||||
{
|
||||
smfMidiChannel * ch = chs[evt->chan].create( tc, trackName );
|
||||
Alg_note_ptr noteEvt = dynamic_cast<Alg_note_ptr>( evt );
|
||||
@@ -558,28 +563,26 @@ bool MidiImport::readSMF( TrackContainer* tc )
|
||||
delete seq;
|
||||
|
||||
|
||||
for( int c=0; c < 256; ++c )
|
||||
for( auto& c: chs )
|
||||
{
|
||||
if (chs[c].hasNotes)
|
||||
if (c.second.hasNotes)
|
||||
{
|
||||
chs[c].splitPatterns();
|
||||
c.second.splitPatterns();
|
||||
}
|
||||
else if (chs[c].it)
|
||||
else if (c.second.it)
|
||||
{
|
||||
printf(" Should remove empty track\n");
|
||||
// must delete trackView first - but where is it?
|
||||
//tc->removeTrack( chs[c].it );
|
||||
//it->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
// Set channel 10 to drums as per General MIDI's orders
|
||||
if( chs[9].hasNotes && chs[9].it_inst && chs[9].isSF2 )
|
||||
{
|
||||
// AFAIK, 128 should be the standard bank for drums in SF2.
|
||||
// If not, this has to be made configurable.
|
||||
chs[9].it_inst->childModel( "bank" )->setValue( 128 );
|
||||
chs[9].it_inst->childModel( "patch" )->setValue( 0 );
|
||||
// Set channel 10 to drums as per General MIDI's orders
|
||||
if (c.first % 16l == 9 /* channel 10 */
|
||||
&& c.second.hasNotes && c.second.it_inst && c.second.isSF2)
|
||||
{
|
||||
c.second.it_inst->childModel("bank")->setValue(128);
|
||||
c.second.it_inst->childModel("patch")->setValue(0);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -30,7 +30,7 @@ using namespace std;
|
||||
// 4311 is type cast ponter to long warning
|
||||
// 4996 is warning against strcpy
|
||||
// 4267 is size_t to long warning
|
||||
#pragma warning(disable: 4311 4996 4267)
|
||||
//#pragma warning(disable: 4311 4996 4267)
|
||||
Alg_atoms symbol_table;
|
||||
Serial_read_buffer Alg_track::ser_read_buf; // declare the static variables
|
||||
Serial_write_buffer Alg_track::ser_write_buf;
|
||||
@@ -720,7 +720,7 @@ Alg_event_list::Alg_event_list(Alg_track *owner)
|
||||
}
|
||||
|
||||
|
||||
Alg_event_ptr &Alg_event_list::operator [](int i)
|
||||
Alg_event_ptr const &Alg_event_list::operator [](int i)
|
||||
{
|
||||
assert(i >= 0 && i < len);
|
||||
return events[i];
|
||||
@@ -739,8 +739,8 @@ void Alg_event_list::set_start_time(Alg_event *event, double t)
|
||||
// For Alg_track, change the time and move the event to the right place
|
||||
// For Alg_seq, find the track and do the update there
|
||||
|
||||
long index, i;
|
||||
Alg_track_ptr track_ptr;
|
||||
long index = 0, i;
|
||||
Alg_track_ptr track_ptr = nullptr;
|
||||
if (type == 'e') { // this is an Alg_event_list
|
||||
// make sure the owner has not changed its event set
|
||||
assert(events_owner &&
|
||||
@@ -1522,7 +1522,7 @@ Alg_track *Alg_track::unserialize(void *buffer, long len)
|
||||
bool alg = ser_read_buf.get_char() == 'A' &&
|
||||
ser_read_buf.get_char() == 'L' &&
|
||||
ser_read_buf.get_char() == 'G';
|
||||
assert(alg);
|
||||
assert(alg); (void)alg; // unused variable
|
||||
char c = ser_read_buf.get_char();
|
||||
if (c == 'S') {
|
||||
Alg_seq *seq = new Alg_seq;
|
||||
@@ -1539,7 +1539,7 @@ Alg_track *Alg_track::unserialize(void *buffer, long len)
|
||||
}
|
||||
|
||||
|
||||
#pragma warning(disable: 4800) // long to bool performance warning
|
||||
//#pragma warning(disable: 4800) // long to bool performance warning
|
||||
|
||||
/* Note: this Alg_seq must have a default initialized Alg_time_map.
|
||||
* It will be filled in with data from the ser_read_buf buffer.
|
||||
@@ -1551,9 +1551,9 @@ void Alg_seq::unserialize_seq()
|
||||
(ser_read_buf.get_char() == 'L') &&
|
||||
(ser_read_buf.get_char() == 'G') &&
|
||||
(ser_read_buf.get_char() == 'S');
|
||||
assert(algs);
|
||||
assert(algs); (void)algs; // unused variable
|
||||
long len = ser_read_buf.get_int32();
|
||||
assert(ser_read_buf.get_len() >= len);
|
||||
assert(ser_read_buf.get_len() >= len); (void)len; // unused variable
|
||||
channel_offset_per_track = ser_read_buf.get_int32();
|
||||
units_are_seconds = ser_read_buf.get_int32() != 0;
|
||||
beat_dur = ser_read_buf.get_double();
|
||||
@@ -1599,10 +1599,10 @@ void Alg_track::unserialize_track()
|
||||
(ser_read_buf.get_char() == 'L') &&
|
||||
(ser_read_buf.get_char() == 'G') &&
|
||||
(ser_read_buf.get_char() == 'T');
|
||||
assert(algt);
|
||||
assert(algt); (void)algt; // unused variable
|
||||
long offset = ser_read_buf.get_posn(); // stored length does not include 'ALGT'
|
||||
long bytes = ser_read_buf.get_int32();
|
||||
assert(bytes <= ser_read_buf.get_len() - offset);
|
||||
assert(bytes <= ser_read_buf.get_len() - offset); (void)offset; (void)bytes; // unused variable
|
||||
units_are_seconds = (bool) ser_read_buf.get_int32();
|
||||
beat_dur = ser_read_buf.get_double();
|
||||
real_dur = ser_read_buf.get_double();
|
||||
@@ -1672,7 +1672,7 @@ void Alg_track::unserialize_parameter(Alg_parameter_ptr parm_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning(default: 4800)
|
||||
//#pragma warning(default: 4800)
|
||||
|
||||
void Alg_track::set_time_map(Alg_time_map *map)
|
||||
{
|
||||
@@ -1840,6 +1840,7 @@ void Alg_track::paste(double t, Alg_event_list *seq)
|
||||
bool prev_units_are_seconds;
|
||||
if (seq->get_type() == 'e') {
|
||||
assert(seq->get_owner()->get_units_are_seconds() == units_are_seconds);
|
||||
prev_units_are_seconds = seq->get_owner()->get_units_are_seconds();
|
||||
} else { // make it match
|
||||
Alg_track_ptr tr = (Alg_track_ptr) seq;
|
||||
prev_units_are_seconds = tr->get_units_are_seconds();
|
||||
@@ -2381,14 +2382,14 @@ void Alg_time_sigs::paste(double start, Alg_seq *seq)
|
||||
double num_of_insert = 4.0;
|
||||
double den_of_insert = 4.0;
|
||||
double beat_of_insert = 0.0;
|
||||
int first_from_index = 0; // where to start copying from
|
||||
/* int first_from_index = 0; // where to start copying from TODO: LMMS commented out unused variable */
|
||||
if (from.length() > 0 && from[0].beat < ALG_EPS) {
|
||||
// there is an initial time signature in "from"
|
||||
num_of_insert = from[0].num;
|
||||
den_of_insert = from[0].den;
|
||||
// since we are handling the first time signature in from,
|
||||
// we can start copying at index == 1:
|
||||
first_from_index = 1;
|
||||
/* first_from_index = 1; TODO: LMMS commented out unused variable */
|
||||
}
|
||||
// compare time signatures to see if we need a change at start:
|
||||
if (num_before_splice != num_of_insert ||
|
||||
@@ -2431,14 +2432,14 @@ void Alg_time_sigs::paste(double start, Alg_seq *seq)
|
||||
double measures = (start - beat_after_splice) / beats_per_measure;
|
||||
// Measures might be slightly negative due to rounding. Use max()
|
||||
// to eliminate any negative rounding error:
|
||||
int imeasures = int(max(measures, 0.0));
|
||||
int imeasures = int(MAX(measures, 0.0));
|
||||
double old_bar_loc = beat_after_splice + (imeasures * beats_per_measure);
|
||||
if (old_bar_loc < start) old_bar_loc += beats_per_measure;
|
||||
// now old_bar_loc is the original first bar position after start
|
||||
// Do similar calculation for position after end after the insertion:
|
||||
// beats_per_measure already calculated because signatures match
|
||||
measures = (start + dur - beat_of_insert) / beats_per_measure;
|
||||
imeasures = int(max(measures, 0.0));
|
||||
imeasures = int(MAX(measures, 0.0));
|
||||
double new_bar_loc = beat_of_insert + (imeasures * beats_per_measure);
|
||||
if (new_bar_loc < start + dur) new_bar_loc += beats_per_measure;
|
||||
// old_bar_loc should be shifted by dur:
|
||||
@@ -2864,9 +2865,9 @@ Alg_track_ptr Alg_seq::track(int i)
|
||||
return &(track_list[i]);
|
||||
}
|
||||
|
||||
#pragma warning(disable: 4715) // ok not to return a value here
|
||||
//#pragma warning(disable: 4715) // ok not to return a value here
|
||||
|
||||
Alg_event_ptr &Alg_seq::operator[](int i)
|
||||
Alg_event_ptr const &Alg_seq::operator[](int i)
|
||||
{
|
||||
int ntracks = track_list.length();
|
||||
int tr = 0;
|
||||
@@ -2880,8 +2881,9 @@ Alg_event_ptr &Alg_seq::operator[](int i)
|
||||
tr++;
|
||||
}
|
||||
assert(false); // out of bounds
|
||||
return NULL;
|
||||
}
|
||||
#pragma warning(default: 4715)
|
||||
//#pragma warning(default: 4715)
|
||||
|
||||
|
||||
void Alg_seq::convert_to_beats()
|
||||
@@ -3044,7 +3046,7 @@ void Alg_seq::insert_silence(double t, double len)
|
||||
// Final duration is defined to be t + len + whatever was
|
||||
// in the sequence after t (if any). This translates to
|
||||
// t + len + max(dur - t, 0)
|
||||
set_dur(t + len + max(get_dur() - t, 0.0));
|
||||
set_dur(t + len + MAX(get_dur() - t, 0.0));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -391,7 +391,7 @@ public:
|
||||
// When applied to an Alg_seq, events are enumerated track
|
||||
// by track with increasing indices. This operation is not
|
||||
// particularly fast on an Alg_seq.
|
||||
virtual Alg_event_ptr &operator[](int i);
|
||||
virtual Alg_event_ptr const &operator[](int i);
|
||||
Alg_event_list() { sequence_number = 0;
|
||||
beat_dur = 0.0; real_dur = 0.0; events_owner = NULL; type = 'e'; }
|
||||
Alg_event_list(Alg_track *owner);
|
||||
@@ -549,12 +549,12 @@ public:
|
||||
// does nothing.
|
||||
virtual ~Serial_read_buffer() { }
|
||||
#if defined(_WIN32)
|
||||
#pragma warning(disable: 546) // cast to int is OK, we only want low 7 bits
|
||||
#pragma warning(disable: 4311) // type cast pointer to long warning
|
||||
//#pragma warning(disable: 546) // cast to int is OK, we only want low 7 bits
|
||||
//#pragma warning(disable: 4311) // type cast pointer to long warning
|
||||
#endif
|
||||
void get_pad() { while (((long) ptr) & 7) ptr++; }
|
||||
void get_pad() { while ((intptr_t) ptr & 7) ptr++; }
|
||||
#if defined(_WIN32)
|
||||
#pragma warning(default: 4311 546)
|
||||
//#pragma warning(default: 4311 546)
|
||||
#endif
|
||||
// Prepare to read n bytes from buf. The caller must manage buf: it is
|
||||
// valid until reading is finished, and it is caller's responsibility
|
||||
@@ -571,7 +571,7 @@ public:
|
||||
double get_double() { double d = *((double *) ptr); ptr += sizeof(double);
|
||||
return d; }
|
||||
const char *get_string() { char *s = ptr; char *fence = buffer + len;
|
||||
assert(ptr < fence);
|
||||
assert(ptr < fence); (void)fence; // unused variable
|
||||
while (*ptr++) assert(ptr < fence);
|
||||
get_pad();
|
||||
return s; }
|
||||
@@ -600,18 +600,18 @@ typedef class Serial_write_buffer: public Serial_buffer {
|
||||
void check_buffer(long needed);
|
||||
void set_string(const char *s) {
|
||||
char *fence = buffer + len;
|
||||
assert(ptr < fence);
|
||||
assert(ptr < fence); (void)fence; // unused variable
|
||||
// two brackets surpress a g++ warning, because this is an
|
||||
// assignment operator inside a test.
|
||||
while ((*ptr++ = *s++)) assert(ptr < fence);
|
||||
// 4311 is type cast pointer to long warning
|
||||
// 4312 is type cast long to pointer warning
|
||||
#if defined(_WIN32)
|
||||
#pragma warning(disable: 4311 4312)
|
||||
//#pragma warning(disable: 4311 4312)
|
||||
#endif
|
||||
assert((char *)(((long) (ptr + 7)) & ~7) <= fence);
|
||||
#if defined(_WIN32)
|
||||
#pragma warning(default: 4311 4312)
|
||||
//#pragma warning(default: 4311 4312)
|
||||
#endif
|
||||
pad(); }
|
||||
void set_int32(long v) { *((long *) ptr) = v; ptr += 4; }
|
||||
@@ -619,12 +619,12 @@ typedef class Serial_write_buffer: public Serial_buffer {
|
||||
void set_float(float v) { *((float *) ptr) = v; ptr += 4; }
|
||||
void set_char(char v) { *ptr++ = v; }
|
||||
#if defined(_WIN32)
|
||||
#pragma warning(disable: 546) // cast to int is OK, we only want low 7 bits
|
||||
#pragma warning(disable: 4311) // type cast pointer to long warning
|
||||
//#pragma warning(disable: 546) // cast to int is OK, we only want low 7 bits
|
||||
//#pragma warning(disable: 4311) // type cast pointer to long warning
|
||||
#endif
|
||||
void pad() { while (((long) ptr) & 7) set_char(0); }
|
||||
void pad() { while ((intptr_t) ptr & 7) set_char(0); }
|
||||
#if defined(_WIN32)
|
||||
#pragma warning(default: 4311 546)
|
||||
//#pragma warning(default: 4311 546)
|
||||
#endif
|
||||
void *to_heap(long *len) {
|
||||
*len = get_posn();
|
||||
@@ -653,7 +653,7 @@ protected:
|
||||
public:
|
||||
void serialize_track();
|
||||
void unserialize_track();
|
||||
virtual Alg_event_ptr &operator[](int i) {
|
||||
virtual Alg_event_ptr const &operator[](int i) {
|
||||
assert(i >= 0 && i < len);
|
||||
return events[i];
|
||||
}
|
||||
@@ -669,7 +669,8 @@ public:
|
||||
Alg_track(Alg_event_list_ref event_list, Alg_time_map_ptr map,
|
||||
bool units_are_seconds);
|
||||
virtual ~Alg_track() { // note: do not call set_time_map(NULL)!
|
||||
if (time_map) time_map->dereference(); time_map = NULL; }
|
||||
if (time_map) time_map->dereference();
|
||||
time_map = NULL; }
|
||||
|
||||
// Returns a buffer containing a serialization of the
|
||||
// file. It will be an ASCII representation unless text is true.
|
||||
@@ -1058,7 +1059,7 @@ public:
|
||||
// caller must not delete the result.
|
||||
Alg_track_ptr track(int);
|
||||
|
||||
virtual Alg_event_ptr &operator[](int i);
|
||||
virtual Alg_event_ptr const &operator[](int i);
|
||||
|
||||
virtual void convert_to_seconds();
|
||||
virtual void convert_to_beats();
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
int find_real_in(string &field, int n);
|
||||
double parse_real(string &field);
|
||||
void parse_error(string &field, long offset, char *message);
|
||||
void parse_error(string &field, long offset, const char *message);
|
||||
double parse_dur(string &field, double base);
|
||||
double parse_after_dur(double dur, string &field, int n, double base);
|
||||
double parse_loud(string &field);
|
||||
@@ -116,19 +117,19 @@ Alg_parameters_ptr Alg_reader::process_attributes(
|
||||
if (attributes) {
|
||||
Alg_parameters_ptr a;
|
||||
bool in_seconds = seq->get_units_are_seconds();
|
||||
if (a = Alg_parameters::remove_key(&attributes, "tempor")) {
|
||||
if ((a = Alg_parameters::remove_key(&attributes, "tempor"))) {
|
||||
double tempo = a->parm.r;
|
||||
seq->insert_tempo(tempo, seq->get_time_map()->time_to_beat(time));
|
||||
}
|
||||
if (a = Alg_parameters::remove_key(&attributes, "beatr")) {
|
||||
if ((a = Alg_parameters::remove_key(&attributes, "beatr"))) {
|
||||
double beat = a->parm.r;
|
||||
seq->insert_beat(time, beat);
|
||||
}
|
||||
if (a = Alg_parameters::remove_key(&attributes, "timesig_numr")) {
|
||||
if ((a = Alg_parameters::remove_key(&attributes, "timesig_numr"))) {
|
||||
tsnum = a->parm.r;
|
||||
ts_flag = true;
|
||||
}
|
||||
if (a = Alg_parameters::remove_key(&attributes, "timesig_denr")) {
|
||||
if ((a = Alg_parameters::remove_key(&attributes, "timesig_denr"))) {
|
||||
tsden = a->parm.r;
|
||||
ts_flag = true;
|
||||
}
|
||||
@@ -158,7 +159,7 @@ bool Alg_reader::parse()
|
||||
while (line_parser_flag) {
|
||||
bool time_flag = false;
|
||||
bool next_flag = false;
|
||||
double next;
|
||||
double next = 0;
|
||||
bool voice_flag = false;
|
||||
bool loud_flag = false;
|
||||
bool dur_flag = false;
|
||||
@@ -422,11 +423,11 @@ bool Alg_reader::parse()
|
||||
long Alg_reader::parse_chan(string &field)
|
||||
{
|
||||
const char *int_string = field.c_str() + 1;
|
||||
char *msg = "Integer or - expected";
|
||||
const char *msg = "Integer or - expected";
|
||||
const char *p = int_string;
|
||||
char c;
|
||||
// check that all chars in int_string are digits or '-':
|
||||
while (c = *p++) {
|
||||
while ((c = *p++)) {
|
||||
if (!isdigit(c) && c != '-') {
|
||||
parse_error(field, p - field.c_str() - 1, msg);
|
||||
return 0;
|
||||
@@ -449,11 +450,11 @@ long Alg_reader::parse_chan(string &field)
|
||||
long Alg_reader::parse_int(string &field)
|
||||
{
|
||||
const char *int_string = field.c_str() + 1;
|
||||
char *msg = "Integer expected";
|
||||
const char *msg = "Integer expected";
|
||||
const char *p = int_string;
|
||||
char c;
|
||||
// check that all chars in int_string are digits:
|
||||
while (c = *p++) {
|
||||
while ((c = *p++)) {
|
||||
if (!isdigit(c)) {
|
||||
parse_error(field, p - field.c_str() - 1, msg);
|
||||
return 0;
|
||||
@@ -491,7 +492,7 @@ int Alg_reader::find_real_in(string &field, int n)
|
||||
|
||||
double Alg_reader::parse_real(string &field)
|
||||
{
|
||||
char *msg = "Real expected";
|
||||
const char *msg = "Real expected";
|
||||
int last = find_real_in(field, 1);
|
||||
string real_string = field.substr(1, last - 1);
|
||||
if (last <= 1 || last < (int) field.length()) {
|
||||
@@ -514,15 +515,20 @@ void Alg_reader::parse_error(string &field, long offset, char *message)
|
||||
printf(" %s\n", message);
|
||||
}
|
||||
|
||||
void Alg_reader::parse_error(string &field, long offset, const char *message)
|
||||
{
|
||||
parse_error(field, offset, const_cast<char*>(message));
|
||||
}
|
||||
|
||||
|
||||
double duration_lookup[] = { 0.25, 0.5, 1.0, 2.0, 4.0 };
|
||||
|
||||
|
||||
double Alg_reader::parse_dur(string &field, double base)
|
||||
{
|
||||
char *msg = "Duration expected";
|
||||
char *durs = "SIQHW";
|
||||
char *p;
|
||||
const char *msg = "Duration expected";
|
||||
const char *durs = "SIQHW";
|
||||
const char *p;
|
||||
int last;
|
||||
double dur;
|
||||
if (field.length() < 2) {
|
||||
@@ -535,7 +541,7 @@ double Alg_reader::parse_dur(string &field, double base)
|
||||
// convert dur from seconds to beats
|
||||
dur = seq->get_time_map()->time_to_beat(base + dur) -
|
||||
seq->get_time_map()->time_to_beat(base);
|
||||
} else if (p = strchr(durs, toupper(field[1]))) {
|
||||
} else if ((p = strchr(durs, toupper(field[1])))) {
|
||||
dur = duration_lookup[p - durs];
|
||||
last = 2;
|
||||
} else {
|
||||
@@ -578,7 +584,7 @@ double Alg_reader::parse_after_dur(double dur, string &field,
|
||||
}
|
||||
|
||||
struct loud_lookup_struct {
|
||||
char *str;
|
||||
const char *str;
|
||||
int val;
|
||||
} loud_lookup[] = { {"FFF", 127}, {"FF", 120}, {"F", 110}, {"MF", 100},
|
||||
{"MP", 90}, {"P", 80}, {"PP", 70}, {"PPP", 60},
|
||||
@@ -587,7 +593,7 @@ struct loud_lookup_struct {
|
||||
|
||||
double Alg_reader::parse_loud(string &field)
|
||||
{
|
||||
char *msg = "Loudness expected";
|
||||
const char *msg = "Loudness expected";
|
||||
if (isdigit(field[1])) {
|
||||
return parse_int(field);
|
||||
} else {
|
||||
@@ -613,14 +619,14 @@ int key_lookup[] = {21, 23, 12, 14, 16, 17, 19};
|
||||
//
|
||||
long Alg_reader::parse_key(string &field)
|
||||
{
|
||||
char *msg = "Pitch expected";
|
||||
char *pitches = "ABCDEFG";
|
||||
char *p;
|
||||
const char *msg = "Pitch expected";
|
||||
const char *pitches = "ABCDEFG";
|
||||
const char *p;
|
||||
if (isdigit(field[1])) {
|
||||
// This routine would not have been called if field = "P<number>"
|
||||
// so it must be "K<number>" so <number> must be an integer.
|
||||
return parse_int(field);
|
||||
} else if (p = strchr(pitches, toupper(field[1]))) {
|
||||
} else if ((p = strchr(pitches, toupper(field[1])))) {
|
||||
long key = key_lookup[p - pitches];
|
||||
key = parse_after_key(key, field, 2);
|
||||
return key;
|
||||
@@ -716,9 +722,9 @@ bool Alg_reader::parse_val(Alg_parameter_ptr param, string &s, int i)
|
||||
} else if (isdigit(s[i]) || s[i] == '-' || s[i] == '.') {
|
||||
int pos = i;
|
||||
bool period = false;
|
||||
int sign = 1;
|
||||
/* int sign = 1; LMMS unused variable */
|
||||
if (s[pos] == '-') {
|
||||
sign = -1;
|
||||
/* sign = -1; LMMS unused variable */
|
||||
pos++;
|
||||
}
|
||||
while (pos < len) {
|
||||
|
||||
@@ -75,6 +75,7 @@ protected:
|
||||
void Mf_portprefix(int port);
|
||||
void Mf_eot();
|
||||
void Mf_error(char *);
|
||||
void Mf_error(const char *);
|
||||
void Mf_header(int,int,int);
|
||||
void Mf_on(int,int,int);
|
||||
void Mf_off(int,int,int);
|
||||
@@ -174,14 +175,19 @@ void Alg_midifile_reader::Mf_error(char *msg)
|
||||
fprintf(stdout, "Midifile reader error: %s\n", msg);
|
||||
}
|
||||
|
||||
void Alg_midifile_reader::Mf_error(const char *msg)
|
||||
{
|
||||
Mf_error(const_cast<char*>(msg));
|
||||
}
|
||||
|
||||
|
||||
void Alg_midifile_reader::Mf_header(int format, int ntrks, int division)
|
||||
{
|
||||
if (format > 1) {
|
||||
char msg[80];
|
||||
#pragma warning(disable: 4996) // msg is long enough
|
||||
//#pragma warning(disable: 4996) // msg is long enough
|
||||
sprintf(msg, "file format %d not implemented", format);
|
||||
#pragma warning(default: 4996)
|
||||
//#pragma warning(default: 4996)
|
||||
Mf_error(msg);
|
||||
}
|
||||
divisions = division;
|
||||
@@ -268,9 +274,9 @@ void Alg_midifile_reader::Mf_controller(int chan, int control, int val)
|
||||
{
|
||||
Alg_parameter parameter;
|
||||
char name[32];
|
||||
#pragma warning(disable: 4996) // name is long enough
|
||||
//#pragma warning(disable: 4996) // name is long enough
|
||||
sprintf(name, "control%dr", control);
|
||||
#pragma warning(default: 4996)
|
||||
//#pragma warning(default: 4996)
|
||||
parameter.set_attr(symbol_table.insert_string(name));
|
||||
parameter.r = val / 127.0;
|
||||
update(chan, -1, ¶meter);
|
||||
@@ -314,9 +320,9 @@ void Alg_midifile_reader::binary_msg(int len, unsigned char *msg,
|
||||
Alg_parameter parameter;
|
||||
char *hexstr = new char[len * 2 + 1];
|
||||
for (int i = 0; i < len; i++) {
|
||||
#pragma warning(disable: 4996) // hexstr is long enough
|
||||
//#pragma warning(disable: 4996) // hexstr is long enough
|
||||
sprintf(hexstr + 2 * i, "%02x", (0xFF & msg[i]));
|
||||
#pragma warning(default: 4996)
|
||||
//#pragma warning(default: 4996)
|
||||
}
|
||||
parameter.s = hexstr;
|
||||
parameter.set_attr(symbol_table.insert_string(attr_string));
|
||||
@@ -340,9 +346,9 @@ void Alg_midifile_reader::Mf_arbitrary(int len, unsigned char *msg)
|
||||
void Alg_midifile_reader::Mf_metamisc(int type, int len, unsigned char *msg)
|
||||
{
|
||||
char text[128];
|
||||
#pragma warning(disable: 4996) // text is long enough
|
||||
//#pragma warning(disable: 4996) // text is long enough
|
||||
sprintf(text, "metamsic data, type 0x%x, ignored", type);
|
||||
#pragma warning(default: 4996)
|
||||
//#pragma warning(default: 4996)
|
||||
Mf_error(text);
|
||||
}
|
||||
|
||||
@@ -353,7 +359,7 @@ void Alg_midifile_reader::Mf_seqnum(int n)
|
||||
}
|
||||
|
||||
|
||||
static char *fpsstr[4] = {"24", "25", "29.97", "30"};
|
||||
static const char *fpsstr[4] = {"24", "25", "29.97", "30"};
|
||||
|
||||
void Alg_midifile_reader::Mf_smpte(int hours, int mins, int secs,
|
||||
int frames, int subframes)
|
||||
@@ -363,10 +369,10 @@ void Alg_midifile_reader::Mf_smpte(int hours, int mins, int secs,
|
||||
char text[32];
|
||||
int fps = (hours >> 6) & 3;
|
||||
hours &= 0x1F;
|
||||
#pragma warning(disable: 4996) // text is long enough
|
||||
//#pragma warning(disable: 4996) // text is long enough
|
||||
sprintf(text, "%sfps:%02dh:%02dm:%02ds:%02d.%02df",
|
||||
fpsstr[fps], hours, mins, secs, frames, subframes);
|
||||
#pragma warning(default: 4996)
|
||||
//#pragma warning(default: 4996)
|
||||
Alg_parameter smpteoffset;
|
||||
smpteoffset.s = heapify(text);
|
||||
smpteoffset.set_attr(symbol_table.insert_string("smpteoffsets"));
|
||||
|
||||
@@ -353,7 +353,7 @@ void Alg_smf_write::write_update(Alg_update_ptr update)
|
||||
int len = strlen(s);
|
||||
char smpteoffset[5];
|
||||
if (len < 24) return; // not long enough, must be bad format
|
||||
int fps;
|
||||
int fps = 0;
|
||||
if (s[0] == '2') {
|
||||
if (s[1] == '4') fps = 0;
|
||||
else if (s[1] == '5') fps = 1;
|
||||
|
||||
@@ -35,7 +35,7 @@ void Midifile_reader::midifile()
|
||||
while (ntrks-- > 0 && !midifile_error) readtrack();
|
||||
}
|
||||
|
||||
int Midifile_reader::readmt(char *s, int skip)
|
||||
int Midifile_reader::readmt(const char *s, int skip)
|
||||
/* read through the "MThd" or "MTrk" header string */
|
||||
/* if skip == 1, we attempt to skip initial garbage. */
|
||||
{
|
||||
@@ -44,7 +44,7 @@ int Midifile_reader::readmt(char *s, int skip)
|
||||
char b[4];
|
||||
char buff[32];
|
||||
int c;
|
||||
char *errmsg = "expecting ";
|
||||
const char *errmsg = "expecting ";
|
||||
|
||||
retry:
|
||||
while ( nread<4 ) {
|
||||
@@ -68,10 +68,10 @@ int Midifile_reader::readmt(char *s, int skip)
|
||||
goto retry;
|
||||
}
|
||||
err:
|
||||
#pragma warning(disable: 4996) // strcpy is safe since strings have known lengths
|
||||
//#pragma warning(disable: 4996) // strcpy is safe since strings have known lengths
|
||||
(void) strcpy(buff,errmsg);
|
||||
(void) strcat(buff,s);
|
||||
#pragma warning(default: 4996) // turn it back on
|
||||
//#pragma warning(default: 4996) // turn it back on
|
||||
mferror(buff);
|
||||
return(0);
|
||||
}
|
||||
@@ -257,9 +257,9 @@ void Midifile_reader::readtrack()
|
||||
void Midifile_reader::badbyte(int c)
|
||||
{
|
||||
char buff[32];
|
||||
#pragma warning(disable: 4996) // safe in this case
|
||||
//#pragma warning(disable: 4996) // safe in this case
|
||||
(void) sprintf(buff,"unexpected byte: 0x%02x",c);
|
||||
#pragma warning(default: 4996)
|
||||
//#pragma warning(default: 4996)
|
||||
mferror(buff);
|
||||
}
|
||||
|
||||
@@ -420,6 +420,11 @@ void Midifile_reader::mferror(char *s)
|
||||
midifile_error = 1;
|
||||
}
|
||||
|
||||
void Midifile_reader::mferror(const char *s)
|
||||
{
|
||||
mferror(const_cast<char *>(s));
|
||||
}
|
||||
|
||||
/* The code below allows collection of a system exclusive message of */
|
||||
/* arbitrary length. The Msgbuff is expanded as necessary. The only */
|
||||
/* visible data/routines are msginit(), msgadd(), msg(), msgleng(). */
|
||||
|
||||
@@ -81,10 +81,11 @@ private:
|
||||
int egetc();
|
||||
int msgleng();
|
||||
|
||||
int readmt(char*,int);
|
||||
int readmt(const char*,int);
|
||||
long to32bit(int,int,int,int);
|
||||
int to16bit(int,int);
|
||||
void mferror(char *);
|
||||
void mferror(const char *);
|
||||
void badbyte(int);
|
||||
void metaevent(int);
|
||||
void msgadd(int);
|
||||
|
||||
Reference in New Issue
Block a user