/* $Id: hmiplay.c,v 1.2 2003/03/13 00:20:21 btb Exp $ */ /* * HMI midi playing routines by Jani Frilander * * External device support by Patrick McCarthy * * Ported to d1x/sdl_threads by Matthew Mueller * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "music.h" #include "cfile.h" #include //#define WANT_AWE32 1 #ifdef WANT_AWE32 #include #endif //#define WANT_MPU401 1 #ifdef WANT_MPU401 #define MIDI_MESSAGE2(a,b) { \ SEQ_MIDIOUT(synth_dev,a); \ SEQ_MIDIOUT(synth_dev,b); \ } #define MIDI_MESSAGE3(a,b,c) { \ SEQ_MIDIOUT(synth_dev,a); \ SEQ_MIDIOUT(synth_dev,b); \ SEQ_MIDIOUT(synth_dev,c); \ } #endif SEQ_DEFINEBUF(1024); int drumflag = 1<<9; int seqfd; int synth_dev; int program[16]; int stop; double volume=1; int ipc_queue_id = -1; struct msgbuf *snd; SDL_Thread *player_thread=NULL; Voice_info *voices; unsigned char *data=NULL; struct synth_info card_info; void seqbuf_dump() { if (_seqbufptr) { if (write(seqfd, _seqbuf, _seqbufptr) == -1) { perror ("Error writing sequencer device"); SDL_KillThread(player_thread); } } _seqbufptr = 0; } void my_quit() { // printf("goodbye\n");//##### // exit(0); } int seq_init() { int nrmidis,nrsynths,i; if ((seqfd = open(SEQ_DEV, O_WRONLY, 0)) < 0) { perror ("Error opening sequencer device"); return (-1); } if (ioctl(seqfd, SNDCTL_SEQ_NRSYNTHS, &nrsynths) == -1) { perror ("There is no soundcard"); return (-1); } if (ioctl(seqfd, SNDCTL_SEQ_NRMIDIS, &nrmidis) == -1) { perror ("There is no soundcard"); return (-1); } if(nrsynths < 1 && nrmidis < 1) { printf("No synth or midi device!\n"); return -1; } synth_dev = 0; //Check if we have wavetable synth device for (i=0; i < nrsynths; i++) { card_info.device = i; if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &card_info) == -1) { perror("cannot get info on soundcard"); return (-1); } if (card_info.synth_type == SYNTH_TYPE_SAMPLE) { synth_dev = i; break; } } #ifdef WANT_AWE32 for (i=0; i < nrsynths; i++) { card_info.device = i; if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &card_info) == -1) { perror("cannot get info on soundcard"); return (-1); } if (card_info.synth_type==SYNTH_TYPE_SAMPLE &&card_info.synth_subtype==SAMPLE_TYPE_AWE32) { synth_dev = i; break; } } #endif #ifdef WANT_MPU401 for (i=0; i < nrmidis; i++) { struct midi_info cinfo; cinfo.device = i; if (ioctl(seqfd, SNDCTL_MIDI_INFO, &cinfo) == -1) { perror("cannot get info on soundcard"); return (-1); } // Just take first available for now. card_info.synth_type=SYNTH_TYPE_MIDI; card_info.device=i; synth_dev=i; break; } if (card_info.synth_type!=SYNTH_TYPE_MIDI) { #endif card_info.device = synth_dev; if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &card_info) == -1) { perror("cannot get info on soundcard"); return (-1); } #ifdef WANT_MPU401 } if (card_info.synth_type==SYNTH_TYPE_MIDI) { // Insert some sort of midi reset here later. } else #endif #ifdef WANT_AWE32 if (card_info.synth_type == SYNTH_TYPE_SAMPLE && card_info.synth_subtype == SAMPLE_TYPE_AWE32) { AWE_SET_CHANNEL_MODE(synth_dev,1); AWE_DRUM_CHANNELS(synth_dev,drumflag); } else #endif { voices = malloc(sizeof(Voice_info)*card_info.nr_voices); for (i=0;imtype=1; player_thread=SDL_CreateThread(play_hmi, NULL); // player_pid = play_hmi(); } if (strlen(message) < 16) { sprintf(snd->mtext,"%s",message); msgsnd(ipc_queue_id,snd,16,0); } } void kill_ipc() { // send_ipc("q"); // kill(player_pid,SIGTERM); msgctl( ipc_queue_id, IPC_RMID, 0); free(snd); ipc_queue_id = -1; // player_pid = 0; } int do_ipc(int qid, struct msgbuf *buf, int flags) { int ipc_read; CFILE *fptr; int l=0; ipc_read = msgrcv(qid,buf,16,0,flags | MSG_NOERROR); switch (ipc_read) { case -1: if (errno == ENOMSG) break; perror("IPC trouble"); break; case 0: break; default: printf ("do_ipc %s\n", buf->mtext);//##########3 switch (buf->mtext[0]) { case 'v': volume=(double) ((double) buf->mtext[0]/127.0); break; case 'p': fptr=cfopen((buf->mtext+1),"rb"); if(fptr != NULL) { l = cfilelength(fptr); data=realloc(data,(size_t) l); cfread(data, l, 1, fptr); cfclose(fptr); printf ("good. fpr=%p l=%i data=%p\n", fptr, l, data);//##########3 } stop = 0; break; case 's': stop = 2; break; case 'q': // SDL_KillThread(player_thread); break; } } return ipc_read; } void play_hmi (void * arg) { int i; int pos = 0x308; int n_chunks = 0; int low_dtime; int low_chunk; int csec; // pid_t loc_pid; int qid; int ipc_read = 0; int k=0; struct msgbuf *rcv; Track_info *t_info; printf ("play_hmi\n");//######### stop = 0; ipc_read=0; // loc_pid=fork(); /* switch (loc_pid) { case 0: break; case -1: return -1; default: atexit(kill_ipc); return loc_pid; }*/ // signal(SIGTERM, my_quit); rcv=malloc(sizeof(long) + 16); rcv->mtype=1; rcv->mtext[0]='0'; sleep(2); qid=msgget ((key_t) ('l'<<24) | ('d'<<16) | ('e'<<8) | 's', 0660); if(qid == -1) { return; } do { ipc_read=do_ipc(qid,rcv,0); } while(rcv->mtext[0] != 'p'); stop=0; rcv->mtext[0] = '0'; seq_init(); n_chunks=data[0x30]; t_info = malloc(sizeof(Track_info)*n_chunks); while(1) { for(i=0;i 0) && (rcv->mtext[0]=='p')) { n_chunks=data[0x30]; t_info = realloc(t_info,sizeof(Track_info)*n_chunks); stop = 1; rcv->mtext[0] = '0'; stop_all(); } } while(!stop); SEQ_STOP_TIMER(); if( stop == 2) { stop_all(); do { ipc_read=do_ipc(qid,rcv,0); } while(rcv->mtext[0] != 'p'); rcv->mtext[0] = '0'; n_chunks=data[0x30]; t_info = realloc(t_info,sizeof(Track_info)*n_chunks); stop = 0; } pos=0x308; } free(data); free(t_info); free(rcv); } void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) { char buf[128]; sprintf(buf,"p%s",filename); send_ipc(buf); } void digi_set_midi_volume( int mvolume ) { char buf[128]; sprintf(buf,"v%i",mvolume); send_ipc(buf); }