📄 player_smf.c
字号:
/* * player_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 <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 "smf.h"#include "player.h"#include "queue.h"#include "extern.h"#include "defines.h"SMF_Player::SMF_Player(){ Track=NULL;}SMF_Player::~SMF_Player(){ clear();}void SMF_Player::init(){ int n; Event *NextEvent; for(n=0;n<Header.NumOfTrack;n++) { if(strncmp(Track[n].Type, "MTrk", 4)==0) { Track[n].init(); NextEvent = new Event; NextEvent->Track = n; NextEvent->Time = Track[n].tick(); Queue.store(NextEvent); } } aSequencer->set_tempo (60*1000000/120); // Default Tempo 120bpm}//遍琳メインル〖チンvoid SMF_Player::play(){ Event *Next; aSequencer->startTimer(); while((Next=Queue.retrieve())!=NULL && stop==FALSE && next==FALSE) { aSequencer->waitTime (Next->Time); if(Track[Next->Track].playaEvent()<0) { delete Next; } else { Next->Time = Track[Next->Track].tick(); Queue.store(Next); } } 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(); usleep (1000); exit(0); }}void SMF_Player::AllNoteOff(){ int devnum, m; devnum = aSequencer->NumOfDevice(); for(m=0;m<devnum;m++) aSequencer->AllNoteOff(m);}void SMF_Player::clear(){ if(Track!=NULL) { delete [] Track; Track=NULL; }}/* error: -1: fileオ〖プンエラ〖 -2: unknown format -3: file broken -4: memory allocation error*/int SMF_Player::load(char *filename){ int songfd; int n; clear(); if (filename==NULL) songfd = fileno(stdin); else songfd = open(filename, O_RDONLY); if(songfd<0) { return -1; } // ヘッダの矢机误チェック read(songfd, Header.Type, 4); if(strncmp(Header.Type, "MThd", 4)!=0) { lseek(songfd, 128L, SEEK_SET); // Mac binary 滦忽 read(songfd, Header.Type, 4); if(strncmp(Header.Type, "MThd", 4)!=0) { if (filename==NULL) close(songfd); return -2; } } // ヘッダデ〖タ粕み哈み u_char buffer[8]; read(songfd, buffer, 4); Header.Length = (buffer[0]<<24) + (buffer[1]<<16) + (buffer[2]<<8) + buffer[3];#ifdef SHOW_HEADER cout << "header length:" << Header.Length << endl;#endif if(Header.Length!=6) { if (filename==NULL) close (songfd); return -2; } read(songfd, buffer, 2); Header.Format = (buffer[0]<<8) + buffer[1]; if(Header.Format > 1) { if (filename==NULL) close (songfd); return -2; } read(songfd, buffer, 2); Header.NumOfTrack = (buffer[0]<<8) + buffer[1]; read(songfd, buffer, 2); aSequencer->set_timebase ((buffer[0]<<8) + buffer[1]); #ifdef SHOW_HEADER cout << endl << "Format :" << (int)Header.Format << endl << "Track :" << Header.NumOfTrack << endl << "Timebase:" << aSequencer->show_timebase () << endl;#endif Track = new SMF_Track [Header.NumOfTrack]; if(!Track) { if (filename==NULL) close (songfd); return -4; } // トラックデ〖タの粕み哈み for(n=0;n<Header.NumOfTrack;n++) { Track[n].Number = n; if (read(songfd, Track[n].Type, 4)!=4) { Header.NumOfTrack=n-1; break; } if (strncmp (Track[n].Type, "MTrk", 4)) { Header.NumOfTrack=n-1; break; } read(songfd, buffer, 4); Track[n].Length = (buffer[0]<<24) + (buffer[1]<<16) + (buffer[2]<<8) + buffer[3]; #ifdef SHOW_HEADER cout << endl; for(int i=0;i<4;i++) cout << Track[n].Type[i]; cout << endl << "Track :" << Track[n].Number << endl << "DataLength:" << Track[n].Length << endl;#endif Track[n].Data = new u_char [ Track[n].Length ]; if(!(Track[n].Data)) { if (filename==NULL) close (songfd); return -4; } if(read(songfd, Track[n].Data, Track[n].Length)<(long)Track[n].Length) { if (filename==NULL) close (songfd); return -3; } }#ifdef SHOW_HEADER cout << endl << "valid track:" << Header.NumOfTrack << endl;#endif if (filename==NULL) close (songfd); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -