📄 player_r36.c
字号:
/* * player_r36.cc * Copyright (C) 1998,1999 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 <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <string.h>#include <stdio.h>#include "config.h"#include "sequencer.h"#include "player.h"#include "defines.h"#include "extern.h"R36_Player::R36_Player(){ Track=NULL;}R36_Player::~R36_Player(){ clear();}//介袋肋年void R36_Player::init(){ u_long n; Event *NextEvent; for(n=0;n<Header.NumOfTrack;n++) { Track[n].init(&Header, &Exclusive, &Noff_Queue); NextEvent = new Event; NextEvent->Type = EV_NORMAL; NextEvent->Track = n; NextEvent->Time = Track[n].tick(); Queue.store(NextEvent); }}//遍琳メインル〖チンvoid R36_Player::play(){ Event *Next; if(Noff_Queue.NextTime()>Queue.NextTime()) { Next = Queue.retrieve(); } else { Next = Noff_Queue.retrieve(); } aSequencer->startTimer(); while(Next!=NULL && stop==FALSE && next==FALSE) { aSequencer->waitTime(Next->Time); if(Next->Type == EV_NOTE_OFF) { NoteOff(Next); delete Next; } else { if(Track[Next->Track].playaEvent()<0) { delete Next; } else { Next->Time = Track[Next->Track].tick(); Queue.store(Next); } } if(Noff_Queue.NextTime()>Queue.NextTime()) { Next = Queue.retrieve(); } else { Next = Noff_Queue.retrieve(); } } if(stop==TRUE || next==TRUE) { aSequencer->reset(); aSequencer->seqbuf_clear(); AllNoteOff(); while((Next=Queue.retrieve())!=NULL) delete Next; next=FALSE; } aSequencer->stopTimer(); if(stop==TRUE) {#ifdef SHOW_INFO cout << "stop." << endl;#endif aSequencer->close(); exit(1); }}void R36_Player::AllNoteOff(){ Event *off; while((off=Noff_Queue.retrieve())!=NULL) NoteOff(off); aSequencer->seqbuf_dump(); for(u_long n=0;n<Header.NumOfTrack;n++) { Track[n].AllNoteOff(); } }void R36_Player::NoteOff(Event *off){ (Track[off->Track].N_ON[off->Note])--;# ifdef SHOW_EVENT cout << "Tick:" << dec << off->Time << " Channel:" <<(int)off->Channel+1 << " Note:" << hex << (int)off->Note << " NoteOff(" << (int) Track[off->Track].N_ON[off->Note] << ')' ;# endif if(Track[off->Track].N_ON[off->Note] == 0) { aSequencer->midiEvent2(off->Port, 0x90|off->Channel, off->Note, 0x0); }#ifdef SHOW_EVENT else if(Track[off->Track].N_ON[off->Note] < 0) { Track[off->Track].N_ON[off->Note]=0; cout << "- BUG!?" << endl; } else { cout << " - ingore"; } cout << endl;#endif}void R36_Player::clear(){ if(Track!=NULL) { delete [] Track; Track=NULL; }}/* load 喇根 : 0 error: -1: RCPfileオ〖プンエラ〖 -2: unknown format -3: file broken -4: memory allocation error*/int R36_Player::load(char *filename){ int songfd; clear(); if (filename==NULL) songfd = fileno(stdin); else songfd = open(filename, O_RDONLY); if(songfd<0) { return -1; } // ヘッダの矢机误チェック read(songfd, Header.Text, 32); u_long n;#ifdef SHOW_HEADER for(n=0;n<28;n++) { cout << Header.Text[n]; } cout << endl;#endif if(strncmp(Header.Text, "RCM-PC98V2.0(C)COME ON MUSIC", 28)!=0) { if (filename==NULL) close(songfd); return -2; } // ヘッダデ〖タ粕み哈み char buffer[80]; int timebase; read(songfd, Header.Title, 64); read(songfd, Header.Memo, 336); read(songfd, buffer, 16 ); read(songfd, buffer, 1 ); timebase = buffer[0]&0xff; read(songfd, buffer, 1 ); Header.Tempo = buffer[0]&0xff; aSequencer->set_tempo (60*1000000/Header.Tempo); read(songfd, Header.TimeSignature, 2); read(songfd, &Header.Key, 1); read(songfd, &Header.PlayBIAS, 1); read(songfd, Header.CM6file, 14); read(songfd, Header.GSDfile, 14); read(songfd, buffer, 4); read(songfd, buffer, 1 ); Header.NumOfTrack = buffer[0]&0xff; read(songfd, buffer, 1); aSequencer->set_timebase (timebase + buffer[0]*256); read(songfd, buffer, 30); if(Header.NumOfTrack==0) Header.NumOfTrack=18;#ifdef SHOW_HEADER cout << endl << "Title :" << (u_int)Header.Title << endl << "Timebase:" << (u_int)aSequencer->show_timebase () << endl << "Tempo :" << Header.Tempo << endl << "BIAS :" << (int)Header.PlayBIAS << endl << "TimeSignature:" << (int) Header.TimeSignature[0] << "/" << (int) Header.TimeSignature[1] << endl << "Track :" << (u_int)Header.NumOfTrack << endl;#endif#if defined(SHOW_RYTHM) || defined(SHOW_USEREX) || defined(SHOW_THEADER) int name;#endif // リズム不富年盗の粕み哈み for(n=0;n<32;n++) { read(songfd, Rythm.Name[n], 14); read(songfd, &Rythm.Key[n], 1); read(songfd, &Rythm.GateTime[n], 1);#ifdef SHOW_RYTHM cout << "RythmDefine read:"; for(name=0;name<14;name++) cout << Rythm.Name[n][name]; cout << " key:" << (int)Rythm.Key[n] << " GT:" << (int)Rythm.GateTime[n] << endl; #endif } // ユ〖ザエクスクル〖シブ年盗の粕み哈み for(n=0;n<8;n++) { read(songfd, Exclusive.Memo[n], 24); if (read(songfd, Exclusive.Data[n], 24)<24) { if (filename==NULL) close (songfd); return -3; }#ifdef SHOW_USEREX cout << "UserExclusiveDefine read :"; for(name=0;name<24;name++) cout << Exclusive.Memo[n][name]; cout << endl; #endif } Track = new R36_Track [Header.NumOfTrack]; if(!Track) { if (filename==NULL) close(songfd); return -4; } // トラックデ〖タの粕み哈み for(n=0;n<Header.NumOfTrack;n++) { read(songfd, buffer, 2); Track[n].DataLength =(u_long) (buffer[1]&0xff)<<8 | (buffer[0]&0xff); read(songfd, &Track[n].Number, 1); read(songfd, &Track[n].RythmFlag, 1); read(songfd, &Track[n].Channel, 1); read(songfd, &Track[n].Key_Bias, 1); read(songfd, &Track[n].ST_Bias, 1); read(songfd, &Track[n].Mode, 1); if (read(songfd, Track[n].Comment, 36)<36) { Header.NumOfTrack = n; continue; } if(Track[n].Number!=n+1) { // cout << "warning: broken file?" << endl; Track[n].Number=n+1; }#ifdef SHOW_THEADER cout << endl << "Ch+Dev(0xff:off):" << hex << (int)Track[n].Channel << dec;#endif if(Track[n].Channel==0xff) Track[n].Mute=TRUE; Track[n].Port = (Track[n].Channel&0xf0)>>4; Track[n].Channel = Track[n].Channel & 0xf; Track[n].Version = V_RCP;#ifdef SHOW_THEADER cout << endl <<"Track :" << (int)Track[n].Number << endl << "RythmFlag:" << (int)Track[n].RythmFlag << endl; if(Track[n].Mute==FALSE) { cout << "Port:" << (int)Track[n].Port << endl << "Channel:" << (int)Track[n].Channel+1 << endl; } else { cout << "Port: OFF" << endl << "Channel: OFF" << endl; } cout << "DataLength:" << Track[n].DataLength << endl << "Key+:" << (int)Track[n].Key_Bias << endl << "ST:" << (int)Track[n].ST_Bias << endl << "Mode:" << (int)Track[n].Mode << endl << endl << "Comment:"; for(name=0;name<36;name++) cout << Track[n].Comment[name]; cout << endl;#endif Track[n].Data = new u_char [ Track[n].DataLength-44 ]; if(!(Track[n].Data)) { delete [] Track; Track = NULL; if (filename==NULL) close(songfd); return -4; } if (read (songfd, Track[n].Data, Track[n].DataLength-44) <Track[n].DataLength-44) { if (filename==NULL) close (songfd); return -3; } } if (filename==NULL) close (songfd); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -