📄 track_smf.c
字号:
/* * track_smf.cc * Copyright (C) 1998-2000 SAKAI Katsuya * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdio.h> // #include <iostream.h>#include <sys/types.h>#include "config.h"#include "extern.h"#include "smf.h"#include "defines.h"#include "midievdefs.h"u_long SMF_Chunk::ReadVarLen(){ register int value; if((value=Data[Index])&0x80) { value &= 0x7F; do { Index++; if (Length<=Index) return 0; value = (value<<7) + (Data[Index]&0x7F); } while(Data[Index]&0x80); } Index++; return value;}u_long SMF_Chunk::ReadLen(int len){ register int value; value = Data[Index++]; while(--len) value = (value<<8) + Data[Index++]; return value;}void SMF_Track::init(){ Port = 0; Index = 0; Tick = ReadVarLen(); for(int i=0;i<16;i++) LocalLastStatus[i]=0;}int SMF_Track::playaEvent(){ u_char nextevent; u_long len; int rtn=0; #ifdef SHOW_EVENT cout << dec << "Tick:" << Tick << " Track:" << Number;#endif if(!(EVENT&0x80)) { #ifdef SHOW_EVENT cout << " (rs)";#endif nextevent = LocalLastStatus[Port]; } else { LocalLastStatus[Port] = nextevent = EVENT; Index++; } # ifdef SHOW_EVENT cout << ' ' << hex << (int)nextevent << ' ';# endif switch (nextevent&0xf0) { case MIDI_NOTEOFF: case MIDI_NOTEON: case MIDI_KEY_PRESSURE: case MIDI_CTL_CHANGE: case MIDI_PITCH_BEND: if (Length<Index+1) {#ifdef SHOW_INFO cout << "data error" << endl;#endif return -2; } aSequencer->midiEvent2(Port, nextevent, Data[Index], Data[Index+1]);#ifdef SHOW_EVENT cout << (int)Data[Index] << ' ' << (int)Data[Index+1] << ' ';#endif Index += 2; break; case MIDI_PGM_CHANGE: case MIDI_CHN_PRESSURE: if (Length<Index) {#ifdef SHOW_INFO cout << "data error2" << endl;#endif return -2; } aSequencer->midiEvent1(Port, nextevent, Data[Index]);#ifdef SHOW_EVENT cout << (int)Data[Index] << ' ';#endif Index++; break; case MIDI_SYSTEM_PREFIX: if(nextevent==META_EVENT) { u_char MetaType; MetaType = Data[Index++]; len = ReadVarLen(); #ifdef SHOW_INFO cout << "len=" << len << " ";#endif if (Length<Index+len) {#ifdef SHOW_INFO cout << "data error 3: Length=" << Length << ", Index=" << Index << endl;#endif return -2; } switch(MetaType) { case META_TEMPO: if(len!=3) {# ifdef SHOW_EVENT cout << "invalid tempo value" << endl;# endif ReadLen(len); } else { // *Tempo = ReadLen(3); aSequencer->set_tempo (ReadLen (3));# ifdef SHOW_EVENT cout << "tempo:" << dec << aSequencer->show_tempo() << hex << ' ';# endif } break; case META_PORT_CHANGE: if(len!=1) { ReadLen(len);# ifdef SHOW_EVENT cout << "invalid port change event" << endl;# endif } else { Port = ReadLen(1);# ifdef SHOW_EVENT cout << "port : " << (int)Port << ' '; # endif } break; case META_TRACKEND: Tick=~0;# ifdef SHOW_EVENT cout << "End of Track" << endl;# endif return -1; break; default:# ifdef SHOW_EVENT cout << "Meta Event ";# endif u_int i; char *metadata = new char [len]; for (i=0;i<len;i++) metadata[i] = Data[Index++]; aSequencer->metaEvent (MetaType, len, metadata); delete [] metadata; // Index += len; break; } } else // exclusive message { u_char ex[512]; int exlen=0;#ifdef RUNNING_ST aSequencer->clearStatus(Port);#endif len = ReadVarLen(); ex[exlen++] = nextevent; for(u_long i=0;i<len;i++) {#ifdef SHOW_EVENT cout << (int)Data[Index] << ' ';#endif ex[exlen++] = Data[Index++]; } aSequencer->send_exclusive (Port, ex, exlen); } break; default: printf("unknown status\n"); // cout << "unknown status" << endl; return -3; break; } len = ReadVarLen (); Tick += len; # ifdef SHOW_EVENT cout << "\tNextTick:" << Tick << endl;# endif if (Length<=Index) {#ifdef SHOW_INFO cout << "data error 4" << endl;#endif return -2; } if (len==0L) rtn = playaEvent (); return rtn;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -