From dfe289850f068f19ba4a83ab4e7e22a7e09c13c9 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sat, 26 Jan 2013 13:17:21 -0600 Subject: Rename a number of libraries and executables to avoid conflicts with KDE4 --- libkmid/CMakeLists.txt | 51 --- libkmid/Makefile.am | 24 -- libkmid/alsaout.cc | 571 --------------------------- libkmid/alsaout.h | 231 ----------- libkmid/awe_sup.h | 50 --- libkmid/configure.in.in | 128 ------- libkmid/dattypes.cc | 110 ------ libkmid/dattypes.h | 55 --- libkmid/deviceman.cc | 830 --------------------------------------- libkmid/deviceman.h | 537 -------------------------- libkmid/fmout.cc | 354 ----------------- libkmid/fmout.h | 155 -------- libkmid/gusout.cc | 691 --------------------------------- libkmid/gusout.h | 180 --------- libkmid/gusvoices.h | 286 -------------- libkmid/libkmid.cc | 263 ------------- libkmid/libkmid.h | 226 ----------- libkmid/midfile.cc | 460 ---------------------- libkmid/midfile.h | 99 ----- libkmid/midimapper.cc | 456 ---------------------- libkmid/midimapper.h | 210 ---------- libkmid/midiout.cc | 301 --------------- libkmid/midiout.h | 251 ------------ libkmid/midispec.h | 60 --- libkmid/midistat.cc | 115 ------ libkmid/midistat.h | 143 ------- libkmid/mt32togm.cc | 18 - libkmid/mt32togm.h | 31 -- libkmid/notearray.cc | 122 ------ libkmid/notearray.h | 145 ------- libkmid/player.cc | 959 ---------------------------------------------- libkmid/player.h | 396 ------------------- libkmid/sndcard.h | 88 ----- libkmid/synthout.cc | 211 ---------- libkmid/synthout.h | 118 ------ libkmid/tests/Kathzy.mid | Bin 9083 -> 0 bytes libkmid/tests/Makefile.am | 14 - libkmid/tests/apitest.cc | 25 -- libkmid/tests/ctest.c | 54 --- libkmid/tests/notesoff.cc | 24 -- libkmid/track.cc | 566 --------------------------- libkmid/track.h | 237 ------------ libkmid/voiceman.cc | 279 -------------- libkmid/voiceman.h | 172 --------- 44 files changed, 10296 deletions(-) delete mode 100644 libkmid/CMakeLists.txt delete mode 100644 libkmid/Makefile.am delete mode 100644 libkmid/alsaout.cc delete mode 100644 libkmid/alsaout.h delete mode 100644 libkmid/awe_sup.h delete mode 100644 libkmid/configure.in.in delete mode 100644 libkmid/dattypes.cc delete mode 100644 libkmid/dattypes.h delete mode 100644 libkmid/deviceman.cc delete mode 100644 libkmid/deviceman.h delete mode 100644 libkmid/fmout.cc delete mode 100644 libkmid/fmout.h delete mode 100644 libkmid/gusout.cc delete mode 100644 libkmid/gusout.h delete mode 100644 libkmid/gusvoices.h delete mode 100644 libkmid/libkmid.cc delete mode 100644 libkmid/libkmid.h delete mode 100644 libkmid/midfile.cc delete mode 100644 libkmid/midfile.h delete mode 100644 libkmid/midimapper.cc delete mode 100644 libkmid/midimapper.h delete mode 100644 libkmid/midiout.cc delete mode 100644 libkmid/midiout.h delete mode 100644 libkmid/midispec.h delete mode 100644 libkmid/midistat.cc delete mode 100644 libkmid/midistat.h delete mode 100644 libkmid/mt32togm.cc delete mode 100644 libkmid/mt32togm.h delete mode 100644 libkmid/notearray.cc delete mode 100644 libkmid/notearray.h delete mode 100644 libkmid/player.cc delete mode 100644 libkmid/player.h delete mode 100644 libkmid/sndcard.h delete mode 100644 libkmid/synthout.cc delete mode 100644 libkmid/synthout.h delete mode 100644 libkmid/tests/Kathzy.mid delete mode 100644 libkmid/tests/Makefile.am delete mode 100644 libkmid/tests/apitest.cc delete mode 100644 libkmid/tests/ctest.c delete mode 100644 libkmid/tests/notesoff.cc delete mode 100644 libkmid/track.cc delete mode 100644 libkmid/track.h delete mode 100644 libkmid/voiceman.cc delete mode 100644 libkmid/voiceman.h (limited to 'libkmid') diff --git a/libkmid/CMakeLists.txt b/libkmid/CMakeLists.txt deleted file mode 100644 index d0bc35d84..000000000 --- a/libkmid/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -################################################# -# -# (C) 2010 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${TQT_INCLUDE_DIRS} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/tdecore - ${CMAKE_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/tdecore -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -##### headers ################################### - -install( FILES - midiout.h player.h track.h midimapper.h midfile.h - dattypes.h midistat.h deviceman.h synthout.h - fmout.h gusout.h alsaout.h voiceman.h notearray.h - mt32togm.h midispec.h libkmid.h - DESTINATION ${INCLUDE_INSTALL_DIR}/libkmid ) - - -##### kmid ###################################### - -set( target kmid ) - -set( ${target}_SRCS - midiout.cc player.cc track.cc midimapper.cc - midfile.cc dattypes.cc midistat.cc deviceman.cc - synthout.cc fmout.cc gusout.cc alsaout.cc voiceman.cc - mt32togm.cc notearray.cc libkmid.cc -) - -tde_add_library( ${target} SHARED - SOURCES ${${target}_SRCS} - VERSION 0.0.95 - LINK tdecore-shared ${ALSA_LIBRARIES} - DESTINATION ${LIB_INSTALL_DIR} -) diff --git a/libkmid/Makefile.am b/libkmid/Makefile.am deleted file mode 100644 index 507b7381e..000000000 --- a/libkmid/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ - -INCLUDES = -I$(srcdir)/.. $(all_includes) - -# For the future: examine if condensing the tons of *_LDFLAGS variables -# into $(all_libraries) isn't better -AM_LDFLAGS = $(LDFLAGS_AS_NEEDED) $(LDFLAGS_NEW_DTAGS) - -libkmidincludedir = $(includedir)/libkmid -libkmidinclude_HEADERS = midiout.h player.h track.h midimapper.h \ - midfile.h dattypes.h midistat.h deviceman.h synthout.h \ - fmout.h gusout.h alsaout.h voiceman.h notearray.h mt32togm.h \ - midispec.h libkmid.h - -lib_LTLIBRARIES = libkmid.la -libkmid_la_SOURCES = midiout.cc player.cc track.cc midimapper.cc \ - midfile.cc dattypes.cc midistat.cc deviceman.cc synthout.cc \ - fmout.cc gusout.cc alsaout.cc voiceman.cc mt32togm.cc notearray.cc \ - libkmid.cc - -libkmid_la_LDFLAGS = $(KDE_MT_LDFLAGS) -version-info 0:95 -no-undefined -libkmid_la_LIBADD = $(LIBASOUND) ../tdecore/libtdecore.la $(LIB_QT) - -DOXYGEN_REFERENCES = tdecore -include ../admin/Doxyfile.am diff --git a/libkmid/alsaout.cc b/libkmid/alsaout.cc deleted file mode 100644 index 4c7f48f4e..000000000 --- a/libkmid/alsaout.cc +++ /dev/null @@ -1,571 +0,0 @@ -/************************************************************************** - - alsaout.cc - class AlsaOut which represents an alsa client/port pair - This file is part of LibKMid 0.9.5 - Copyright (C) 2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "alsaout.h" -#include -#include -#include -#include "sndcard.h" -#include -#include -#include -#include -#include "midispec.h" - - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_ALSA_ASOUNDLIB_H -# include -#elif defined(HAVE_SYS_ASOUNDLIB_H) -# include -#endif - -#ifdef HAVE_LIBASOUND2 -# define HAVE_ALSA_SEQ 1 -# define snd_seq_flush_output(x) snd_seq_drain_output(x) -#elif defined(HAVE_LIBASOUND) -# define HAVE_ALSA_SEQ 1 -# include -#endif - - -SEQ_USE_EXTBUF(); - -class AlsaOut::AlsaOutPrivate -{ -public: -#ifdef HAVE_ALSA_SEQ - AlsaOutPrivate(int _client, int _port, const char *cname,const char *pname) - { - handle=0L; - src=tgt=0L; - queue=0; - tPCN=1; - tgtclient=_client; - tgtport=_port; - tgtname=new char[strlen(cname)+strlen(pname)+3]; - strcpy(tgtname, cname); - strcat(tgtname, " "); - strcat(tgtname, pname); - ev=new snd_seq_event_t; - timerStarted=false; - } -#else - AlsaOutPrivate(int, int, const char *,const char *) - { - } -#endif - - ~AlsaOutPrivate() - { -#ifdef HAVE_ALSA_SEQ - delete ev; - delete tgtname; -#endif - } - -#ifdef HAVE_ALSA_SEQ - snd_seq_t *handle; - int client; - int queue; - snd_seq_addr_t *src; - snd_seq_addr_t *tgt; - - snd_seq_event_t *ev; - int tPCN; - - int tgtclient; - int tgtport; - char *tgtname; - - bool timerStarted; - -#endif -}; - -AlsaOut::AlsaOut(int d,int _client, int _port, const char *cname,const char *pname) : MidiOut (d) -{ - di = new AlsaOutPrivate( _client, _port, cname, pname); - seqfd = 0; - devicetype=KMID_ALSA; - device= d; - - volumepercentage=100; -#ifdef HAVE_ALSA_SEQ -// printf("%d %d %d (%s)\n",device, di->tgtclient, di->tgtport, di->tgtname); -#endif - - _ok=1; -} - -AlsaOut::~AlsaOut() -{ - closeDev(); - delete di; -} - -void AlsaOut::openDev (int) -{ -#ifndef HAVE_ALSA_SEQ - return; -#else - _ok=1; -#ifdef HAVE_LIBASOUND2 - if (snd_seq_open(&di->handle, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) - fprintf(stderr, "Couldn't open sequencer: %s", snd_strerror(errno)); -#else - if (snd_seq_open(&di->handle, SND_SEQ_OPEN) < 0) - fprintf(stderr, "Couldn't open sequencer: %s", snd_strerror(errno)); -#endif - - di->queue = snd_seq_alloc_queue(di->handle); - if (di->queue < 0) {fprintf(stderr, "Couldn't allocate queue"); return; }; - di->client = snd_seq_client_id(di->handle); - if (di->client < 0) {fprintf(stderr, "Couldn't get client id"); return; }; - di->tgt = new snd_seq_addr_t; - di->tgt->client=di->tgtclient; - di->tgt->port=di->tgtport; - - di->src = new snd_seq_addr_t; - di->src->client = di->client; - int port = snd_seq_create_simple_port(di->handle, NULL, - SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE - | SND_SEQ_PORT_CAP_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC); - if ( port < 0 ) - { - delete di->src; - delete di->tgt; - di->src=0; - di->tgt=0; - _ok=0; - time=0; - snd_seq_free_queue(di->handle, di->queue); - snd_seq_close(di->handle); - fprintf(stderr, "Cannot connect to %d:%d\n",di->tgtclient,di->tgtport); - return; - } - di->src->port = port; - - - int r=snd_seq_connect_to(di->handle, di->src->port, di->tgt->client, di->tgt->port); - if (r < 0) { _ok=0; fprintf(stderr, "Cannot connect to %d:%d\n",di->tgtclient,di->tgtport); } - time=0; -#endif -} - -void AlsaOut::closeDev (void) -{ - if (!ok()) return; -#ifdef HAVE_ALSA_SEQ - if (di->handle) - { - if (di->src) - { - snd_seq_delete_simple_port(di->handle,di->src->port); - delete di->src; - di->src=0; - } - if (di->tgt) - { - delete di->tgt; - di->tgt=0; - } - if (di->queue) - { - snd_seq_free_queue(di->handle, di->queue); - snd_seq_close(di->handle); - } - di->handle=0; - } - -#endif -} - -void AlsaOut::initDev (void) -{ -#ifdef HAVE_ALSA_SEQ - int chn; - if (!ok()) return; - uchar gm_reset[5]={0x7e, 0x7f, 0x09, 0x01, 0xf7}; - sysex(gm_reset, sizeof(gm_reset)); - for (chn=0;chn<16;chn++) - { - chnmute[chn]=0; - if (chn!=9) chnPatchChange(chn,0); - chnPressure(chn,64); - chnPitchBender(chn, 0x00, 0x40); - chnController(chn, CTL_MAIN_VOLUME,110*volumepercentage); - chnController(chn, CTL_EXT_EFF_DEPTH, 0); - chnController(chn, CTL_CHORUS_DEPTH, 0); - chnController(chn, 0x4a, 127); - } -#endif -} - -#ifdef HAVE_ALSA_SEQ -void AlsaOut::eventInit(snd_seq_event_t *ev) -{ - snd_seq_ev_clear(ev); - snd_seq_real_time_t tmp; - tmp.tv_sec=(time)/1000; - tmp.tv_nsec=(time%1000)*1000000; -// printf("time : %d %d %d\n",(int)time,(int)tmp.tv_sec, (int)tmp.tv_nsec); - if (!di->src) { fprintf(stderr,"AlsaOut::eventInit : no source\n"); return; } - ev->source = *di->src; - if (!di->tgt) { fprintf(stderr,"AlsaOut::eventInit : no target\n"); return; } - ev->dest = *di->tgt; - - snd_seq_ev_schedule_real(ev, di->queue, 0, &tmp); -} - -void AlsaOut::eventSend(snd_seq_event_t *ev) -{ - /*int err = */ snd_seq_event_output(di->handle, ev); -/* if (err < 0) - return; -*/ -//#ifndef SND_SEQ_IOCTL_GET_CLIENT_POOL - /* - * If this is not defined then block mode writes will not be - * working correctly. Therefore loop until all events are flushed - * out. - */ -/* err = 0; - do { - err = snd_seq_flush_output(di->handle); - if (err > 0) - usleep(2000); - } while (err > 0); - -#endif - - return ; -*/ -} - -void AlsaOut::timerEventSend(int type) -{ - snd_seq_event_t ev; - - ev.queue = di->queue; - ev.dest.client = SND_SEQ_CLIENT_SYSTEM; - ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER; - - ev.data.queue.queue = di->queue; - - ev.flags = SND_SEQ_TIME_STAMP_REAL | SND_SEQ_TIME_MODE_REL; - ev.time.time.tv_sec = 0; - ev.time.time.tv_nsec = 0; - - ev.type = type; - - snd_seq_event_output(di->handle, &ev); - snd_seq_flush_output(di->handle); -} - -#endif // HAVE_ALSA_SEQ - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::noteOn (uchar , uchar , uchar ) -{ -#else -void AlsaOut::noteOn (uchar chn, uchar note, uchar vel) -{ - if (vel==0) - { - noteOff(chn,note,vel); - } - else - { - eventInit(di->ev); - snd_seq_ev_set_noteon(di->ev,map->channel(chn), map->key(chn,chnpatch[chn],note), vel); - eventSend(di->ev); - } -#endif -#ifdef MIDIOUTDEBUG - printfdebug("Note ON >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::noteOff (uchar , uchar , uchar ) -{ -#else -void AlsaOut::noteOff (uchar chn, uchar note, uchar vel) -{ - eventInit(di->ev); - snd_seq_ev_set_noteoff(di->ev,map->channel(chn), map->key(chn,chnpatch[chn],note), vel); - eventSend(di->ev); -#endif -#ifdef MIDIOUTDEBUG - printfdebug("Note OFF >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::keyPressure (uchar , uchar , uchar ) -{ -#else -void AlsaOut::keyPressure (uchar chn, uchar note, uchar vel) -{ - eventInit(di->ev); - snd_seq_ev_set_keypress(di->ev,map->channel(chn), map->key(chn,chnpatch[chn],note), vel); - eventSend(di->ev); -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::chnPatchChange (uchar , uchar ) -{ -#else -void AlsaOut::chnPatchChange (uchar chn, uchar patch) -{ -#ifdef MIDIOUTDEBUG - printfdebug("PATCHCHANGE [%d->%d] %d -> %d\n", - chn,map->channel(chn),patch,map->patch(chn,patch)); -#endif - eventInit(di->ev); - snd_seq_ev_set_pgmchange(di->ev,map->channel(chn), map->patch(chn,patch)); - eventSend(di->ev); - chnpatch[chn]=patch; -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::chnPressure (uchar , uchar ) -{ -#else -void AlsaOut::chnPressure (uchar chn, uchar vel) -{ - eventInit(di->ev); - snd_seq_ev_set_chanpress(di->ev,map->channel(chn), vel); - eventSend(di->ev); - - chnpressure[chn]=vel; -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::chnPitchBender(uchar ,uchar , uchar ) -{ -#else -void AlsaOut::chnPitchBender(uchar chn,uchar lsb, uchar msb) -{ - map->pitchBender(chn,lsb,msb); - chnbender[chn]=((short)msb<<7) | (lsb & 0x7F); - chnbender[chn]=chnbender[chn]-0x2000; - - eventInit(di->ev); - snd_seq_ev_set_pitchbend(di->ev,map->channel(chn), chnbender[chn]); - eventSend(di->ev); -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::chnController (uchar , uchar , uchar ) -{ -#else -void AlsaOut::chnController (uchar chn, uchar ctl, uchar v) -{ - map->controller(chn,ctl,v); - if ((ctl==11)||(ctl==7)) - { - v=(v*volumepercentage)/100; - if (v>127) v=127; - } - - eventInit(di->ev); - snd_seq_ev_set_controller(di->ev,map->channel(chn), ctl, v); - eventSend(di->ev); - - chncontroller[chn][ctl]=v; -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::sysex(uchar *, ulong ) -{ -#else -void AlsaOut::sysex(uchar *data, ulong size) -{ - eventInit(di->ev); - snd_seq_ev_set_sysex(di->ev, size, data); - eventSend(di->ev); -#endif - -#ifdef MIDIOUTDEBUG - printfdebug("sysex\n"); -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::channelSilence (uchar ) -{ -#else -void AlsaOut::channelSilence (uchar chn) -{ - uchar i; - for ( i=0; i<127; i++) - { - noteOff(chn,i,0); - } -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::channelMute(uchar , int ) -{ -#else -void AlsaOut::channelMute(uchar chn, int a) -{ - if (a==1) - { - chnmute[chn]=a; - channelSilence(chn); - } - else if (a==0) - { - chnmute[chn]=a; - } - /* else ignore the call to this procedure */ -#endif -} - -void AlsaOut::seqbuf_dump (void) -{ - printf("You shouldn't be here.\n"); -} - -void AlsaOut::seqbuf_clean(void) -{ - printf("You shouldn't be here neither.\n"); -} - -void AlsaOut::wait(double ticks) -{ -// SEQ_WAIT_TIME(((int)(ticks/convertrate))); - time=static_cast(ticks); - -#ifdef MIDIOUTDEBUG - printfdebug("Wait >\t ticks: %g\n",ticks); -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::tmrSetTempo(int ) -{ -#else -void AlsaOut::tmrSetTempo(int v) -{ - eventInit(di->ev); - di->ev->type = SND_SEQ_EVENT_TEMPO; - snd_seq_ev_set_direct(di->ev); - di->ev->data.queue.queue = di->queue; - di->ev->data.queue.param.value = v; - di->ev->dest.client = SND_SEQ_CLIENT_SYSTEM; - di->ev->dest.port = SND_SEQ_PORT_SYSTEM_TIMER; - snd_seq_event_output_direct(di->handle, di->ev); -#ifdef MIDIOUTDEBUG - printfdebug("SETTEMPO >\t tempo: %d\n",v); -#endif -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::sync(int ) -{ -#else -void AlsaOut::sync(int i) -{ - if (i==1) - { - snd_seq_flush_output(di->handle); - } - - if (di->timerStarted && di->src) - { - eventInit(di->ev); - di->ev->dest = *di->src; - eventSend(di->ev); - snd_seq_flush_output(di->handle); - snd_seq_event_input(di->handle,&di->ev); - } - -#endif -} - -#ifndef HAVE_ALSA_SEQ -void AlsaOut::tmrStart(int ) -{ -#else -void AlsaOut::tmrStart(int tpcn) -{ - int ret; - di->timerStarted=true; - di->tPCN=tpcn; - -#ifdef HAVE_LIBASOUND2 - snd_seq_queue_tempo_t *queuetempo; - snd_seq_queue_tempo_alloca(&queuetempo); - snd_seq_queue_tempo_set_ppq(queuetempo, tpcn); - snd_seq_queue_tempo_set_tempo(queuetempo, 60*1000000/120); - ret = snd_seq_set_queue_tempo(di->handle, di->queue, queuetempo); -#else - snd_seq_queue_tempo_t queuetempo; - memset(&queuetempo, 0, sizeof(queuetempo)); - queuetempo.queue = di->queue; - queuetempo.ppq = tpcn; - queuetempo.tempo = 60*1000000/120; - ret = snd_seq_set_queue_tempo(di->handle, di->queue, &queuetempo); -#endif - - timerEventSend(SND_SEQ_EVENT_START); - snd_seq_start_queue(di->handle,di->queue,NULL); -#endif -} - -void AlsaOut::tmrStop(void) -{ -#ifdef HAVE_ALSA_SEQ - di->timerStarted=false; - timerEventSend(SND_SEQ_EVENT_STOP); -#endif -} - -void AlsaOut::tmrContinue(void) -{ -} - -const char * AlsaOut::deviceName(void) const -{ -#ifdef HAVE_ALSA_SEQ - return di->tgtname; -#else - return 0L; -#endif -} diff --git a/libkmid/alsaout.h b/libkmid/alsaout.h deleted file mode 100644 index fd4a46579..000000000 --- a/libkmid/alsaout.h +++ /dev/null @@ -1,231 +0,0 @@ -/* alsaout.cc - class AlsaOut which represents an alsa client/port pair - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _ALSAOUT_H -#define _ALSAOUT_H - -#include - -struct snd_seq_event; -typedef struct snd_seq_event snd_seq_event_t; - -/** - * @short Sends MIDI events to a MIDI devices using ALSA - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class AlsaOut : public MidiOut -{ - friend class DeviceManager; - - protected: - -/** - * @internal - * Total number of devices. - */ - int ndevs; - -/** - * @internal - * Total number of midi ports - */ - int nmidiports; - - double count; - double lastcount; - double lasttime; - double begintime; - int m_rate; - -/** - * @internal - * A "constant" used to convert from milliseconds to the computer rate - */ - double convertrate; - - long int time; - - virtual void seqbuf_dump (void); - virtual void seqbuf_clean(void); - void eventInit(snd_seq_event_t *ev); - void eventSend(snd_seq_event_t *ep); - void timerEventSend(int type); - - public: - - /** - * Constructor. After constructing a MidiOut device, you must open it - * (using openDev() ). Additionally you may want to initialize it - * (with initDev() ), - */ - AlsaOut(int d, int client=64, int port=0, const char *cname="", const char *pname=""); - - /** - * Destructor. It doesn't matter if you close the device ( closeDev() ) - * before you destruct the object because in other case, it will be closed - * here. - */ - virtual ~AlsaOut(); - - /** - * Opens the device. This is generally called from DeviceManager , so you - * shouldn't call this yourself (except if you created the MidiOut object - * yourself. - * @param sqfd a file descriptor of /dev/sequencer - * @see closeDev - * @see initDev - */ - virtual void openDev (int sqfd); - - /** - * Closes the device. It basically tells the device (the file descriptor) - * is going to be closed. - * @see openDev - */ - virtual void closeDev (); - - /** - * Initializes the device sending generic standard midi events and controllers, - * such as changing the patches of each channel to an Acoustic Piano (000), - * setting the volume to a normal value, etc. - */ - virtual void initDev (); - - /** - * @return the device type of the object. This is to identify the - * inherited class that a given object is polymorphed to. - * The returned value is one of these : - * - * @li KMID_EXTERNAL_MIDI if it's a MidiOut object - * @li KMID_SYNTH if it's a SynthOut object (as an AWE device) - * @li KMID_FM if it's a FMOut object - * @li KMID_GUS if it's a GUSOut object - * - * which are defined in midispec.h - * - * @see deviceName - */ - int deviceType () const { return devicetype; } - - /** - * Returns the name and type of this MIDI device. - * @see deviceType - */ - virtual const char * deviceName (void) const; - - /** - * @internal - */ - int rate (void) { return m_rate; } - - /** - * See DeviceManager::noteOn() - */ - virtual void noteOn ( uchar chn, uchar note, uchar vel ); - - /** - * See DeviceManager::noteOff() - */ - virtual void noteOff ( uchar chn, uchar note, uchar vel ); - - /** - * See DeviceManager::keyPressure() - */ - virtual void keyPressure ( uchar chn, uchar note, uchar vel ); - - /** - * See DeviceManager::chnPatchChange() - */ - virtual void chnPatchChange ( uchar chn, uchar patch ); - - /** - * See DeviceManager::chnPressure() - */ - virtual void chnPressure ( uchar chn, uchar vel ); - - /** - * See DeviceManager::chnPitchBender() - */ - virtual void chnPitchBender ( uchar chn, uchar lsb, uchar msb ); - - /** - * See DeviceManager::chnController() - */ - virtual void chnController ( uchar chn, uchar ctl , uchar v ); - - /** - * See DeviceManager::sysex() - */ - virtual void sysex ( uchar *data,ulong size); - - /** - * Mutes all notes being played on a given channel. - */ - virtual void channelSilence ( uchar chn ); - - /** - * Mute or "unmute" a given channel . - * @param chn channel to work on - * @param b if true, the device will ignore subsequent notes played on the chn - * channel, and mute all notes being played on it. If b is false, the channel - * is back to work. - */ - virtual void channelMute ( uchar chn, int b ); - - /** - * Change all channel volume events multiplying it by this percentage correction - * Instead of forcing a channel to a fixed volume, this method allows to - * music to fade out even when it was being played softly. - * @param volper is an integer value, where 0 is quiet, 100 is used to send - * an unmodified value, 200 play music twice louder than it should, etc. - */ - virtual void setVolumePercentage ( int volper ) - { volumepercentage = volper; } - - /** - * Returns true if everything's ok and false if there has been any problem - */ - int ok (void) - { if (seqfd<0) return 0; - return (_ok>0); - } - - virtual void wait (double ticks); - virtual void tmrSetTempo (int v); - virtual void tmrStart (int tpcn); - virtual void tmrStart () { tmrStart(-1); } - virtual void tmrStop (); - virtual void tmrContinue (); - /** - * @internal - * If i==1 syncronizes by cleaning the buffer instead of sending it (in fact, - * this is what synchronizing really means :-) ) - */ - void sync (int i=0); - - class AlsaOutPrivate; - AlsaOutPrivate *di; -}; - -#endif // _ALSAOUT_H diff --git a/libkmid/awe_sup.h b/libkmid/awe_sup.h deleted file mode 100644 index 5602cf15f..000000000 --- a/libkmid/awe_sup.h +++ /dev/null @@ -1,50 +0,0 @@ -/* awe_sup.h - A wrapper on awe_voice.h - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _AWE_SUP_H -#define _AWE_SUP_H - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_AWE_VOICE_H -#include -#define HAVE_AWE32 -#elif defined(HAVE_LINUX_AWE_VOICE_H) -#include -#define HAVE_AWE32 -#elif defined(HAVE__USR_SRC_SYS_I386_ISA_SOUND_AWE_VOICE_H) -#include "/usr/src/sys/i386/isa/sound/awe_voice.h" -#define HAVE_AWE32 -#elif defined(HAVE__USR_SRC_SYS_GNU_I386_ISA_SOUND_AWE_VOICE_H) -#include "/usr/src/sys/gnu/i386/isa/sound/awe_voice.h" -#define HAVE_AWE32 -#endif - -#ifndef AWE_SET_CHANNEL_MODE -// AWE32 doesn't work if AWE_SET_CHANNEL_MODE isn't defined. -#undef HAVE_AWE32 -#endif - -#endif diff --git a/libkmid/configure.in.in b/libkmid/configure.in.in deleted file mode 100644 index 7500e3455..000000000 --- a/libkmid/configure.in.in +++ /dev/null @@ -1,128 +0,0 @@ -dnl libkmid's specific checks - -#AC_MSG_CHECKING(if libkmid would compile) -#AC_CACHE_VAL(kde_libkmid_compiles, -#[ -#AC_TRY_COMPILE([ -##ifndef __FreeBSD__ -##include -##else -##include -##endif -#], -#[ -#], -# kde_libmid_compiles=yes, -#kde_libmid_compiles=no) -#]) -#AC_MSG_RESULT($kde_libmid_compiles) -#if test $kde_libmid_compiles = no; then -# DO_NOT_COMPILE="$DO_NOT_COMPILE libkmid" -#fi - -#AC_MSG_CHECKING([for OSS support]) -#AC_CACHE_VAL(ac_cv_header_soundcard_h, -#[ -#AC_TRY_COMPILE([ -##include -#], -#[ ], -#ac_cv_header_soundcard_h=yes, -#ac_cv_header_soundcard_h=no) -#]) -#AC_MSG_RESULT($ac_cv_header_soundcard_h) -#if eval "test \"`echo $ac_cv_header_soundcard_h`\" = yes"; then -# AC_DEFINE(HAVE_GETHOSTNAME, 1, [Define if you have getdomainname]) -#fi -#CXXFLAGS="$save_CXXFLAGS" -#]) - - -AC_CHECK_HEADERS(sys/soundcard.h machine/soundcard.h linux/awe_voice.h awe_voice.h /usr/src/sys/i386/isa/sound/awe_voice.h /usr/src/sys/gnu/i386/isa/sound/awe_voice.h) - -dnl check for ALSA audio support - -kde_with_alsa=yes -AC_ARG_WITH(alsa, AC_HELP_STRING([--with-alsa],[enable libKMid ALSA support]), -[kde_with_alsa=$withval]) - -if test "$kde_with_alsa" = "yes"; then -AC_DEFUN([AC_CHECK_LIBASOUND], -[ - ac_ldflags_save="$LDFLAGS" - LDFLAGS="$all_libraries $LDFLAGS" - kde_has_asoundlib=no - - AC_CHECK_HEADERS([ sys/asoundlib.h alsa/asoundlib.h ], - [ - kde_has_asoundlib=yes - ]) - - dnl trial and error version check for ALSA 0.5.x / ALSA 0.9.x - AC_LANG_SAVE - AC_LANG_C - if test "x$kde_has_asoundlib" = "xyes"; then - AC_TRY_COMPILE([ - #include "confdefs.h" - #ifdef HAVE_SYS_ASOUNDLIB_H - #include - #endif - #ifdef HAVE_ALSA_ASOUNDLIB_H - #include - #endif - ],[ - #if ((SND_LIB_MAJOR == 0) && (SND_LIB_MINOR == 9)) || (SND_LIB_MAJOR == 1) - /* we have ALSA 0.9.x or 1.x */ - #else - #error not ALSA 0.9.x - #endif - ], - kde_has_alsa_0_9=yes, - kde_has_alsa_0_9=no) - fi - - if test "x$kde_has_asoundlib" = "xyes"; then - AC_TRY_COMPILE([ - #include "confdefs.h" - #ifdef HAVE_SYS_ASOUNDLIB_H - #include - #endif - #ifdef HAVE_ALSA_ASOUNDLIB_H - #include - #endif - ],[ - #if (SND_LIB_MAJOR == 0) && (SND_LIB_MINOR == 5) - /* we have ALSA 0.5.x */ - #else - #error not ALSA 0.5.x - #endif - ], - kde_has_alsa_0_5=yes, - kde_has_alsa_0_5=no) - fi - AC_LANG_RESTORE - - if test "x$kde_has_asoundlib" = "xyes"; then - AC_CHECK_LIB(asound,snd_seq_create_simple_port,[ - if test "x$kde_has_alsa_0_5" = "xyes"; then - LIBASOUND="-lasound" - AC_DEFINE(HAVE_LIBASOUND, 1, - [Define if you have libasound.so.1 (required for ALSA 0.5.x support)]) - fi - if test "x$kde_has_alsa_0_9" = "xyes"; then - LIBASOUND="-lasound" - AC_DEFINE(HAVE_LIBASOUND2, 1, - [Define if you have libasound.so.2 (required for ALSA 0.9.x support)]) - AC_CHECK_LIB(asound,snd_pcm_resume,[ - AC_DEFINE(HAVE_SND_PCM_RESUME, 1, - [Define if libasound has snd_pcm_resume()])]) - fi - ]) - fi - AC_SUBST(LIBASOUND) - LDFLAGS="$ac_ldflags_save" -]) -AC_CHECK_LIBASOUND -fi - -AC_SUBST(LIBASOUND) diff --git a/libkmid/dattypes.cc b/libkmid/dattypes.cc deleted file mode 100644 index 821abd00a..000000000 --- a/libkmid/dattypes.cc +++ /dev/null @@ -1,110 +0,0 @@ -/************************************************************************** - - dattypes.cc - Some always useful definitions and functions - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "dattypes.h" -#include - -ushort readShort(FILE *fh) -{ - uchar c1; - uchar c2; - - fread(&c1,1,1,fh); - fread(&c2,1,1,fh); - return (c1<<8)|c2; -} - -ulong readLong(FILE *fh) -{ - uchar c1; - uchar c2; - uchar c3; - uchar c4; - ulong l; - - fread(&c1,1,1,fh); - fread(&c2,1,1,fh); - fread(&c3,1,1,fh); - fread(&c4,1,1,fh); - l=((c1<<24)|(c2<<16)|(c3<<8)|c4); - return l; -} - -#ifdef DEBUG - -void printfdebug(const char *format, int a, int b, int c) -{ - char *s=(char *)format; - int i=0; - while (*s!=0) - { - if (*s=='%') i++; - s++; - } - switch (i) - { - case (1) : fprintf(stderr,format,a); break; - case (2) : fprintf(stderr,format,a,b); break; - case (3) : fprintf(stderr,format,a,b,c); break; - default : fprintf(stderr,format); break; - } - -} - -void printfdebug(const char *format, int a, long b) -{ - fprintf(stderr,format,a,b); -} - -void printfdebug(const char *format, double a, double b, double c) -{ - char *s=(char *)format; - int i=0; - while (*s!=0) - { - if (*s=='%') i++; - s++; - } - switch (i) - { - case (1) : fprintf(stderr,format,a); break; - case (2) : fprintf(stderr,format,a,b); break; - case (3) : fprintf(stderr,format,a,b,c); break; - default : fprintf(stderr,format); break; - } - -} -#else - -void printfdebug(const char *, int , int , int ) -{ -} -void printfdebug(const char *, int , long ) -{ -} -void printfdebug(const char *, double , double , double ) -{ -} -#endif diff --git a/libkmid/dattypes.h b/libkmid/dattypes.h deleted file mode 100644 index 0e647980f..000000000 --- a/libkmid/dattypes.h +++ /dev/null @@ -1,55 +0,0 @@ -/* dattypes.h - Some useful definitions and functions - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _DATTYPES_H -#define _DATTYPES_H - -#include -#include - -#undef uchar -#undef ushort -#undef ulong - -/** - * Unsigned char - */ -typedef unsigned char uchar; - -/** - * Unsigned short - */ -typedef unsigned short ushort; - -/** - * Unsigned long - */ -typedef unsigned long ulong; - -ushort readShort(FILE *fh); -ulong readLong (FILE *fh); - -void printfdebug(const char *s,int a=0,int b=0, int c=0); -void printfdebug(const char *s,int a,long b); -void printfdebug(const char *s,double a,double b=0, double c=0); - -#endif diff --git a/libkmid/deviceman.cc b/libkmid/deviceman.cc deleted file mode 100644 index f539d00b6..000000000 --- a/libkmid/deviceman.cc +++ /dev/null @@ -1,830 +0,0 @@ -/************************************************************************** - - deviceman.cc - The device manager, that hides the use of midiOut - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - $Id$ - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "deviceman.h" -#include "midiout.h" -#include -#include -#include -#include -#include -#include "sndcard.h" -#include "synthout.h" -#include "fmout.h" -#include "gusout.h" -#include "alsaout.h" -#include "midimapper.h" -#include "midispec.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_SYS_STAT_H -#include -#endif - -#ifdef HAVE_ALSA_ASOUNDLIB_H -# define HAVE_ALSA_SUPPORT -# include -#elif defined(HAVE_SYS_ASOUNDLIB_H) -# define HAVE_ALSA_SUPPORT -# include -#else -#ifdef HAVE_LIBASOUND2 -# define HAVE_ALSA_SUPPORT -# include -# include -#elif defined(HAVE_LIBASOUND) -# define HAVE_ALSA_SUPPORT -# include -#endif -#endif - -#if 1 -#include -#include -#include -#endif - -//#define DEVICEMANDEBUG -//#define GENERAL_DEBUG_MESSAGES - -SEQ_DEFINEBUF (4096); - -#define CONTROLTIMER - -#ifdef GENERAL_DEBUG_MESSAGES -void DEBUGPRINTF(const char *format) -{ - printf(format); -} - -void DEBUGPRINTF(const char *format,int i) -{ - printf(format,i); -} - -void DEBUGPRINTF(const char *format,const char *s) -{ - printf(format,s); -} - -#else - -void DEBUGPRINTF(const char *) { } -void DEBUGPRINTF(const char *,int ) { } -void DEBUGPRINTF(const char *,const char * ) { } - -#endif - - -DeviceManager::DeviceManager(int def) -{ -#if 1 - if (def==-1) - { - TDEInstance *tmp_instance=0L; - if (!TDEGlobal::_instance) tmp_instance=new TDEInstance("nonKDEapp"); - TDEConfig *config = new TDEConfig("kcmmidirc", true); - - config->setGroup("Configuration"); - default_dev=config->readNumEntry("midiDevice",0); - if ( default_dev < 0 ) - default_dev=0; - TQString mapurl(config->readPathEntry("mapFilename")); - if ((config->readBoolEntry("useMidiMapper", false))&&(!mapurl.isEmpty())) - { - mapper_tmp = new MidiMapper( mapurl.mid(mapurl.find(":")+1 ).local8Bit() ); - } - else - mapper_tmp = 0L; - - delete config; - delete tmp_instance; - } - else -#endif - { - default_dev = def; - mapper_tmp = 0L; - } - - initialized=0; - _ok=1; - alsa=false; - device = 0L; - m_rate=0; - convertrate=10; - seqfd=-1; - timerstarted=0; - n_midi=0; - n_synths=0; - n_total=0; - midiinfo=0L; - synthinfo=0L; - for (int i=0;i<16;i++) chn2dev[i]=default_dev; -} - -DeviceManager::~DeviceManager(void) -{ - closeDev(); - if (device) - { - for (int i=0;i=n_total) default_dev=0; - DEBUGPRINTF("check : %d\n",r); - return r; - } - return 0; -} - -void DeviceManager::checkAlsa(void) -{ -#ifdef HAVE_SYS_STAT_H - struct stat buf; - stat("/proc/asound", &buf); - if ((stat("/proc/asound", &buf) == 0 ) && (S_ISDIR(buf.st_mode))) - alsa=true; - else - alsa=false; -#else -#warning "ALSA won't be found at runtime" - alsa=false; -#endif -} - -int DeviceManager::initManager(void) -{ - checkAlsa(); - - if (!alsa) // We are using OSS - { -#ifdef HAVE_OSS_SUPPORT - n_synths=0; - n_midi=0; - n_total=0; - - seqfd = open("/dev/sequencer", O_WRONLY | O_NONBLOCK, 0); - if (seqfd==-1) - { - fprintf(stderr,"ERROR: Couldn't open /dev/sequencer to get some information\n"); - _ok=0; - return -1; - } - ioctl(seqfd,SNDCTL_SEQ_NRSYNTHS,&n_synths); - ioctl(seqfd,SNDCTL_SEQ_NRMIDIS,&n_midi); - n_total=n_midi+n_synths; - - - if (n_midi==0) - { - fprintf(stderr,"ERROR: There's no midi port\n"); - /* This could be a problem if the user don't have a synth neither, - but not having any of both things is unusual */ - // _ok=0; - // return 1; - } - - device=new MidiOut*[n_total]; - midiinfo=new midi_info[n_midi]; - synthinfo=new synth_info[n_synths]; - - int i; - for (i=0;iopenDev(seqfd); -// DEBUGPRINTF("%s ",device[i]->deviceName()); - } -// DEBUGPRINTF("\n"); - for (int i=0;iok()) _ok=0; - if (_ok==0) - { - for (int i=0;icloseDev(); -// DEBUGPRINTF("DeviceMan :: ERROR : Closing devices\n"); - return; - } - -// DEBUGPRINTF("Devices opened\n"); -} - -void DeviceManager::closeDev(void) -{ - if (alsa) - { - if (device) - for (int i=0;icloseDev(); - - return; - } - -#ifdef HAVE_OSS_SUPPORT - if (seqfd==-1) return; - tmrStop(); - if (device) - for (int i=0;icloseDev(); - /* - DEBUGPRINTF("Closing devices : "); - if (device!=NULL) for (int i=0;iinitDev(); - DEBUGPRINTF("%s ",device[i]->deviceName()); - - // device[i]->closeDev(); - }; - DEBUGPRINTF("\n"); - */ - close(seqfd); - seqfd=-1; -#endif -} - -void DeviceManager::initDev(void) -{ - if (device!=0L) - { -// DEBUGPRINTF("Initializing devices :"); - for (int i=0;iinitDev(); - DEBUGPRINTF("%s ",device[i]->deviceName()); - } - DEBUGPRINTF("\n"); - } -} - -void DeviceManager::noteOn ( uchar chn, uchar note, uchar vel ) -{ - MidiOut *midi=chntodev(chn); - if (midi) midi->noteOn(chn,note,vel); -} -void DeviceManager::noteOff ( uchar chn, uchar note, uchar vel ) -{ - MidiOut *midi=chntodev(chn); - if (midi) midi->noteOff(chn,note,vel); -} -void DeviceManager::keyPressure ( uchar chn, uchar note, uchar vel ) -{ - MidiOut *midi=chntodev(chn); - if (midi) midi->keyPressure(chn,note,vel); -} -void DeviceManager::chnPatchChange ( uchar chn, uchar patch ) -{ - MidiOut *midi=chntodev(chn); - if (midi) midi->chnPatchChange(chn,patch); -} -void DeviceManager::chnPressure ( uchar chn, uchar vel ) -{ - MidiOut *midi=chntodev(chn); - if (midi) midi->chnPressure(chn,vel); -} -void DeviceManager::chnPitchBender ( uchar chn, uchar lsb, uchar msb ) -{ - MidiOut *midi=chntodev(chn); - if (midi) midi->chnPitchBender(chn,lsb,msb); -} -void DeviceManager::chnController ( uchar chn, uchar ctl , uchar v ) -{ - MidiOut *midi=chntodev(chn); - if (midi) midi->chnController(chn,ctl,v); -} -void DeviceManager::sysEx ( uchar *data,ulong size) -{ - for (int i=0;isysex(data,size); -} - -void DeviceManager::wait (double ticks) -{ -#ifdef HAVE_ALSA_SUPPORT - if (alsa) { ((AlsaOut *)device[default_dev])->wait(ticks); return; }; -#endif - -#ifdef HAVE_OSS_SUPPORT - unsigned long int t=(unsigned long int)(ticks/convertrate); - if (lastwaittime==t) return; - lastwaittime=t; - SEQ_WAIT_TIME(t); - SEQ_DUMPBUF(); -#endif -} - -//void DeviceManager::tmrSetTempo(int v) -void DeviceManager::tmrSetTempo(int v) -{ -#ifdef HAVE_ALSA_SUPPORT - if (alsa) { ((AlsaOut *)device[default_dev])->tmrSetTempo(v); return; } -#endif - -#ifdef HAVE_OSS_SUPPORT - SEQ_SET_TEMPO(v); - SEQ_DUMPBUF(); -#endif -} - -void DeviceManager::tmrStart(long int -#ifdef HAVE_ALSA_SUPPORT -tpcn /*name the argument only if it is used*/ -#endif -) -{ -#ifdef HAVE_ALSA_SUPPORT - if (alsa) { ((AlsaOut *)device[default_dev])->tmrStart(tpcn); return; } -#endif - -#ifdef HAVE_OSS_SUPPORT -#ifdef CONTROLTIMER - if (!timerstarted) - { - SEQ_START_TIMER(); - SEQ_DUMPBUF(); - timerstarted=1; - } - lastwaittime=0; -#else - SEQ_START_TIMER(); - SEQ_DUMPBUF(); -#endif -#endif -} - -void DeviceManager::tmrStop(void) -{ -#ifdef HAVE_ALSA_SUPPORT - if (alsa) { ((AlsaOut *)device[default_dev])->tmrStop(); return; } -#endif - -#ifdef HAVE_OSS_SUPPORT -#ifdef CONTROLTIMER - if (timerstarted) - { - SEQ_STOP_TIMER(); - SEQ_DUMPBUF(); - timerstarted=0; - } -#else - SEQ_STOP_TIMER(); - SEQ_DUMPBUF(); -#endif -#endif -} - -void DeviceManager::tmrContinue(void) -{ -#ifdef HAVE_ALSA_SUPPORT - if (alsa) { ((AlsaOut *)device[default_dev])->tmrContinue(); return; } -#endif - -#ifdef HAVE_OSS_SUPPORT -#ifdef CONTROLTIMER - if (timerstarted) - { - SEQ_CONTINUE_TIMER(); - SEQ_DUMPBUF(); - } -#else - SEQ_CONTINUE_TIMER(); - SEQ_DUMPBUF(); -#endif -#endif -} - -void DeviceManager::sync(bool f) -{ -#ifdef HAVE_ALSA_SUPPORT - if (alsa) { ((AlsaOut *)device[default_dev])->sync(f); return ; }; -#endif - -#ifdef HAVE_OSS_SUPPORT -#ifdef DEVICEMANDEBUG - printf("Sync %d\n",f); -#endif - if (f) - { - seqbuf_clean(); - /* If you have any problem, try removing the next 2 lines, - I though they would be useful here but the may have side effects */ - ioctl(seqfd,SNDCTL_SEQ_RESET); - ioctl(seqfd,SNDCTL_SEQ_PANIC); - } - else - { - seqbuf_dump(); - ioctl(seqfd, SNDCTL_SEQ_SYNC); - }; -#endif -} - -void DeviceManager::seqbuf_dump (void) -{ - if (!alsa) - { -#ifdef HAVE_OSS_SUPPORT - if (_seqbufptr) - { - int r=0; - unsigned char *sb=_seqbuf; - int w=_seqbufptr; - r=write (seqfd, _seqbuf, _seqbufptr); -#ifdef DEVICEMANDEBUG - printf("%d == %d\n",r,w); - printf("%d\n",(errno==EAGAIN)? 1 : 0); -#endif - while (((r == -1)&&(errno==EAGAIN))||(r != w)) - { - if ((r==-1)&&(errno==EAGAIN)) - { - usleep(1); - } - else if ((r>0)&&(r!=w)) - { - w-=r; - sb+=r; - } - r=write (seqfd, sb, w); -#ifdef DEVICEMANDEBUG - printf("%d == %d\n",r,w); - printf("%d\n",(errno==EAGAIN)? 1 : 0); -#endif - } - } - /* - * if (_seqbufptr) - * if (write (seqfd, _seqbuf, _seqbufptr) == -1) - * { - * printf("Error writing to /dev/sequencer in deviceManager::seqbuf_dump\n"); - * perror ("write /dev/sequencer in seqbuf_dump\n"); - * exit (-1); - * } - */ - _seqbufptr = 0; -#endif - } -} - -void DeviceManager::seqbuf_clean(void) -{ -#ifdef HAVE_ALSA_SUPPORT - if (alsa) - ((AlsaOut *)device[default_dev])->seqbuf_clean(); - else -#endif -#ifdef HAVE_OSS_SUPPORT - _seqbufptr=0; -#endif -} - - -const char *DeviceManager::name(int i) -{ -#ifdef HAVE_OSS_SUPPORT - if (checkInit()<0) {_ok = 0; return NULL;} - - if (alsa) - { - if (ideviceName(); - } - else - { - if (i=n_total) return; - default_dev=i; - for (int i=0;i<16;i++) chn2dev[i]=default_dev; -} - -const char *DeviceManager::midiMapFilename(void) -{ - if (device==0L) return ""; - if (default_dev>=n_total) return ""; - return (device[default_dev]!=NULL) ? - device[default_dev]->midiMapFilename() : ""; -} - -void DeviceManager::setMidiMap(MidiMapper *map) -{ - if (map==NULL) return; - mapper_tmp=map; - if (default_dev>=n_total) {default_dev=0;return;}; - if ((device==0L)||(device[default_dev]==NULL)) - return; - device[default_dev]->setMidiMapper(map); -} - -int DeviceManager::setPatchesToUse(int *patchesused) -{ - if (checkInit()<0) return -1; - if ((device==0L)||(device[default_dev]==NULL)) - return 0; - - if ((device[default_dev]->deviceType())==KMID_GUS) - { - GUSOut *gus=(GUSOut *)device[default_dev]; - gus->setPatchesToUse(patchesused); - } - return 0; -} - -void DeviceManager::setVolumePercentage(int v) -{ - if (device!=0L) - { - for (int i=0;isetVolumePercentage(v); - } - } -} - -void DeviceManager::setDeviceNumberForChannel(int chn, int dev) -{ - chn2dev[chn]=dev; -} - -void DeviceManager::allNotesOff(void) -{ - for (int i=0;iallNotesOff(); -} diff --git a/libkmid/deviceman.h b/libkmid/deviceman.h deleted file mode 100644 index 8bd0728a6..000000000 --- a/libkmid/deviceman.h +++ /dev/null @@ -1,537 +0,0 @@ -/* deviceman.h - The device manager, that hides the use of midiOut - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef DEVICEMAN_H -#define DEVICEMAN_H - -#include -#include - -class MidiOut; -class MidiMapper; - -/** - * MIDI Device Manager class . This class is the one you should use to - * send MIDI events to any device, as it creates and manages the *Out classes. - * - * This class is usually used by creating a DeviceManager object, then call - * openDev() and initDev() . Then, use numberOfMidiPorts(), - * numberOfSynthDevices(), name() and type() to choose which - * device to play MIDI events to and then use defaultDevice() to set the - * MIDI device to play. - * - * @short Manages all MIDI devices and redirects MIDI events to each one as - * configured. - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class KMID_EXPORT DeviceManager -{ - protected: - - /** - * @internal - * The midi devices objects - */ - MidiOut **device; - - /** - * @internal - * Midi info - */ - struct midi_info *midiinfo; - - /** - * @internal - * Synth info - */ - struct synth_info *synthinfo; - - /** - * @internal - * Stores the device thru which a channel will be sent - */ - int chn2dev[16]; - - /** - * @internal - * Number of synths devices - */ - int n_synths; - - /** - * @internal - * Number of midi ports - */ - int n_midi; - - /** - * @internal - * n_midi + n_synths - */ - int n_total; - - /** - * @internal - * rate - */ - int m_rate; - - /** - * @internal - * A "constant" used to convert from milliseconds to the computer rate. - */ - double convertrate; - - /** - * @internal - * Newest kernels don't want me to stop a timer that hasn't been started :-) - */ - int timerstarted; - - /** - * @internal - * Last time waited for in wait(double) - */ - double lastwaittime; - - /** - * @internal - * Keeps a pointer to the mapper so that if devices weren't initialized when - * first called setMidiMap then, when they get initialized, they use the - * proper mapper - */ - MidiMapper *mapper_tmp; - - int initialized; - - /** - * @internal - * The real file handler for /dev/sequencer, that is opened and closed. - */ - int seqfd; - - /** - * @internal - * The device to which timer events will be sent - */ - int default_dev; - - /** - * @internal - */ - int _ok; - - /** - * @internal - * True if the user is running ALSA. False if (s)he's using OSS - */ - bool alsa; - - /** - * @internal - */ - void seqbuf_dump (void); - - /** - * @internal - */ - void seqbuf_clean (void); - - /** - * @internal - */ - void checkAlsa (void); - public: - /** - * Constructor. It just initializes internal variables, before playing any - * music, you should call initManager(), setMidiMap() - * (optional), openDev(), initDev(), setPatchesToUse() - * (not required, unless you're playing to a GUS device, which must load - * the patches), tmrStart(), and finally, play the music. - */ - DeviceManager(int def=-1); - - /** - * Destructor. It closes the device (calling closeDev() ) if it wasn't - * closed before. - */ - ~DeviceManager(void); - - /** - * Initializes the MIDI Device Manager object. - * - * The /dev/sequencer and/or /dev/snd/seq files are opened, available - * devices are analyzed and *Out objects are created. Then, the - * device files are closed. - * - * @return 0 if everything was OK, or -1 if there was an error and it - * couldn't be initialized (for example, because it couldn't open the - * /dev/sequencer file) - */ - int initManager(void); - - /** - * Checks if the device manager has been initialized (with @p initManager), - * and in case it wasn't, initializes it. - * - * @return 0 if it was (or has just been) correctly initialized, and -1 if - * there was an error. - */ - int checkInit(void); - - /** - * \obsolete Please use deviceForChannel() instead. - * - */ - MidiOut *chntodev(int chn) - { return deviceForChannel(chn); } - - /** - * It's possible to send different MIDI channels to different MIDI devices, - * so that you can for example send channel 1 to an external synthesizer, - * channel 2 to a FM device and channel 10 to an AWE synth. - * - * @return the device to which MIDI events goind to channel @p chn should - * be sent. - */ - MidiOut *deviceForChannel(int chn) - { return (device!=0L) ? device[chn2dev[chn]] : 0L ; } - - /** - * Returns the device number associated with a given channel. - */ - int deviceNumberForChannel(int chn) { return chn2dev[chn]; } - - /** - * Sets the device number associated with a given channel. - */ - void setDeviceNumberForChannel(int chn, int dev); - - /** - * @return 0 if there was a problem and 1 if everything was OK. Note that the - * return value is changed after you check it, so you can only check it once. - */ - int ok(void); - - /** - * Returns true if it's running ALSA and false if OSS is being run - */ - int usingAlsa(void) { return alsa; } - - // The following function are here to emulate a midi, so that the - // DeviceManager sends the events to the appropriate devices. - - /** - * Open the devices. It first initializes the manager it that wasn't done - * yet (you should do it yourself, to be able to choose the MIDI output - * device, as it will be set to an external synth by default, if available). - * - * Then /dev/sequencer is opened and the MIDI devices are opened - * (calling MidiOut::openDev() ). - * @see ok() to check if there was any problem - * @see closeDev() - * @see initDev() - */ - void openDev (void); - - /** - * Closes the devices, and /dev/sequencer. - * - * @see openDev() - */ - void closeDev (void); - - /** - * Calls MidiOut::initDev() in turn in each of the available devices. - * - * @see MidiOut::initDev() - */ - void initDev (void); - - /** - * Sends a Note On MIDI event. - * - * @param chn the MIDI channel (0 to 15) to play the note on. - * @param note the key of the note to play (0 to 127). - * @param vel the velocity of the note (0 to 127). - * - * @see noteOff() - */ - void noteOn ( uchar chn, uchar note, uchar vel ); - - /** - * Sends a Note Off MIDI event. This is equivalent to send a Note On event - * with a vel value of 0. - * - * @param chn the MIDI channel (0 to 15) to play the note on. - * @param note the key of the note to play (0 to 127). - * @param vel the velocity of the note (0 to 127). - * - * @see noteOn() - */ - void noteOff ( uchar chn, uchar note, uchar vel ); - - /** - * Sends a Key Pressure (or Aftertouch) MIDI event. - * This event changes the pressure over a key after this key has been played. - * - * @param chn the MIDI channel (0 to 15) where the note is being played. - * @param note the key of the note (0 to 127). - * @param vel the new velocity (or pressure) of the note (0 to 127). - */ - void keyPressure ( uchar chn, uchar note, uchar vel ); - - /** - * Changes the patch (instrument) on a MIDI channel. - * - * @see setPatchesToUse() - * - * @param chn the MIDI channel (0 to 15) . - * @param patch the General Midi patch (0 to 127) to use on the channel chn. - */ - void chnPatchChange ( uchar chn, uchar patch ); - - /** - * Changes the Pressure (Aftertouch) on a MIDI channel. Keep in mind that - * some synthesizers don't like this events, and it's better not to send it. - * - * @param chn the MIDI channel (0 to 15) to change. - * @param vel the velocity (0 to 127) to use on the channel chn. - */ - void chnPressure ( uchar chn, uchar vel ); - - /** - * Changes the Pitch Bender value on a MIDI channel. This bends the tone of - * each note played on this channel. - * - * @param chn the MIDI channel (0 to 15) to use. - * @param lsb and @p msb the less significant byte and the most significant - * byte (0 to 127 each) of the number by which notes will be bend. a 0x4000 - * value means not to bend. - * @param msb the most significant byte - */ - void chnPitchBender ( uchar chn, uchar lsb, uchar msb ); - - /** - * Sends a Controller event to a MIDI channel. This can be used for example - * to change the volume, set a XG patch, etc. Look for any General Midi - * resource page on the net for more information about the available - * controller events. - * - * For example, to set the tremolo value to a maximum on the MIDI channel - * number one, you should pass 1 to @p chn, 1 to @p ctl and 127 to @p v. - * - * @param chn the MIDI channel (0 to 15) to send the event to. - * @param ctl the controller (0 to 15) to send. - * @param v the value (data) of the controller. - */ - void chnController ( uchar chn, uchar ctl , uchar v ); - - /** - * Sends a SYStem EXclusive message to the default MIDI device (usually, - * external MIDI synths, as most internal synths do not support sysex - * messages) - * - * @param data the array of bytes that comform the system exclusive message. - * Without the initial 0xF0 char, and including the final 0xF7 char (end of - * exclusive message) - * @param size the size in bytes of the data to send - * - * @see setDefaultDevice() - */ - void sysEx ( uchar *data,ulong size); - - /** - * Sets the number of milliseconds at which the next event will be sent. - * This way, you can schedule notes and events to send to the MIDI device. - * @see tmrStart() - */ - void wait (double ms); - - /** - * Sets the tempo which will be used to convert between ticks and - * milliseconds. - */ - void tmrSetTempo(int v); - - /** - * Starts the timer. You must call tmrStart before using wait() - */ - void tmrStart(long int tpcn); - - /** - * Stops the timer. This will be called by closeDev() before closing - * the device - */ - void tmrStop(void); - - /** - * Continue the stopped timer . It is the same than starting a new timer, but - * without resetting it. - */ - void tmrContinue(void); - - /** - * Sends an all notes off event - */ - void allNotesOff(void); - - /** - * Synchronizes with the MIDI buffer. Midi events are put into a buffer, - * along with timer delays (see wait() ). sync returns when the buffer - * is empty. - * - * @param f if false, it syncronizes by waiting for the buffer to be sent. - * If true, it forces the synchronization by clearing the buffer - * inmediately. The "force" method is, of course, not recommended, except - * in rare situations. - */ - void sync(bool f=0); - - /** - * Changes the "master" volume of the played events by altering next volume - * controller events. The parameter @p i should be in the range of 0 - * (nothing is heard) to 150 (music is played at a 150% of the original - * volume). - * - * Keep in mind that as most MIDI files already play music at near the - * maximum volume, an @p i value greater than 100 is very probably ignored - * most of the times. - */ - void setVolumePercentage(int i); - - /** - * Returns the device to which the MIDI events will be sent. - * Returns -1 if there's no available device. - * - * @see setDefaultDevice() - */ - int defaultDevice(void); - - /** - * Sets the device to send the MIDI events to. - * - * By using midiPorts(), synthDevices(), name() and - * type(), you should choose which device to use (note that they are - * numbered with midi ports being first and synth devices next) - * - * @see defaultDevice() - */ - void setDefaultDevice(int i); - - /** - * Loads the patches you're going to use . This has effect only for GUS - * cards, although, if you use this function when defaultDevice() is - * not a GUS device, it will be ignored. - * - * The parameter is an int [256] array, which contain the following: - * - * The first 0..127 integers, are the number of times each General MIDI patch - * will be used, and -1 when the corresponding patch won't be used. - * - * The 128..255 integers are the number of times each drum voice (each note - * on the drum channel) will be used, and -1 when the corresponding - * percussion won't be used. - * - * This is done this way so that if the user has very little memory on his - * GUS card, and not all patches will be loaded, they are at least - * reordered, so that it first loads the one you're going to use most. - * - * In case you don't worry about such users, or you don't know "a priori" - * the number of notes you're going to play, you can just use 1 for each - * patch you want to load and -1 in the rest. - * - * @see GUSOut::setPatchesToUse() - * @see GUSOut::loadPatch() - * - * @return 0 if ok, and -1 if there wasn't enough memory to load the patches - * in the card's memory. - */ - int setPatchesToUse(int *patchesused); - - /** - * Returns the filename where the Midi Mapper was loaded from, or "" if no - * MIDI Mapper is in use. - * - * @see setMidiMap() - */ - const char *midiMapFilename(void); - - /** - * Sets a MidiMapper object to use. This object should already have - * loaded the configuration. See the description of MidiMapper for - * more information. - * - * @see MidiMapper::MidiMapper() - * @see midiMapFilename() - */ - void setMidiMap(MidiMapper *map); - - /** - * Returns the SNDCTL_SEQ_CTRLRATE ioctl value - */ - int rate(void) { return m_rate; } - - /** - * Returns the number of MIDI ports available on the system. It's common that - * users have MIDI ports available, but there are no external synthesizers - * connected to these ports, so sending MIDI events to these ports will not - * produce any music in this case. - * - * @see synthDevices() - * @see setDefaultDevice() - */ - int midiPorts(void) { return n_midi; } - - /** - * Returns the number of internal synthesizers available on the system. Some - * of these devices will need special configuration, for example, to load - * sound patches. - * - * @see midiPorts() - * @see setDefaultDevice() - * @see setPatchesToUse() - */ - int synthDevices(void) { return n_synths; } - - /** - * Returns the name of the @p i-th device . In case the DeviceManager wasn't - * yet initialized ( see checkInit() ), the return value is NULL, and - * in case the parameter has a value out of the valid range ( 0 to - * midiPorts() + synthDevices() ) it returns an empty string. - */ - const char *name(int i); - - /** - * Returns the type of device the @p i-th device is , in a user-friendly - * string . For example, "External Midi Port" for midi ports, "FM" for FM - * synthesizers, "GUS" for Gravis Ultrasound devices, etc. - */ - const char *type(int i); - - private: - class DeviceManagerPrivate; - DeviceManagerPrivate *d; -}; - -#endif diff --git a/libkmid/fmout.cc b/libkmid/fmout.cc deleted file mode 100644 index bce421f81..000000000 --- a/libkmid/fmout.cc +++ /dev/null @@ -1,354 +0,0 @@ -/************************************************************************** - - fmout.cc - class fmOut which handles the /dev/sequencer device - for fm synths - This file is part of LibKMid 0.9.5 - Copyright (C) 1998,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "fmout.h" -#include -#include -#include -#include "sndcard.h" -#include -#include -#include -#include -#include -#include -#include "midispec.h" -#ifdef HAVE_CONFIG_H -#include -#endif - -SEQ_USE_EXTBUF(); - -FMOut::FMOut( int d, int total ) -{ - seqfd = -1; - devicetype = KMID_FM; - device = d; - _ok = 1; - // Put opl=3 for opl/3 (better quality/ 6 voices) - // or opl=2 for fm output (less quality/ 18 voices, which is better imho) : - opl = 2; - // But be aware that opl=3 is not intended to be fully supported by now - - nvoices = total; - vm = new VoiceManager (nvoices); -} - -FMOut::~FMOut() -{ - closeDev(); - delete vm; - if (deleteFMPatchesDirectory) - { - free((char *)FMPatchesDirectory); - deleteFMPatchesDirectory = 0; - FMPatchesDirectory="/etc"; - } -} - -void FMOut::openDev (int sqfd) -{ -#ifdef HAVE_OSS_SUPPORT - _ok=1; - seqfd = sqfd; - //vm->clearLists(); - if ( seqfd == -1 ) - { - printfdebug("ERROR: Could not open /dev/sequencer\n"); - return; - } - - loadFMPatches(); -#endif - -} - -void FMOut::closeDev (void) -{ - if (!ok()) return; - vm->clearLists(); - //if (seqfd>=0) close(seqfd); - seqfd = -1; -} - -void FMOut::initDev (void) -{ -#ifdef HAVE_OSS_SUPPORT - int chn; - if (!ok()) return; - uchar gm_reset[5]={0x7e, 0x7f, 0x09, 0x01, 0xf7}; - sysex(gm_reset, sizeof(gm_reset)); - for (chn=0;chn<16;chn++) - { - chnmute[chn]=0; - chnPatchChange(chn,0); - chnPressure(chn,127); - chnPitchBender(chn, 0x00, 0x40); - chnController(chn, CTL_MAIN_VOLUME,127); - chnController(chn, CTL_EXT_EFF_DEPTH, 0); - chnController(chn, CTL_CHORUS_DEPTH, 0); - chnController(chn, 0x4a, 127); - } - - if (opl==3) ioctl(seqfd, SNDCTL_FM_4OP_ENABLE, &device); - SEQ_VOLUME_MODE(device,VOL_METHOD_LINEAR); - - for (int i = 0; i < nvoices; i++) - { - SEQ_CONTROL(device, i, SEQ_VOLMODE, VOL_METHOD_LINEAR); - SEQ_STOP_NOTE(device, i, vm->note(i), 64); - } -#endif -} - -void FMOut::loadFMPatches(void) -{ -#ifdef HAVE_OSS_SUPPORT - char patchesfile[strlen(FMPatchesDirectory)+7+1]; - char drumsfile[strlen(FMPatchesDirectory)+9+1]; - int size; - struct sbi_instrument instr; - char tmp[60]; - int i,j; - for ( i=0; i<256; i++ ) - patchloaded[i] = 0; - int stereoeffect=rand()%3; - FILE *fh; - int datasize; - - if (opl==3) - { - snprintf(patchesfile, sizeof(patchesfile), "%s/std.o3",FMPatchesDirectory); - size=60; - } - else - { - snprintf(patchesfile, sizeof(patchesfile), "%s/std.sb",FMPatchesDirectory); - size=52; - } - fh=fopen(patchesfile,"rb"); - if (fh==NULL) return; - - for (i=0;i<128;i++) - { - fread(tmp,size,1,fh); - patchloaded[i]=1; - instr.key = ((strncmp(tmp, "4OP", 3) == 0))? OPL3_PATCH : FM_PATCH; - datasize = (strncmp(tmp, "4OP", 3) == 0)? 22 : 11; - instr.device=device; - instr.channel = i; - // Let's get some stereo effect ... - tmp[46] = (tmp[46] & 0xcf) | ((++stereoeffect)<<4); - stereoeffect=stereoeffect%3; - for (j=0; j<22; j++) - instr.operators[j] = tmp[j+36]; - SEQ_WRPATCH(&instr,sizeof(instr)); - } - fclose(fh); - - if (opl==3) - { - snprintf(drumsfile, sizeof(drumsfile), "%s/drums.o3",FMPatchesDirectory); - } - else - { - snprintf(drumsfile, sizeof(drumsfile), "%s/drums.sb",FMPatchesDirectory); - } - - fh=fopen(drumsfile,"rb"); - if (fh==NULL) return; - - for (i=128;i<175;i++) - { - fread(tmp,size,1,fh); - patchloaded[i]=1; - instr.key = (strncmp(tmp, "4OP", 3) == 0)? OPL3_PATCH : FM_PATCH; - datasize = (strncmp(tmp, "4OP", 3) == 0)? 22 : 11; - instr.device=device; - instr.channel = i; - // Let's get some stereo effect ... - tmp[46] = (tmp[46] & 0xcf) | ((++stereoeffect)<<4); - stereoeffect=stereoeffect%3; - for (j=0; j<22; j++) - instr.operators[j] = tmp[j+36]; - SEQ_WRPATCH(&instr,sizeof(instr)); - } - fclose(fh); - -#ifdef FMOUTDEBUG - printfdebug("Patches loaded\n"); -#endif -#endif -} - -int FMOut::patch(int p) -{ - if (patchloaded[p]==1) return p; -#ifdef FMOUTDEBUG - printfdebug("Not loaded %d!\n",p); -#endif - p=0; - while ((p<256)&&(patchloaded[p]==0)) p++; - return p; -} - -void FMOut::noteOn (uchar chn, uchar note, uchar vel) -{ - if (vel==0) - { - noteOff(chn,note,vel); - } - else - { - if (chn==PERCUSSION_CHANNEL) - { - if (patchloaded[note+128]==0) return; - else - if (patchloaded[chnpatch[chn]]==0) return; - } - int v=vm->allocateVoice(chn,note); - int p; - if (chn==PERCUSSION_CHANNEL) - SEQ_SET_PATCH(device,v ,p=patch(note+128)) - else - SEQ_SET_PATCH(device,v ,p=map->patch(chn,chnpatch[chn])); - SEQ_BENDER(device, v, chnbender[chn]); - - SEQ_START_NOTE(device, v, note, vel); - // SEQ_CONTROL(device, v, CTL_MAIN_VOLUME, chncontroller[chn][CTL_MAIN_VOLUME]); - - SEQ_CHN_PRESSURE(device, v , chnpressure[chn]); - } - -#ifdef FMOUTDEBUG - printfdebug("Note ON >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); -#endif -} - -void FMOut::noteOff (uchar chn, uchar note, uchar vel) -{ - int i; - vm->initSearch(); - while ((i=vm->search(chn,note))!=-1) - { - SEQ_STOP_NOTE(device, i, note, vel); - vm->deallocateVoice(i); - } - -#ifdef FMOUTDEBUG - printfdebug("Note OFF >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); -#endif -} - -void FMOut::keyPressure (uchar chn, uchar note, uchar vel) -{ - int i; - vm->initSearch(); - while ((i=vm->search(chn,note))!=-1) - SEQ_KEY_PRESSURE(device, i, note,vel); -} - -void FMOut::chnPatchChange (uchar chn, uchar patch) -{ - if (chn==PERCUSSION_CHANNEL) return; - int i; - vm->initSearch(); - while ((i=vm->search(chn))!=-1) - SEQ_SET_PATCH(device,i,map->patch(chn,patch)); - - chnpatch[chn]=patch; -} - -void FMOut::chnPressure (uchar chn, uchar vel) -{ - int i; - vm->initSearch(); - while ((i=vm->search(chn))!=-1) - SEQ_CHN_PRESSURE(device, i , vel); - - chnpressure[chn]=vel; -} - -void FMOut::chnPitchBender(uchar chn,uchar lsb, uchar msb) -{ - chnbender[chn]=((int)msb<<7) | (lsb & 0x7F); - - int i; - vm->initSearch(); - while ((i=vm->search(chn))!=-1) - SEQ_BENDER(device, i, chnbender[chn]); - -} - -void FMOut::chnController (uchar chn, uchar ctl, uchar v) -{ - if ((ctl==11)||(ctl==7)) - { - v=(v*volumepercentage)/100; - if (v>127) v=127; - } - int i; - vm->initSearch(); - while ((i=vm->search(chn))!=-1) - SEQ_CONTROL(device, i, ctl, v); - - chncontroller[chn][ctl]=v; -} - -void FMOut::sysex(uchar *, ulong ) -{ - -} - -void FMOut::setFMPatchesDirectory(const char *dir) -{ - if ((dir==NULL)||(dir[0]==0)) return; - if (deleteFMPatchesDirectory) - free((char *)FMPatchesDirectory); - - FMPatchesDirectory = strdup(dir); - - deleteFMPatchesDirectory=1; -} - -void FMOut::setVolumePercentage ( int i ) -{ -#ifdef HAVE_OSS_SUPPORT - int fd=open("/dev/mixer0",O_RDWR,0); - if (fd==-1) return; - int a=i*255/100; - if (a>255) a=255; - a=(a<<8) | a; - if (ioctl(fd,MIXER_WRITE(SOUND_MIXER_SYNTH),&a) == -1) - printfdebug("ERROR writing to mixer\n"); - close(fd); -#endif - volumepercentage=i; -} - - -const char *FMOut::FMPatchesDirectory = "/etc"; -int FMOut::deleteFMPatchesDirectory = 0; diff --git a/libkmid/fmout.h b/libkmid/fmout.h deleted file mode 100644 index 328ca5626..000000000 --- a/libkmid/fmout.h +++ /dev/null @@ -1,155 +0,0 @@ -/* fmout.h - class fmOut which handles the /dev/sequencer device - for FM synths - This file is part of LibKMid 0.9.5 - Copyright (C) 1998,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _FMOUT_H -#define _FMOUT_H - -#include -#include - -/** - * FM device output class . FMOut is used to send MIDI events to - * FM devices, such as AdLib cards, or OPL3 synthesizers. - * - * FMOut inherits MidiOut and supports the same simple API. - * - * The preferred way to use this class is by selecting a FM device - * on the MidiManager and using a MidiManager object directly - * - * @short Sends MIDI events to FM devices - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class KMID_EXPORT FMOut : public MidiOut -{ - private: - class FMOutPrivate; - FMOutPrivate *di; - - int patchloaded[256]; - /** - * Takes a value of 2 or 3, for FM or OPL3 support - */ - int opl; - int nvoices; - - VoiceManager *vm; - - void modifyPatch(char *buf, int key); - void loadFMPatches (void); - - public: - /** - * Constructor. See MidiOut::MidiOut() for more information. - */ - FMOut ( int d=0, int total =12 ); - - /** - * Destructor. - */ - ~FMOut (); - - /** - * See MidiOut::openDev() - */ - virtual void openDev ( int sqfd ); - - /** - * See MidiOut::closeDev() - */ - virtual void closeDev ( void ); - - /** - * See MidiOut::initDev() - */ - virtual void initDev ( void ); - - /** - * See MidiOut::noteOn() - */ - virtual void noteOn ( uchar chn, uchar note, uchar vel ); - - /** - * See MidiOut::noteOff() - */ - virtual void noteOff ( uchar chn, uchar note, uchar vel ); - - /** - * See MidiOut::keyPressure() - */ - virtual void keyPressure ( uchar chn, uchar note, uchar vel ); - - /** - * See MidiOut::chnPatchChange() - */ - virtual void chnPatchChange ( uchar chn, uchar patch ); - - /** - * See MidiOut::chnPressure() - */ - virtual void chnPressure ( uchar chn, uchar vel ); - - /** - * See MidiOut::chnPitchBender() - */ - virtual void chnPitchBender ( uchar chn, uchar lsb, uchar msb ); - - /** - * See MidiOut::chnController() - */ - virtual void chnController ( uchar chn, uchar ctl , uchar v ); - - /** - * It's an empty function, as FM devices don't support System Exclusive - * messages - */ - virtual void sysex ( uchar *data,ulong size); - - /** - * See MidiOut::setVolumePercentage() - */ - virtual void setVolumePercentage ( int i ); - - /** - * Returns @p p if the patch p has been loaded, or another patch (already loaded) - * if @p p hasn't been loaded. - */ - int patch(int p); - - private: - static const char *FMPatchesDirectory; - static int deleteFMPatchesDirectory; - - public: - /** - * Sets the directory where the FM patches are stored, that is, where the - * std.o3, std.sb, drums.o3 and drums.sb files can be found. - * - * It will store a copy of the parameter, so you should delete the memory - * used by the parameter you passed. - */ - static void setFMPatchesDirectory(const char *dir); - -}; - -#endif diff --git a/libkmid/gusout.cc b/libkmid/gusout.cc deleted file mode 100644 index 6b207956b..000000000 --- a/libkmid/gusout.cc +++ /dev/null @@ -1,691 +0,0 @@ -/************************************************************************** - - gusout.cc - class GUSOut which implements support for Gravis - Ultrasound cards through a /dev/sequencer device - This file is part of LibKMid 0.9.5 - Copyright (C) 1998,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "gusout.h" -#include "sndcard.h" -#include "midispec.h" -#include "gusvoices.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_CONFIG_H -#include -#endif - -SEQ_USE_EXTBUF(); - -#ifdef HAVE_OSS_SUPPORT -struct pat_header -{ - char magic[12]; - char version[10]; - char description[60]; - unsigned char instruments; - char voices; - char channels; - unsigned short nr_waveforms; - unsigned short master_volume; - unsigned long data_size; -}; -struct sample_header -{ - char name[7]; - unsigned char fractions; - long len; - long loop_start; - long loop_end; - unsigned short base_freq; - long low_note; - long high_note; - long base_note; - short detune; - unsigned char panning; - - unsigned char envelope_rate[6]; - unsigned char envelope_offset[6]; - - unsigned char tremolo_sweep; - unsigned char tremolo_rate; - unsigned char tremolo_depth; - - unsigned char vibrato_sweep; - unsigned char vibrato_rate; - unsigned char vibrato_depth; - - char modes; - - short scale_frequency; - unsigned short scale_factor; -}; - -int get_dint(unsigned char *p) -{ - unsigned int v=0; - - for (int i=0;i<4;i++) - { - v |= (p[i] << (i*8)); - } - return (int)v; -} - -unsigned short get_word(unsigned char *p) -{ - unsigned short v=0; - - for (int i=0;i<2;i++) - v |= (*p++ << (i*8)); - return (short)v; -} - -#endif - -GUSOut::GUSOut(int d,int total) -{ - seqfd = -1; - devicetype=KMID_GUS; - device= d; - _ok=1; - - use8bit=0; - nvoices=total; - vm=new VoiceManager(nvoices); -} - -GUSOut::~GUSOut() -{ - closeDev(); - - delete vm; - if (delete_GUS_patches_directory) - { - free((char *)GUS_patches_directory); - delete_GUS_patches_directory = 0; - GUS_patches_directory="/etc"; - } -} - -void GUSOut::openDev (int sqfd) -{ - _ok=1; - seqfd = sqfd; - //vm->clearLists(); - if (seqfd==-1) - { - printfdebug("ERROR: Could not open /dev/sequencer\n"); - return; - } - -#ifdef HAVE_OSS_SUPPORT - - //seqbuf_clean(); - //ioctl(seqfd,SNDCTL_SEQ_RESET); - //ioctl(seqfd,SNDCTL_SEQ_PANIC); - - if (ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &device)==-1) - { - printfdebug("Error reseting gus samples. Please report\n"); - }; - use8bit=0; - totalmemory = device; - ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &totalmemory); - freememory = device; - ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &freememory); - -#endif - - -} - -void GUSOut::closeDev (void) -{ - if (!ok()) return; - vm->clearLists(); - //if (seqfd>=0) - // close(seqfd); - seqfd=-1; -} - -void GUSOut::initDev (void) -{ -#ifdef HAVE_OSS_SUPPORT - int chn; - if (!ok()) return; - uchar gm_reset[5]={0x7e, 0x7f, 0x09, 0x01, 0xf7}; - sysex(gm_reset, sizeof(gm_reset)); - for (chn=0;chn<16;chn++) - { - chnmute[chn]=0; - chnPatchChange(chn,0); - // chnPressure(chn,127); - chnPitchBender(chn, 0x00, 0x40); - chnController(chn, CTL_MAIN_VOLUME,127); - chnController(chn, CTL_EXT_EFF_DEPTH, 0); - chnController(chn, CTL_CHORUS_DEPTH, 0); - chnController(chn, 0x4a, 127); - } - - - for (int i = 0; i < nvoices; i++) - { - SEQ_CONTROL(device, i, SEQ_VOLMODE, VOL_METHOD_LINEAR); - SEQ_STOP_NOTE(device, i, vm->note(i), 64); - } - -#endif -} - - -int GUSOut::patch(int p) -{ - if (patchloaded[p]==1) return p; - printfdebug("Not loaded %d!\n",p); - p=0; - while ((p<256)&&(patchloaded[p]==0)) p++; - return p; -} - -void GUSOut::noteOn (uchar chn, uchar note, uchar vel) -{ - if (vel==0) - { - noteOff(chn,note,vel); - } - else - { - if (chn==PERCUSSION_CHANNEL) - { - if (patchloaded[note+128]==0) return; - else - if (patchloaded[chnpatch[chn]]==0) return; - }; - int v=vm->allocateVoice(chn,note); - int p; - if (chn==PERCUSSION_CHANNEL) - SEQ_SET_PATCH(device,v ,p=patch(note+128)) - else - SEQ_SET_PATCH(device,v ,p=map->patch(chn,chnpatch[chn])); - SEQ_BENDER(device, v, chnbender[chn]); - - SEQ_START_NOTE(device, v, note, vel); - // SEQ_CONTROL(device, v, CTL_MAIN_VOLUME, chncontroller[chn][CTL_MAIN_VOLUME]); - SEQ_CHN_PRESSURE(device, v , chnpressure[chn]); - } - - printfdebug("Note ON >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); -} - -void GUSOut::noteOff (uchar chn, uchar note, uchar vel) -{ - int i; - vm->initSearch(); - while ((i=vm->search(chn,note))!=-1) - { - SEQ_STOP_NOTE(device, i, note, vel); - vm->deallocateVoice(i); - } - -#ifdef GUSOUTDEBUG - printf("Note OFF >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); -#endif -} - -void GUSOut::keyPressure (uchar chn, uchar note, uchar vel) -{ - int i; - vm->initSearch(); - while ((i=vm->search(chn,note))!=-1) - SEQ_KEY_PRESSURE(device, i, note,vel); -} - -void GUSOut::chnPatchChange (uchar chn, uchar patch) -{ - if (chn==PERCUSSION_CHANNEL) return; - int i; - vm->initSearch(); - while ((i=vm->search(chn))!=-1) - SEQ_SET_PATCH(device,i,map->patch(chn,patch)); - chnpatch[chn]=patch; - -} - -void GUSOut::chnPressure (uchar /*chn*/, uchar /*vel*/) -{ - /* int i; - vm->initSearch(); - while ((i=vm->search(chn))!=-1) - SEQ_CHN_PRESSURE(device, i , vel); - chnpressure[chn]=vel; - */ -} - -void GUSOut::chnPitchBender(uchar chn,uchar lsb, uchar msb) -{ - chnbender[chn]=((int)msb<<7) | (lsb & 0x7F); - - int i; - vm->initSearch(); - while ((i=vm->search(chn))!=-1) - SEQ_BENDER(device, i, chnbender[chn]); -} - -void GUSOut::chnController (uchar chn, uchar ctl, uchar v) -{ - if ((ctl==11)||(ctl==7)) - { - v=(v*volumepercentage)/100; - if (v>127) v=127; - }; - - int i; - vm->initSearch(); - while ((i=vm->search(chn))!=-1) - SEQ_CONTROL(device, i, ctl, v); - - chncontroller[chn][ctl]=v; -} - -void GUSOut::sysex(uchar *, ulong ) -{ - -} - -void GUSOut::setGUSPatchesDirectory(const char *dir) -{ - if ((dir==NULL)||(dir[0]==0)) return; - if (delete_GUS_patches_directory) - free((char *)GUS_patches_directory); - - GUS_patches_directory = strdup(dir); - delete_GUS_patches_directory=1; -} - -const char *GUSOut::patchName(int pgm) -{ - return GUS_voice_names[pgm]; -} - - -int GUSOut::loadPatch(int pgm) -{ -#ifdef HAVE_OSS_SUPPORT - struct pat_header header; - struct sample_header sample; - if (patchloaded[pgm]==1) - { -#ifdef GUSOUTDEBUG - printf("Trying to reload a patch. This should never happen, please report.\n"); -#endif - return 0; - } - if ((patchName(pgm)==NULL)||((patchName(pgm))[0]==0)) - { -#ifdef GUSOUTDEBUG - printf("Couldn't guess patch name for patch number %d\n",pgm); -#endif - return -1; - } - char *s=new char[strlen(GUS_patches_directory)+strlen(patchName(pgm))+10]; - if (s==NULL) return -1; - sprintf(s,"%s/%s.pat",GUS_patches_directory,patchName(pgm)); -#ifdef GUSOUTDEBUG - printf("Loading patch : %s\n",s); -#endif - struct patch_info *patch=NULL; - struct stat info; - if (stat(s, &info)==-1) - { -#ifdef GUSOUTDEBUG - printf("File %s doesn't exist\n",s); -#endif - return -1; - } - - FILE *fh=fopen(s,"rb"); - if (fh==NULL) - { -#ifdef GUSOUTDEBUG - printf("Couldn't open patch %s\n",s); -#endif - return -1; - } - - unsigned char tmp[256]; - if (fread(tmp,1,0xef,fh)!=0xef) - { - fclose(fh); -#ifdef GUSOUTDEBUG - printf("Short file ! \n"); -#endif - return -1; - } - memcpy ((char *) &header, tmp, sizeof (header)); - - if (strncmp(header.magic,"GF1PATCH110",12)!=0) - { -#ifdef GUSOUTDEBUG - printf("File %s is corrupted or it isn't a patch file\n",s); -#endif - return -1; - } - if (strncmp(header.version,"ID#000002",10)!=0) - { -#ifdef GUSOUTDEBUG - printf("File %s's version is not supported\n",s); -#endif - return -1; - } - unsigned short nWaves= *(unsigned short *)&tmp[85]; -#ifdef GUSOUTDEBUG - unsigned short masterVolume= *(unsigned short *)&tmp[87]; - printf("nWaves: %d\n",nWaves); - printf("masterVolume : %d\n",masterVolume); -#endif - - unsigned short i; - int offset=0xef; - for (i=0;ikey = GUS_PATCH; - patch->device_no = device; - patch->instr_no = pgm; - patch->mode = sample.modes | WAVE_TREMOLO | WAVE_VIBRATO | WAVE_SCALE; - patch->len = sample.len; - patch->loop_start = sample.loop_start; - patch->loop_end = sample.loop_end; - patch->base_note = sample.base_note; - patch->high_note = sample.high_note; - patch->low_note = sample.low_note; - patch->base_freq = sample.base_freq; - patch->detuning = sample.detune; - patch->panning = (sample.panning - 7) * 16; - - memcpy (patch->env_rate, sample.envelope_rate, 6); - memcpy (patch->env_offset, sample.envelope_offset, 6); - - patch->tremolo_sweep = sample.tremolo_sweep; - patch->tremolo_rate = sample.tremolo_rate; - patch->tremolo_depth = sample.tremolo_depth; - - patch->vibrato_sweep = sample.vibrato_sweep; - patch->vibrato_rate = sample.vibrato_rate; - patch->vibrato_depth = sample.vibrato_depth; - - patch->scale_frequency = sample.scale_frequency; - patch->scale_factor = sample.scale_factor; - - patch->volume = header.master_volume; - - if (fseek (fh, offset, 0) == -1) - { - fclose(fh); - return -1; - } - - if ((long)fread (patch->data, 1,sample.len,fh) != sample.len) - { -#ifdef GUSOUTDEBUG - printf ("Short file\n"); -#endif - return -1; - } - - SEQ_WRPATCH (patch, sizeof (*patch) + sample.len); - - offset = offset + sample.len; - - } - patchloaded[pgm]=1; - - fclose(fh); - free(patch); // Shouldn't this 'free' be within the 'for' loop ? - delete s; - freememory = device; - ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &freememory); -#endif - return 0; -} - - -void GUSOut::setPatchesToUse(int *patchesused) -{ -#ifdef HAVE_OSS_SUPPORT - int k; - for (k=0;k<256;k++) patchloaded[k]=0; - - int patchesordered[256]; //This holds the pgm used ordered by a method which - // put first the patches more oftenly used, and then the least - // In example, if a song only uses a piano and a splash cymbal, - // This is set to : 0,188,-1,-1,-1,-1 ... - patchesLoadingOrder(patchesused,patchesordered); - - // If above line doesn't work, perhaps you could try this ? : - // for (int j=0;j<256;j++) patchesordered[j]=patchesused[j]; -#ifdef GUSOUTDEBUG - printf("Patches used : \n"); - for (k=0;k<256;k++) - { - if (patchesused[k]!=-1) printf("%d,",patchesused[k]); - } - printf("\n Patches used, sorted :\n"); - for (k=0;k<256;k++) - { - if (patchesordered[k]!=-1) printf("%d,",patchesordered[k]); - } -#endif - - int i=0; - while (patchesordered[i]!=-1) - { -#ifdef GUSOUTDEBUG - printf("Load Patch : %d\n",patchesordered[i]); -#endif - loadPatch(patchesordered[i]); - i++; - } -#endif -} - -int compare_decreasing(const void *a,const void *b) -{ - struct instr_gm - { - int used; - int pgm; - }; - instr_gm *ai=(instr_gm *)a; - instr_gm *bi=(instr_gm *)b; - return ai->usedused; -} - - -void GUSOut::patchesLoadingOrder(int *patchesused,int *patchesordered) -{ - struct instr_gm - { - int used; - int pgm; - }; - - instr_gm tempmelody[128]; - instr_gm tempdrums[128]; - int i,j; - for (i=0,j=128;i<128;i++,j++) - { - tempmelody[i].used=patchesused[i]; - tempmelody[i].pgm=i; - tempdrums[i].used=patchesused[j]; - tempdrums[i].pgm=j; - } - /* SORT */ // Decreasing order (first most used patch, then less used patch) - qsort(&tempmelody[0],128,sizeof(instr_gm),compare_decreasing); - qsort(&tempdrums[0],128,sizeof(instr_gm),compare_decreasing); - - /* Once they are sorted, the result is put on patchesordered in the following - * way : If tempmelody is : M0 M1 M2 M3 ... M127 and tempdrums is : - * D0 D1 D2 D3 ... D127, the result is : - * M0 D0 M1 M2 D1 M3 M4 D2 M5 M6 D3 ... - * P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 ... - */ - -#ifdef GUSOUTDEBUG - for (int k=0;k<128;k++) - { - printf("%d - %d\n",tempmelody[k].used,tempmelody[k].pgm); - } - for (int k=0;k<128;k++) - { - printf("%d : %d\n",tempdrums[k].used,tempdrums[k].pgm); - } -#endif - - i=0; - int totalmelody=0; - while ((i<128)&&(tempmelody[i].used!=0)) - { - totalmelody++; - i++; - } - i=0; - int totaldrums=0; - while ((i<128)&&(tempdrums[i].used!=0)) - { - totaldrums++; - i++; - } -#ifdef GUSOUTDEBUG - printf("Totalmelody : %d,totaldrums : %d\n",totalmelody,totaldrums); -#endif - int tgt=0; - - int tm=totalmelody; - int td=totaldrums; - int cm,cd; - cm=cd=0; - if ((tm!=0)&&(td!=0)) - { - patchesordered[0]=tempmelody[0].pgm; - patchesordered[1]=tempdrums[0].pgm; - tm--;td--; - cm++;cd++; - tgt+=2; - while ((tm>0)&&(td>0)) - { - if (((tgt-1)%3)==0) - { - patchesordered[tgt]=tempdrums[cd].pgm; - cd++; - td--; - } - else - { - patchesordered[tgt]=tempmelody[cm].pgm; - cm++; - tm--; - } - tgt++; - } - } - while (tm>0) - { - patchesordered[tgt]=tempmelody[cm].pgm; - tgt++; - cm++; - tm--; - } - while (td>0) - { - patchesordered[tgt]=tempdrums[cd].pgm; - tgt++; - cd++; - td--; - } - - // Now we put as not used (-1) the rest of the array - while (tgt<256) - { - patchesordered[tgt]=-1; - tgt++; - } -} - -//char *GUSOut::GUS_patches_directory="/mnt/dosc/gravis/patches"; -const char *GUSOut::GUS_patches_directory="/usr/share/ultrasnd"; - -int GUSOut::delete_GUS_patches_directory = 0; -/* No, this doesn't delete any file :-) it's just for internal use */ diff --git a/libkmid/gusout.h b/libkmid/gusout.h deleted file mode 100644 index 1fd8a3cbd..000000000 --- a/libkmid/gusout.h +++ /dev/null @@ -1,180 +0,0 @@ -/* gusout.h - class gusOut which implements support for Gravis - Ultrasound cards through a /dev/sequencer device - This file is part of LibKMid 0.9.5 - Copyright (C) 1998,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _GUSOUT_H -#define _GUSOUT_H - -#include -#include - -/** - * Gravis Ultrasound synthesizer output class . This class is used to send midi - * events to synthesizers on GUS cards. - * - * GUSOut inherits MidiOut and supports the same simple API. - * - * The recommended way to use this class is by using a DeviceManager - * object, and use the DeviceManager::setPatchesToUse() member which will - * call the setPatchesToUse() member in this class. - * - * @short Sends MIDI events to GUS synths - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class GUSOut : public MidiOut -{ - private: - class GUSOutPrivate; - GUSOutPrivate *di; - - int patchloaded[256]; - int nvoices; - - int use8bit; // Use 8 bit patches, instead of 16 bits to use less memory - VoiceManager *vm; - - int totalmemory; // Total memory in soundcard - int freememory; // Free memory - - - void patchesLoadingOrder(int *patchesused,int *patchesordered); - const char *patchName(int pgm); - - public: - /** - * Constructor. See MidiOut::MidiOut() for more information. - */ - GUSOut(int d=0,int total =12); - - /** - * Destructor. - */ - ~GUSOut(); - - /** - * See MidiOut::openDev() - */ - virtual void openDev (int sqfd); - - /** - * See MidiOut::closeDev() - */ - virtual void closeDev (void); - - /** - * See MidiOut::initDev() - */ - virtual void initDev (void); - - /** - * See MidiOut::noteOn() - */ - virtual void noteOn ( uchar chn, uchar note, uchar vel ); - - /** - * See MidiOut::noteOff() - */ - virtual void noteOff ( uchar chn, uchar note, uchar vel ); - - /** - * See MidiOut::keyPressure() - */ - virtual void keyPressure ( uchar chn, uchar note, uchar vel ); - - /** - * See MidiOut::chnPatchChange() - */ - virtual void chnPatchChange ( uchar chn, uchar patch ); - - /** - * See MidiOut::chnPressure() - */ - virtual void chnPressure ( uchar chn, uchar vel ); - - /** - * See MidiOut::chnPitchBender() - */ - virtual void chnPitchBender ( uchar chn, uchar lsb, uchar msb ); - - /** - * See MidiOut::chnController() - */ - virtual void chnController ( uchar chn, uchar ctl , uchar v ); - - /** - * It's an empty function, as GUS synths don't support System Exclusive - * messages - */ - virtual void sysex ( uchar *data,ulong size); - - /** - * See DeviceManager::setPatchesToUse() . All the information about this - * member is explained there because it's (for now) just a simple call to this - * function when the device used is a GUS device, and you're supposed to use - * a DeviceManager object instead of a GUSOut object except in rare ocassions. - * - * @see patch() - * @see loadPatch() - */ - void setPatchesToUse(int *patchesused); - - /** - * Loads a single patch on the synthesizer memory. - * @param pgm is the number of the GM patch when pgm is between 0 and 127. - * Values from 128 to 255 are used to represent the percussion instruments. - * @return 0 if OK and -1 if there was an error (patch not found, not enough - * memory, etc.) - * - * @see patch() - * @see setPatchesToUse() - */ - int loadPatch (int pgm); - - /** - * Returns p if the patch with number p has been correctly loaded. - * In the case it hasn't been loaded, it returns the number of another patch - * that is loaded and that should be used instead. - * - * @see loadPatch() - * @see setPatchesToUse() - */ - int patch(int p); - - private: - static const char *GUS_patches_directory; - static int delete_GUS_patches_directory; - - public: - /** - * Sets the directory where the GUS patches are stored, that is, where the - * acpiano.pat, ... files can be found. - * - * It will store a copy of the parameter, so you should delete the memory - * used by the parameter you passed. - */ - static void setGUSPatchesDirectory(const char *dir); - -}; - -#endif diff --git a/libkmid/gusvoices.h b/libkmid/gusvoices.h deleted file mode 100644 index da364eb18..000000000 --- a/libkmid/gusvoices.h +++ /dev/null @@ -1,286 +0,0 @@ -/* gusvoices.h - struct with Gravis Ultrasound patches' names - This file is part of LibKMid 0.9.5 - Copyright (C) 1998,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -const char GUS_voice_names[256][9] = -{ - /* 0 */ "acpiano", - /* 1 */ "britepno", - /* 2 */ "synpiano", - /* 3 */ "honky", - /* 4 */ "epiano1", - /* 5 */ "epiano2", - /* 6 */ "hrpschrd", - /* 7 */ "clavinet", - /* 8 */ "celeste", - /* 9 */ "glocken", - /* 10 */ "musicbox", - /* 11 */ "vibes", - /* 12 */ "marimba", - /* 13 */ "xylophon", - /* 14 */ "tubebell", - /* 15 */ "santur", - /* 16 */ "homeorg", - /* 17 */ "percorg", - /* 18 */ "rockorg", - /* 19 */ "church", - /* 20 */ "reedorg", - /* 21 */ "accordn", - /* 22 */ "harmonca", - /* 23 */ "concrtna", - /* 24 */ "nyguitar", - /* 25 */ "acguitar", - /* 26 */ "jazzgtr", - /* 27 */ "cleangtr", - /* 28 */ "mutegtr", - /* 29 */ "odguitar", - /* 30 */ "distgtr", - /* 31 */ "gtrharm", - /* 32 */ "acbass", - /* 33 */ "fngrbass", - /* 34 */ "pickbass", - /* 35 */ "fretless", - /* 36 */ "slapbas1", - /* 37 */ "slapbas2", - /* 38 */ "synbass1", - /* 39 */ "synbass2", - /* 40 */ "violin", - /* 41 */ "viola", - /* 42 */ "cello", - /* 43 */ "contraba", -// /* 44 */ "marcato", - /* 44 */ "tremstr", - /* 45 */ "pizzcato", - /* 46 */ "harp", - /* 47 */ "timpani", - /* 48 */ "marcato", - /* 49 */ "slowstr", - /* 50 */ "synstr1", - /* 51 */ "synstr2", - /* 52 */ "choir", - /* 53 */ "doo", - /* 54 */ "voices", - /* 55 */ "orchhit", - /* 56 */ "trumpet", - /* 57 */ "trombone", - /* 58 */ "tuba", - /* 59 */ "mutetrum", - /* 60 */ "frenchrn", - /* 61 */ "hitbrass", - /* 62 */ "synbras1", - /* 63 */ "synbras2", - /* 64 */ "sprnosax", - /* 65 */ "altosax", - /* 66 */ "tenorsax", - /* 67 */ "barisax", - /* 68 */ "oboe", - /* 69 */ "englhorn", - /* 70 */ "bassoon", - /* 71 */ "clarinet", - /* 72 */ "piccolo", - /* 73 */ "flute", - /* 74 */ "recorder", - /* 75 */ "woodflut", - /* 76 */ "bottle", - /* 77 */ "shakazul", - /* 78 */ "whistle", - /* 79 */ "ocarina", - /* 80 */ "sqrwave", - /* 81 */ "sawwave", - /* 82 */ "calliope", - /* 83 */ "chiflead", -// /* 84 */ "voxlead", - /* 84 */ "charang", - /* 85 */ "voxlead", - /* 86 */ "lead5th", - /* 87 */ "basslead", - /* 88 */ "fantasia", - /* 89 */ "warmpad", - /* 90 */ "polysyn", - /* 91 */ "ghostie", - /* 92 */ "bowglass", - /* 93 */ "metalpad", - /* 94 */ "halopad", - /* 95 */ "sweeper", - /* 96 */ "aurora", - /* 97 */ "soundtrk", - /* 98 */ "crystal", - /* 99 */ "atmosphr", - /* 100 */ "freshair", - /* 101 */ "unicorn", -// /* 102 */ "sweeper", - /* 102 */ "echovox", - /* 103 */ "startrak", - /* 104 */ "sitar", - /* 105 */ "banjo", - /* 106 */ "shamisen", - /* 107 */ "koto", - /* 108 */ "kalimba", - /* 109 */ "bagpipes", - /* 110 */ "fiddle", - /* 111 */ "shannai", - /* 112 */ "carillon", - /* 113 */ "agogo", - /* 114 */ "steeldrm", - /* 115 */ "woodblk", - /* 116 */ "taiko", - /* 117 */ "toms", - /* 118 */ "syntom", - /* 119 */ "revcym", - /* 120 */ "fx-fret", - /* 121 */ "fx-blow", - /* 122 */ "seashore", - /* 123 */ "jungle", - /* 124 */ "telephon", - /* 125 */ "helicptr", - /* 126 */ "applause", - /* 127 */ "pistol", - - "", /* 128 = drum 0*/ - "", /* 129 = drum 1*/ - "", /* 130 = drum 2*/ - "", /* 131 = drum 3*/ - "", /* 132 = drum 4*/ - "", /* 133 = drum 5*/ - "", /* 134 = drum 6*/ - "", /* 135 = drum 7*/ - "", /* 136 = drum 8*/ - "", /* 137 = drum 9*/ - "", /* 138 = drum 10*/ - "", /* 139 = drum 11*/ - "", /* 140 = drum 12*/ - "", /* 141 = drum 13*/ - "", /* 142 = drum 14*/ - "", /* 143 = drum 15*/ - "", /* 144 = drum 16*/ - "", /* 145 = drum 17*/ - "", /* 146 = drum 18*/ - "", /* 147 = drum 19*/ - "", /* 148 = drum 20*/ - "", /* 149 = drum 21*/ - "", /* 150 = drum 22*/ - "", /* 151 = drum 23*/ - "", /* 152 = drum 24*/ - "", /* 153 = drum 25*/ - "", /* 154 = drum 26*/ - "highq", /* 155 = drum 27*/ - "slap", /* 156 = drum 28*/ - "scratch1", /* 157 = drum 29*/ - "scratch2", /* 158 = drum 30*/ - "sticks", /* 159 = drum 31*/ - "sqrclick", /* 160 = drum 32*/ - "metclick", /* 161 = drum 33*/ - "metbell", /* 162 = drum 34*/ - "kick1", /* 163 = drum 35*/ - "kick2", /* 164 = drum 36*/ - "stickrim", /* 165 = drum 37*/ - "snare1", /* 166 = drum 38*/ - "claps", /* 167 = drum 39*/ - "snare2", /* 168 = drum 40*/ - "tomlo2", /* 169 = drum 41*/ - "hihatcl", /* 170 = drum 42*/ - "tomlo1", /* 171 = drum 43*/ - "hihatpd", /* 172 = drum 44*/ - "tommid2", /* 173 = drum 45*/ - "hihatop", /* 174 = drum 46*/ - "tommid1", /* 175 = drum 47*/ - "tomhi2", /* 176 = drum 48*/ - "cymcrsh1", /* 177 = drum 49*/ - "tomhi1", /* 178 = drum 50*/ - "cymride1", /* 179 = drum 51*/ - "cymchina", /* 180 = drum 52*/ - "cymbell", /* 181 = drum 53*/ - "tamborin", /* 182 = drum 54*/ - "cymsplsh", /* 183 = drum 55*/ - "cowbell", /* 184 = drum 56*/ - "cymcrsh2", /* 185 = drum 57*/ - "vibslap", /* 186 = drum 58*/ - "cymride2", /* 187 = drum 59*/ - "bongohi", /* 188 = drum 60*/ - "bongolo", /* 189 = drum 61*/ - "congahi1", /* 190 = drum 62*/ - "congahi2", /* 191 = drum 63*/ - "congalo", /* 192 = drum 64*/ - "timbaleh", /* 193 = drum 65*/ - "timbalel", /* 194 = drum 66*/ - "agogohi", /* 195 = drum 67*/ - "agogolo", /* 196 = drum 68*/ - "cabasa", /* 197 = drum 69*/ - "maracas", /* 198 = drum 70*/ - "whistle1", /* 199 = drum 71*/ - "whistle2", /* 200 = drum 72*/ - "guiro1", /* 201 = drum 73*/ - "guiro2", /* 202 = drum 74*/ - "clave", /* 203 = drum 75*/ - "woodblk1", /* 204 = drum 76*/ - "woodblk2", /* 205 = drum 77*/ - "cuica1", /* 206 = drum 78*/ - "cuica2", /* 207 = drum 79*/ - "triangl1", /* 208 = drum 80*/ - "triangl2", /* 209 = drum 81*/ - "shaker", /* 210 = drum 82*/ - "jingles", /* 211 = drum 83*/ - "belltree", /* 212 = drum 84*/ - "castinet", /* 213 = drum 85*/ - "surdo1", /* 214 = drum 86*/ - "surdo2", /* 215 = drum 87*/ - "", /* 216 = drum 88*/ - "", /* 217 = drum 89*/ - "", /* 218 = drum 90*/ - "", /* 219 = drum 91*/ - "", /* 220 = drum 92*/ - "", /* 221 = drum 93*/ - "", /* 222 = drum 94*/ - "", /* 223 = drum 95*/ - "", /* 224 = drum 96*/ - "", /* 225 = drum 97*/ - "", /* 226 = drum 98*/ - "", /* 227 = drum 99*/ - "", /* 228 = drum 100*/ - "", /* 229 = drum 101*/ - "", /* 230 = drum 102*/ - "", /* 231 = drum 103*/ - "", /* 232 = drum 104*/ - "", /* 233 = drum 105*/ - "", /* 234 = drum 106*/ - "", /* 235 = drum 107*/ - "", /* 236 = drum 108*/ - "", /* 237 = drum 109*/ - "", /* 238 = drum 110*/ - "", /* 239 = drum 111*/ - "", /* 240 = drum 112*/ - "", /* 241 = drum 113*/ - "", /* 242 = drum 114*/ - "", /* 243 = drum 115*/ - "", /* 244 = drum 116*/ - "", /* 245 = drum 117*/ - "", /* 246 = drum 118*/ - "", /* 247 = drum 119*/ - "", /* 248 = drum 120*/ - "", /* 249 = drum 121*/ - "", /* 250 = drum 122*/ - "", /* 251 = drum 123*/ - "", /* 252 = drum 124*/ - "", /* 253 = drum 125*/ - "", /* 254 = drum 126*/ - "" /* 255 = drum 127*/ -}; diff --git a/libkmid/libkmid.cc b/libkmid/libkmid.cc deleted file mode 100644 index 59e96ad0f..000000000 --- a/libkmid/libkmid.cc +++ /dev/null @@ -1,263 +0,0 @@ -/************************************************************************** - - libkmid.cc - class KMidSimpleAPI that makes it easy to use libkmid - and a C wrapper. - This file is part of LibKMid 0.9.5 - Copyright (C) 2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ - -#include "libkmid.h" -#include -#include -#include -#include -#include -#include - -#include "deviceman.h" -#include "player.h" -#include "midimapper.h" - -struct kMidData kMid; - -int KMidSimpleAPI::kMidInit(void) -{ - kMid.midi = new DeviceManager(); - if ( kMid.midi == 0L ) return 1; - kMid.midi->initManager(); - if (!kMid.midi->ok()) return 1; - - kMid.pctlsmID=shmget(getpid(),sizeof(PlayerController),0600 | IPC_CREAT); - if (kMid.pctlsmID==-1) return 1; - kMid.pctl=(PlayerController *)shmat(kMid.pctlsmID,NULL,0); - if (kMid.pctl==NULL) return 1; - - kMid.player=new MidiPlayer(kMid.midi,kMid.pctl); - if ( kMid.player == 0L ) - { - delete kMid.midi; - return 1; - } - - kMid.player->setParseSong(false); - - kMid.pctl->message=0; - kMid.pctl->gm=1; - kMid.pctl->error=0; - kMid.pctl->ratioTempo=1.0; - kMid.pctl->tempo=500000; - kMid.pctl->volumepercentage=100; - for (int i=0;i<16;i++) - { - kMid.pctl->forcepgm[i]=0; - kMid.pctl->pgm[i]=0; - } - - return 0; -} - -int KMidSimpleAPI::kMidLoad(const char *filename) -{ - if (kMidDevices()==0) return 0; - return kMid.player->loadSong(filename); -} - -int KMidSimpleAPI::kMidPlay(int loop) -{ - if (kMidDevices()==0) return 4; - if (!kMid.player->isSongLoaded()) return 1; - if (kMid.pctl->playing==1) return 2; - if (kMid.midi->checkInit()==-1) return 3; - kMid.pctl->message=0; - kMid.pctl->playing=0; - kMid.pctl->finished=0; - kMid.pctl->error=0; - kMid.pctl->SPEVplayed=0; - kMid.pctl->SPEVprocessed=0; - kMid.pctl->millisecsPlayed=0; - if ((kMid.pid=fork())==0) - { - if (loop) - { - while (1) - { - kMid.player->play(); - if (kMid.pctl->error) return 5; - kMid.pctl->message=0; - kMid.pctl->playing=0; - kMid.pctl->finished=0; - kMid.pctl->error=0; - kMid.pctl->SPEVplayed=0; - kMid.pctl->SPEVprocessed=0; - kMid.pctl->millisecsPlayed=0; - } - - } else { - kMid.player->play(); - if (kMid.pctl->error) return 5; - } - _exit(0); - } else return 4; - return 0; -} - -int KMidSimpleAPI::kMidStop(void) -{ - if (kMidDevices()==0) return 4; - if (kMid.pctl->playing==0) return 1; - if (kMid.pid!=0) - { - kill(kMid.pid,SIGTERM); - waitpid(kMid.pid, NULL, 0); - kMid.pid=0; - } else return 2; - - kMid.pctl->playing=0; - return 0; -} - -void KMidSimpleAPI::kMidDestruct(void) -{ - delete kMid.midi; - kMid.midi=0L; - delete kMid.player; - kMid.player=0L; - delete kMid.map; - shmdt((char *)kMid.pctl); - shmctl(kMid.pctlsmID, IPC_RMID, 0L); -} - -int KMidSimpleAPI::kMidIsPlaying(void) -{ - return kMid.pctl->playing; -} - -int KMidSimpleAPI::kMidDevices(void) -{ - return kMid.midi->midiPorts()+kMid.midi->synthDevices(); -} - -const char * KMidSimpleAPI::kMidName(int i) -{ - return kMid.midi->name(i); -} - -const char * KMidSimpleAPI::kMidType(int i) -{ - return kMid.midi->type(i); -} - -void KMidSimpleAPI::kMidSetDevice(int i) -{ - kMid.midi->setDefaultDevice(i); -} - -void KMidSimpleAPI::kMidSetMidiMapper(const char *mapfilename) -{ - if (kMidDevices()==0) return; - kMid.map=new MidiMapper(mapfilename); - if ((kMid.map->ok() == 0L)||(!kMid.map->ok())) return; - kMid.midi->setMidiMap(kMid.map); -} - -const char *KMidSimpleAPI::kMidVersion(void) -{ - return "0.9.5"; -} - -const char *KMidSimpleAPI::kMidCopyright(void) -{ - return "LibKMid 0.9.5 (C)1997-2000 Antonio Larrosa Jimenez .Malaga(es)"; -} - -/* * * * * * - - Under this line (------) there's only a C wrapper for the KMidSimpleAPI class - -* * * * * */ - - -int kMidInit(void) -{ - return KMidSimpleAPI::kMidInit(); -} - -int kMidLoad(const char *filename) -{ - return KMidSimpleAPI::kMidLoad(filename); -} - -int kMidPlay(void) -{ - return KMidSimpleAPI::kMidPlay(); -} - -int kMidStop(void) -{ - return KMidSimpleAPI::kMidStop(); -} - -void kMidDestruct(void) -{ - KMidSimpleAPI::kMidDestruct(); -} - -int kMidIsPlaying(void) -{ - return KMidSimpleAPI::kMidIsPlaying(); -} - -int kMidDevices(void) -{ - return KMidSimpleAPI::kMidDevices(); -} - -const char *kMidName(int i) -{ - return KMidSimpleAPI::kMidName(i); -} - -const char *kMidType(int i) -{ - return KMidSimpleAPI::kMidType(i); -} - -void kMidSetDevice(int i) -{ - KMidSimpleAPI::kMidSetDevice(i); -} - -void kMidSetMidiMapper(const char *mapfilename) -{ - KMidSimpleAPI::kMidSetMidiMapper(mapfilename); -} - -const char *kMidVersion(void) -{ - return KMidSimpleAPI::kMidVersion(); -} - -const char *kMidCopyright(void) -{ - return KMidSimpleAPI::kMidCopyright(); -} - diff --git a/libkmid/libkmid.h b/libkmid/libkmid.h deleted file mode 100644 index 53f765093..000000000 --- a/libkmid/libkmid.h +++ /dev/null @@ -1,226 +0,0 @@ -/* libkmid.h - class KMidSimpleAPI that makes it easy to use libkmid - and a C wrapper. - This file is part of LibKMid 0.9.5 - Copyright (C) 2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _LIBKMID_H -#define _LIBKMID_H - -#ifdef __cplusplus - -#include - -/** - * Simple API covering most of the uses of libkmid. - * - * You can use the members of this class in pure C applications, just by using - * the same name as the corresponding function member. - * - * Suppose you're developing a game and you want to play some background music - * while the user is playing. You only have to call : - * - * @li kMidInit(); - * @li kMidLoad("RideOfTheValkyries.mid"); - * @li kMidPlay(); - * - * When the user decides to quit the game, use - * - * @li kMidStop(); - * @li kMidDestruct(); - * - * to stop the music and release the memory allocated by libkmid. - * - * @short A very simple API around the rest of libkmid. - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class KMID_EXPORT KMidSimpleAPI -{ - private: - class KMidSimpleAPIPrivate; - KMidSimpleAPIPrivate *d; - - public: - - /** - * Initializes libkmid. Creates the DeviceManager object, and initializes - * some variables that will be used later. - * - * @return 0 if OK, and a positive number when there's any error (for - * example, because the /dev/sequencer device couldn't be opened, be it - * because it was already opened by another application, or because the - * sound card wasn't configured) - */ - static int kMidInit(void); - - /** - * Loads a song that will be played with the next call to kMidPlay(). - */ - static int kMidLoad(const char *filename); - - /** - * Plays the song currently loaded with kMidLoad(). - * kMidPlay forks in order to play the song in a different process, it - * exits inmediately, so that the application can follow the normal - * execution flow while the sone is played. - * - * If loop is 0 the song is played once and then the child process - * finishes. If loop is 1, the song is played repeatedly until - * kMidStop() is called. You can call kMidStop() anytime you want - * (also if loop is 0) to stop the song and kill the child process. - * - * @see kMidStop - * @see kMidIsPlaying - */ - static int kMidPlay(int loop=0); - - /** - * Stops playing a song inmediatly. It doesn't return until the child - * process that is playing the song is terminated. - * - * @see kMidPlay - */ - static int kMidStop(void); - - /** - * Releases the memory allocated by libkmid. To continue playing, you must - * first make a(nother) call to kMidInit(). - */ - static void kMidDestruct(void); - - /** - * Returns 1 if the library is playing a song, and 0 if it's not. - * @see kMidPlay - */ - static int kMidIsPlaying(void); - - /** - * Returns the number of MIDI devices ( MIDI ports + synthesizers ) - * @see DeviceManager::midiPorts - * @see DeviceManager::synthDevices - * @see kMidName - * @see kMidType - */ - static int kMidDevices(void); - - /** - * Returns the name of the i-th device . In case libkmid wasn't yet - * initialized ( see kMidInit() ), the return value is NULL, and in - * case the parameter has a value out of the valid range - * ( see kMidDevices() ) it returns an empty string. - * - * @see kMidDevices - * @see kMidType - */ - static const char *kMidName(int i); - - /** - * Returns the type of the i-th device . In case libkmid wasn't yet - * initialized ( see kMidInit() ), the return value is NULL, and in - * case the parameter has a value out of the valid range - * ( see kMidDevices() ) it returns an empty string. - * - * @see kMidDevices - * @see kMidName - */ - static const char *kMidType(int i); - - /** - * Sets the MIDI device to use when playing a song. - * @see kMidDevices - * @see kMidName - * @see DeviceManager - */ - static void kMidSetDevice(int i); - - /** - * Sets the Midi Mapper to use. Most of the users won't need a midi mapper, - * but there're still non-General Midi synthesizers out there, and people - * with one of those will get much better sound quality by using a MIDI - * mapper. - * - * Please have a look at KMid's documentation for more information - * about MIDI mappers and how to write a MIDI mapper for your keyboard. - */ - static void kMidSetMidiMapper(const char *mapfilename); - - /** - * Returns the version number of libkmid, i.e. "0.9.5" or "1.0 Beta" - */ - static const char *kMidVersion(void); - - /** - * Returns the copyright notice that applications using libkmid should print - * to the user in an about box or somewhere visible. - * I.e. - * - * "LibKMid 0.9.5 (C) 1997-2000 Antonio Larrosa Jimenez . Spain" - */ - static const char *kMidCopyright(void); - -}; - - - -extern "C" { - -#else -#define KMID_EXPORT -#endif - - -KMID_EXPORT int kMidInit(void); -KMID_EXPORT int kMidLoad(const char *filename); -KMID_EXPORT int kMidPlay(void); -KMID_EXPORT int kMidStop(void); -KMID_EXPORT void kMidDestruct(void); -KMID_EXPORT int kMidIsPlaying(void); -KMID_EXPORT int kMidDevices(void); -KMID_EXPORT const char * kMidName(int i); -KMID_EXPORT const char * kMidType(int i); -KMID_EXPORT void kMidSetDevice(int i); -KMID_EXPORT void kMidSetMidiMapper(const char *mapfilename); -KMID_EXPORT const char * kMidVersion(void); -KMID_EXPORT const char * kMidCopyright(void); - - - -#ifdef __cplusplus - -} - -/** - * @internal - */ -extern struct kMidData -{ - class DeviceManager *midi; - class MidiPlayer *player; - class MidiMapper *map; - struct PlayerController *pctl; - int pctlsmID; - int pid; -} kMid; -#endif - - -#endif diff --git a/libkmid/midfile.cc b/libkmid/midfile.cc deleted file mode 100644 index 4bf19f5b1..000000000 --- a/libkmid/midfile.cc +++ /dev/null @@ -1,460 +0,0 @@ -/************************************************************************** - - midfile.cc - function which reads a midi file,and creates the track classes - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "midfile.h" -#include -#include -#include -#include -#include "sndcard.h" -#include "midispec.h" -#include "mt32togm.h" -#include "sys/stat.h" -#include - -#include -#include - -int fsearch(FILE *fh,const char *text,long *ptr); - -/* This function gives the metronome tempo, from a tempo data as found in - a midi file */ -double tempoToMetronomeTempo(ulong x) -{ - return 60/((double)x/1000000); -} - -double metronomeTempoToTempo(ulong x) -{ - return ((double)60*x)/1000000; -} - -int uncompressFile(const char *gzname, char *tmpname) - // Returns 0 if OK, 1 if error (tmpname not set) -{ - TQString cmd("gzip -dc " + TDEProcess::quote(gzname)); - FILE *infile = popen( TQFile::encodeName(cmd).data(), "r"); - if (infile==NULL) { - fprintf(stderr,"ERROR : popen failed : %s\n",TQFile::encodeName(cmd).data()); - return 1; - } - strcpy(tmpname, "/tmp/KMid.XXXXXXXXXX"); - int fd = mkstemp(tmpname); - if (fd == -1) - { - pclose(infile); - return 1; - } - FILE *outfile= fdopen(fd,"wb"); - if (outfile==NULL) - { - pclose(infile); - return 1; - } - int n=getc(infile); - if (n==EOF) - { - pclose(infile); - fclose(outfile); - unlink(tmpname); - return 1; - } - fputc(n,outfile); - int buf[BUFSIZ]; - n = fread(buf, 1, BUFSIZ, infile); - while (n>0) - { - fwrite(buf, 1, n, outfile); - n = fread(buf, 1, BUFSIZ, infile); - } - - pclose(infile); - - //if (pclose(infile) != 0) fprintf(stderr,"Error : pclose failed\n"); - // Is it right for pclose to always fail ? - - fclose(outfile); - return 0; -} - -MidiTrack **readMidiFile( const char *name, MidiFileInfo *info, int &ok) -{ - ok=1; - MidiTrack **tracks; - - struct stat buf; - if (stat(name,&buf) || !S_ISREG(buf.st_mode)) - { - fprintf(stderr,"ERROR: %s is not a regular file\n",name); - ok=-6; - return NULL; - } - - FILE *fh=fopen(name,"rb"); - if (fh==NULL) - { - fprintf(stderr,"ERROR: Can't open file %s\n",name); - ok=-1; - return NULL; - } - char text[4]; - text[0] = 0; - fread(text,1,4,fh); - if ((strncmp(text,"MThd",4)!=0)&&(strcmp(&name[strlen(name)-3],".gz")==0)) - { - fclose(fh); - char tempname[200]; - fprintf(stderr,"Trying to open zipped midi file...\n"); - if (uncompressFile(name,tempname)!=0) - { - fprintf(stderr,"ERROR: %s is not a (zipped) midi file\n",name); - ok=-2; - return NULL; - } - fh=fopen(tempname,"rb"); - fread(text,1,4,fh); - unlink(tempname); - } - - if (strncmp(text,"MThd",4)!=0) - { - fseek(fh,0,SEEK_SET); - long pos; - if (fsearch(fh,"MThd",&pos)==0) - { - fclose(fh); - fprintf(stderr,"ERROR: %s is not a midi file.\n",name); - ok=-2; - return NULL; - } - fseek(fh,pos,SEEK_SET); - fread(text,1,4,fh); - } - long header_size=readLong(fh); - info->format=readShort(fh); - info->ntracks=readShort(fh); - info->ticksPerCuarterNote=readShort(fh); - if (info->ticksPerCuarterNote<0) - { - fprintf(stderr,"ERROR: Ticks per cuarter note is negative !\n"); - fprintf(stderr,"Please report this error to : larrosa@kde.org\n"); - fclose(fh); - ok=-3; - return NULL; - } - if (header_size>6) fseek(fh,header_size-6,SEEK_CUR); - tracks=new MidiTrack*[info->ntracks]; - if (tracks==NULL) - { - fprintf(stderr,"ERROR: Not enough memory\n"); - fclose(fh); - ok=-4; - return NULL; - } - int i=0; - while (intracks) - { - fread(text,1,4,fh); - if (strncmp(text,"MTrk",4)!=0) - { - fprintf(stderr,"ERROR: Not a well built midi file\n"); - fprintf(stderr,"%s",text); - fclose(fh); - ok=-5; - return NULL; - } - tracks[i]=new MidiTrack(fh,info->ticksPerCuarterNote,i); - if (tracks[i]==NULL) - { - fprintf(stderr,"ERROR: Not enough memory"); - fclose(fh); - ok=-4; - return NULL; - } - i++; - } - - fclose(fh); - - return tracks; - -} - -void parseInfoData(MidiFileInfo *info,MidiTrack **tracks,float ratioTempo) -{ - - info->ticksTotal=0; - info->millisecsTotal=0.0; - info->ticksPlayed=0; - int i; - for (i=0;i<256;i++) - { - info->patchesUsed[i]=0; - } - - int parsing=1; - int trk,minTrk; - ulong tempo=(ulong)(500000 * ratioTempo); - -#ifdef MIDFILEDEBUG - printf("Parsing 1 ...\n"); -#endif - - int pgminchannel[16]; - for (i=0;i<16;i++) - { - pgminchannel[i]=0; - } - - int j; - for (i=0;intracks;i++) - { - tracks[i]->init(); - tracks[i]->changeTempo(tempo); - } - double prevms=0; - double minTime=0; - double maxTime; - MidiEvent *ev=new MidiEvent; - while (parsing) - { - prevms=minTime; - trk=0; - minTrk=0; - maxTime=minTime + 2 * 60000L; - minTime=maxTime; - while (trkntracks) - { - if (tracks[trk]->absMsOfNextEvent()absMsOfNextEvent(); - } - trk++; - } - if ((minTime==maxTime)) - { - parsing=0; -#ifdef MIDFILEDEBUG - printf("END of parsing\n"); -#endif - } - else - { - trk=0; - while (trkntracks) - { - tracks[trk]->currentMs(minTime); - trk++; - } - } - trk=minTrk; - tracks[trk]->readEvent(ev); - - switch (ev->command) - { - case (MIDI_NOTEON) : - if (ev->chn!=PERCUSSION_CHANNEL) - info->patchesUsed[pgminchannel[ev->chn]]++; - else - info->patchesUsed[ev->note+128]++; - break; - case (MIDI_PGM_CHANGE) : - pgminchannel[ev->chn]=(ev->patch); - break; - case (MIDI_SYSTEM_PREFIX) : - if (((ev->command|ev->chn)==META_EVENT)&&(ev->d1==ME_SET_TEMPO)) - { - tempo=(ulong)(((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2])) * ratioTempo); - for (j=0;jntracks;j++) - { - tracks[j]->changeTempo(tempo); - } - } - break; - } - } - - delete ev; - info->millisecsTotal=prevms; - - for (i=0;intracks;i++) - { - tracks[i]->init(); - } - -#ifdef MIDFILEDEBUG - printf("info.ticksTotal = %ld \n",info->ticksTotal); - printf("info.ticksPlayed= %ld \n",info->ticksPlayed); - printf("info.millisecsTotal = %g \n",info->millisecsTotal); - printf("info.TicksPerCN = %d \n",info->ticksPerCuarterNote); -#endif - -} - - -void parsePatchesUsed(MidiTrack **tracks,MidiFileInfo *info,int gm) -{ - int i; - for (i=0;i<256;i++) - { - info->patchesUsed[i]=0; - } - int parsing=1; - int trk,minTrk; - ulong tempo=500000; - -#ifdef MIDFILEDEBUG - printf("Parsing for patches ...\n"); -#endif - - int j; - for (i=0;intracks;i++) - { - tracks[i]->init(); - } - double prevms=0; - double minTime=0; - double maxTime; - ulong tmp; - MidiEvent *ev=new MidiEvent; - int pgminchannel[16]; - for (i=0;i<16;i++) - { - pgminchannel[i]=0; - } - - while (parsing) - { - prevms=minTime; - trk=0; - minTrk=0; - maxTime=minTime + 2 * 60000L; - minTime=maxTime; - while (trkntracks) - { - if (tracks[trk]->absMsOfNextEvent()absMsOfNextEvent(); - } - trk++; - } - if ((minTime==maxTime)) - { - parsing=0; -#ifdef MIDFILEDEBUG - printf("END of parsing for patches\n"); -#endif - } - else - { - trk=0; - while (trkntracks) - { - tracks[trk]->currentMs(minTime); - trk++; - } - } - trk=minTrk; - tracks[trk]->readEvent(ev); - switch (ev->command) - { - case (MIDI_NOTEON) : - if (ev->chn!=PERCUSSION_CHANNEL) - info->patchesUsed[pgminchannel[ev->chn]]++; - else - info->patchesUsed[ev->note+128]++; - break; - case (MIDI_PGM_CHANGE) : - pgminchannel[ev->chn]=(gm==1)?(ev->patch):(MT32toGM[ev->patch]); - break; - case (MIDI_SYSTEM_PREFIX) : - if (((ev->command|ev->chn)==META_EVENT)&&(ev->d1==ME_SET_TEMPO)) - { - if (tempoToMetronomeTempo(tmp=((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2])))>=8) - { - tempo=tmp; - // printf("setTempo %ld\n",tempo); - for (j=0;jntracks;j++) - { - tracks[j]->changeTempo(tempo); - } - } - } - break; - } - } - - delete ev; - - for (i=0;intracks;i++) - { - tracks[i]->init(); - } - -} - -int fsearch(FILE *fh,const char *text,long *ptr) - // Search for "text" through the fh file and then returns : - // text MUST BE smaller than 256 characters - // 0 if not was found - // 1 if it was found and in ptr (if !=NULL) the position where text begins. -{ - if ((text==NULL)||(text[0]==0)) return 0; - char buf[1024]; - char tmp[256]; - long pos; - int l=strlen(text); - int i,k,r; - while (!feof(fh)) - { - pos=ftell(fh); - k=fread(buf,1,1024,fh); - i=0; - while (i=l) - r=strncmp(text,&buf[i],l); - else - { - fseek(fh,pos+i,SEEK_SET); - if (fread(tmp,1,l,fh)<(uint)l) return 0; - fseek(fh,pos+k,SEEK_SET); - r=strncmp(text,tmp,l); - } - if (r==0) - { - if (ptr!=NULL) *ptr=pos+i; - return 1; - } - } - i++; - } - } - return 0; -} diff --git a/libkmid/midfile.h b/libkmid/midfile.h deleted file mode 100644 index 18687b25c..000000000 --- a/libkmid/midfile.h +++ /dev/null @@ -1,99 +0,0 @@ -/* midfile.h - function which reads a midi file,and creates the track classes - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - - ***************************************************************************/ -#ifndef _MIDFILE_H -#define _MIDFILE_H - -#include -#include -#include -#include - -/** - * Contains all the information about a MIDI file. - * - * @short All the information about a MIDI file. - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -struct MidiFileInfo -{ - /** - * Format of MIDI file. - */ - int format; - - /** - * Number of tracks. - */ - int ntracks; - - /** - * Ticks per cuarter note. - */ - int ticksPerCuarterNote; - - /** - * Total number of MIDI ticks - */ - ulong ticksTotal; - - /** - * Total number of milliseconds - */ - double millisecsTotal; - - ulong ticksPlayed; - - /** - * Patches used in the MIDI file. - * - * In each position of the array it stores the number of times the - * corresponding patch is used. So, if a MIDI file plays 782 notes - * with a piano, patchesUsed[0] will store 782. In the same way, - * if it doesn't use the Music Box patch, patchesUsed[10] will be 0. - * - */ - int patchesUsed[256]; - -}; - -double KMID_EXPORT tempoToMetronomeTempo(ulong x); -double metronomeTempoToTempo(ulong x); - -/** - * Reads a midi file. - * - * @param name the filename of the midi file to load. - * @param info a pointer to the MidiFileInfo struct that will be - * filled with the information of the loaded file. - * @param ok return status. - * @return an array of MidiTrack objects with the contents of the file. - */ -MidiTrack **readMidiFile( const char *name, MidiFileInfo *info, int &ok); - -void parseInfoData( MidiFileInfo *info, MidiTrack **tracks, float ratioTempo); - -void parsePatchesUsed( MidiTrack **tracks, MidiFileInfo *info, int gm); - -#endif diff --git a/libkmid/midimapper.cc b/libkmid/midimapper.cc deleted file mode 100644 index 0b8022b8e..000000000 --- a/libkmid/midimapper.cc +++ /dev/null @@ -1,456 +0,0 @@ -/************************************************************************** - - midimapper.cc - The midi mapper object - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "midimapper.h" -#include -#include -#include -#ifdef HAVE_CONFIG_H -#include -#endif - -MidiMapper::MidiMapper(const char *name) -{ - _ok=1; - keymaps=NULL; - _filename=NULL; - mapPitchBender=0; - mapExpressionToVolumeEvents=0; - if ((name==NULL)||(name[0]==0)) - { - deallocateMaps(); - int i; - for (i=0;i<16;i++) - { - channelmap[i]=i; - channelPatchForced[i]=-1; - } - for (i=0;i<128;i++) patchmap[i]=i; - } - else - loadFile(name); -} - -MidiMapper::~MidiMapper() -{ - if (_filename) free(_filename); - deallocateMaps(); -} - -void MidiMapper::deallocateMaps(void) -{ - int i; - for (i=0;i<16;i++) channelKeymap[i]=NULL; - for (i=0;i<128;i++) patchKeymap[i]=NULL; - Keymap *km; - while (keymaps!=NULL) - { - km=keymaps->next; - delete keymaps; - keymaps=km; - } -} - -void MidiMapper::getValue(char *s,char *v) -{ - char *c=s; - while ((*c!=0)&&(*c!='=')) c++; - if (*c==0) v[0]=0; - else - { - c++; - while (*c!=0) - { - *v=*c; - c++;v++; - } - *v=0; - } -} - -void MidiMapper::removeSpaces(char *s) -{ - char *a=s; - while ((*a!=0)&&(*a==' ')) a++; - if (*a==0) {*s=0;return;}; - while (*a!=0) - { - while ((*a!=0)&&(*a!=' ')&&(*a!=10)&&(*a!=13)) - { - *s=*a; - s++; - a++; - } - while ((*a!=0)&&((*a==' ')||(*a==10)||(*a==13))) a++; - *s=' ';s++; - if (*a==0) {*s=0;return;}; - } - *s=0; - -} - -int MidiMapper::countWords(char *s) -{ - int c=0; - while (*s!=0) - { - if (*s==' ') c++; - s++; - } - return c; -} - -void MidiMapper::getWord(char *t,char *s,int w) -{ - int i=0; - *t=0; - while ((*s!=0)&&(iname, name, KM_NAME_SIZE); - km->name[KM_NAME_SIZE - 1] = 0; - - int i; - if (use_same_note==1) - { - for (i=0;i<128;i++) - km->key[i]=note; - } - else - { - for (i=0;i<128;i++) - km->key[i]=i; - } - addKeymap(km); - return km; -} - -void MidiMapper::addKeymap(Keymap *newkm) -{ - Keymap *km=keymaps; - if (keymaps==NULL) - { - keymaps=newkm; - newkm->next=NULL; - return; - } - while (km->next!=NULL) km=km->next; - km->next=newkm; - newkm->next=NULL; - return; -} - -MidiMapper::Keymap *MidiMapper::keymap(char *n) -{ - Keymap *km=keymaps; - while ((km!=NULL)&&(strcmp(km->name,n)!=0)) km=km->next; - return km; -} - -void MidiMapper::readOptions(FILE *fh) -{ -#ifdef MIDIMAPPERDEBUG - printf("Loading Options ... \n"); -#endif - char s[101]; - char v[101]; - char t[101]; - int fin=0; - mapPitchBender=0; - while (!fin) - { - s[0]=0; - while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh); - if (strncmp(s,"PitchBenderRatio",16)==0) - { - getValue(s,v); - removeSpaces(v); - getWord(t,v,0); - mapPitchBender=1; - pitchBenderRatio=atoi(t); - } - else if (strncmp(s,"MapExpressionToVolumeEvents",27)==0) mapExpressionToVolumeEvents=1; - else if (strncmp(s,"END",3)==0) - { - fin=1; - } - else - { - printf("ERROR: Invalid option in OPTIONS section of map file : (%s)\n",s); - _ok=0; - return; - } - } -} - -void MidiMapper::readPatchmap(FILE *fh) -{ - char s[101]; - char v[101]; - char t[101]; - char name[256]; /* Longer than t and 'AllKeysTo' */ - int i=0; - int j,w; -#ifdef MIDIMAPPERDEBUG - printf("Loading Patch map ... \n"); -#endif - while (i<128) - { - s[0]=0; - while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh); - getValue(s,v); - removeSpaces(v); - w=countWords(v); - j=0; - patchKeymap[i]=NULL; - patchmap[i]=i; - while (j=w) - { - printf("ERROR: Invalid option in PATCHMAP section of map file\n"); - _ok=0; - return; - } - getWord(t,v,j); - sprintf(name,"AllKeysTo%s",t); - patchKeymap[i]=createKeymap(name,1,atoi(t)); - } - else - { - patchmap[i]=atoi(t); - } - j++; - } - i++; - } - s[0]=0; - while ((s[0]==0)||(s[0]=='#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh); - if (strncmp(s,"END",3)!=0) - { - printf("ERROR: End of section not found in map file\n"); - _ok=0; - return; - } -} - -void MidiMapper::readKeymap(FILE *fh,char *first_line) -{ - char s[101]; - char v[101]; -#ifdef MIDIMAPPERDEBUG - printf("Loading Key map ... %s",first_line); -#endif - removeSpaces(first_line); - getWord(v,first_line,2); - Keymap *km=new Keymap; - strncpy(km->name, v, KM_NAME_SIZE); - km->name[KM_NAME_SIZE - 1] = 0; - - int i=0; - while (i<128) - { - s[0]=0; - while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh); - getValue(s,v); - removeSpaces(v); - km->key[i]=atoi(v); - i++; - } - s[0]=0; - while ((s[0]==0)||(s[0]=='#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh); - if (strncmp(s,"END",3)!=0) - { - printf("ERROR: End of section not found in map file\n"); - _ok=0; - return; - } - addKeymap(km); -} - -void MidiMapper::readChannelmap(FILE *fh) -{ - char s[101]; - char v[101]; - char t[101]; - int i=0; - int w,j; -#ifdef MIDIMAPPERDEBUG - printf("Loading Channel map ... \n"); -#endif - while (i<16) - { - s[0]=0; - while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh); - getValue(s,v); - removeSpaces(v); - w=countWords(v); - j=0; - channelKeymap[i]=NULL; - channelPatchForced[i]=-1; - channelmap[i]=i; - while (j=w) - { - printf("ERROR: Invalid option in CHANNELMAP section of map file\n"); - _ok=0; - return; - } - getWord(t,v,j); - channelKeymap[i]=keymap(t); - } - else if (strcmp(t,"ForcePatch")==0) - { - j++; - if (j>=w) - { - printf("ERROR: Invalid option in CHANNELMAP section of map file\n"); - _ok=0; - return; - } - getWord(t,v,j); - channelPatchForced[i]=atoi(t); - } - else - { - channelmap[i]=atoi(t); - } - j++; - } - i++; - } - s[0]=0; - while ((s[0]==0)||(s[0]=='#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh); - if (strncmp(s,"END",3)!=0) - { - printf("END of section not found in map file\n"); - _ok=0; - return; - } - -} - -const char *MidiMapper::filename(void) -{ - return (_filename)? _filename : ""; -} - -uchar MidiMapper::key(uchar chn,uchar pgm, uchar note) -{ - uchar notemapped=note; - if (patchKeymap[pgm]!=NULL) notemapped=patchKeymap[pgm]->key[note]; - if (channelKeymap[chn]!=NULL) notemapped=channelKeymap[chn]->key[note]; - return notemapped; -} - -uchar MidiMapper::patch(uchar chn,uchar pgm) -{ - return (channelPatchForced[chn] == -1) ? - patchmap[pgm] : (uchar)channelPatchForced[chn] ; -} - -void MidiMapper::pitchBender(uchar ,uchar &lsb,uchar &msb) -{ - if (mapPitchBender) - { - short pbs=((short)msb<<7) | (lsb & 0x7F); - pbs=pbs-0x2000; - short pbs2=(((long)pbs*pitchBenderRatio)/4096); -#ifdef MIDIMAPPERDEBUG - printf("Pitch Bender (%d): %d -> %d \n",chn,pbs,pbs2); -#endif - pbs2=pbs2+0x2000; - lsb=pbs2 & 0x7F; - msb=(pbs2 >> 7)&0x7F; - } -} - -void MidiMapper::controller(uchar ,uchar &ctl, uchar &) -{ - if ((mapExpressionToVolumeEvents)&&(ctl==11)) ctl=7; -} diff --git a/libkmid/midimapper.h b/libkmid/midimapper.h deleted file mode 100644 index 0edefdeec..000000000 --- a/libkmid/midimapper.h +++ /dev/null @@ -1,210 +0,0 @@ -/* midimapper.h - The midi mapper object - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _MIDIMAPPER_H -#define _MIDIMAPPER_H - -#include -#include -#include - -#define KM_NAME_SIZE 30 - -/** - * A Midi Mapper class which defines the way MIDI events are translated - * (or "mapped") to different ones. This way, when two MIDI devices "talk" - * in a somehow different way, they can still communicate. - * - * When the user has an external keyboard that is not compatible with the - * General Midi standard, he can use a MIDI mapper file to play files - * as if the synthesizer was GM compatible. - * - * Please see the KMid documentation - * ( http://www.arrakis.es/~rlarrosa/kmid.html ) for information on the - * format of a MIDI mapper definition file, and how they work. - * - * I created this class because I had one of those non-GM keyboards, - * so it can do everything I needed it to do for my keyboard to work - * exactly as a GM synth, and a few more things. Currently, it's the most - * featured MIDI mapper available. - * - * The usage of this class is quite simple, just create an object with - * a correct filename in the constructor and then use this object as - * parameter for DeviceManager::setMidiMap(). - * - * @short Midi Mapper - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class KMID_EXPORT MidiMapper -{ - private: - class MidiMapperPrivate; - MidiMapperPrivate *d; - - /** - * @internal - * Internal definition for Keymaps - */ - struct Keymap - { - char name[KM_NAME_SIZE]; - uchar key[128]; - struct Keymap *next; - }; - - int _ok; - - uchar channelmap[16]; - /** - * @internal - * It's a pointer to the Keymap to use for a channel - * This variable is used to get faster a given Keymap - * The index is the real channel (after mapping it) - */ - Keymap *channelKeymap[16]; - - /** - * @internal - * It's -1 if the channel doesn't have a forced patch, - * else indicates the patch to force in the channel. - */ - int channelPatchForced[16]; - - uchar patchmap[128]; - - /** - * @internal - * Same as channelKeymap - */ - Keymap *patchKeymap[128]; - - /** - * @internal - * Real linked list of keymaps used around the class. - */ - Keymap *keymaps; - - /** - * @internal - * Stores the name of the file from which the map was loaded - */ - char *_filename; - - /** - * @internal - * Simulate expression events with volume events - */ - int mapExpressionToVolumeEvents; - - /** - * @internal - * Map or not the Pitch Bender using pitchBenderRatio() - */ - int mapPitchBender; - - /** - * @internal - * Indicates the ratio between the standard and the synthesizer's pitch - * bender engine. The number sent to the synth is multiplied by this - * and dividied by 4096. Thus if PitchBenderRatio is 4096, the synth's - * pitch bender works as the standard one - */ - int pitchBenderRatio; - - void getValue(char *s,char *v); - void removeSpaces(char *s); - int countWords(char *s); - void getWord(char *t,char *s,int w); - // get from s the word in position w and store it in t - - void deallocateMaps(void); - Keymap *createKeymap(char *name,uchar use_same_note=0,uchar note=0); - void readPatchmap(FILE *fh); - void readKeymap(FILE *fh,char *first_line); - void readChannelmap(FILE *fh); - void readOptions(FILE *fh); - - void addKeymap(Keymap *newkm); - Keymap *keymap(char *n); - - public: - /** - * Constructor. Loads a MIDI Mapper definition from a file. - * @see filename() - */ - MidiMapper(const char *name); - - /** - * Destructor. - */ - ~MidiMapper(); - - /** - * Loads a MIDI Mapper definition file (you don't need to use this if you - * used a correct filename in constructor). - */ - void loadFile(const char *name); - - /** - * Returns the status of the object. - */ - int ok(void) { return _ok; } - - /** - * Returns the channel which chn should be mapped to. - */ - uchar channel(uchar chn) { return channelmap[chn];} - - /** - * Returns the patch which pgm used on channel chn should be mapped to. - */ - uchar patch(uchar chn,uchar pgm); - - /** - * Returns the key that key note playing a pgm patch on channel chn should - * be mapped to. - */ - uchar key(uchar chn,uchar pgm, uchar note); - - /** - * Returns the value which the pitch bender on channel chn should be - * mapped to. - */ - void pitchBender(uchar chn,uchar &lsb,uchar &msb); - - /** - * Returns the value which a given controller and its value should - * be mapped to when played on channel chn. - */ - void controller(uchar chn,uchar &ctl,uchar &v); - - /** - * Returns the path and name of the file which the object loaded the - * mapper from. - */ - const char *filename(void); - -}; - -#endif diff --git a/libkmid/midiout.cc b/libkmid/midiout.cc deleted file mode 100644 index e4a03a405..000000000 --- a/libkmid/midiout.cc +++ /dev/null @@ -1,301 +0,0 @@ -/************************************************************************** - - midiout.cc - class midiOut which handles external midi devices - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "midiout.h" -#include -#include -#include -#include "sndcard.h" -#include -#include -#include -#include -#include "midispec.h" -#include "alsaout.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -SEQ_USE_EXTBUF(); - -MidiOut::MidiOut(int d) -{ - seqfd = -1; - devicetype=KMID_EXTERNAL_MIDI; - device= d; - volumepercentage=100; - map=new MidiMapper(NULL); - if (map==NULL) { printfdebug("ERROR : midiOut : Map is NULL\n"); return; }; - _ok=1; -} - -MidiOut::~MidiOut() -{ - delete map; - closeDev(); -} - -void MidiOut::openDev (int sqfd) -{ -#ifdef HAVE_OSS_SUPPORT - _ok=1; - seqfd=sqfd; - if (seqfd==-1) - { - printfdebug("ERROR: Could not open /dev/sequencer\n"); - _ok=0; - return; - } -#endif -} - -void MidiOut::closeDev (void) -{ - if (!ok()) return; -// if (deviceType()!=KMID_ALSA) allNotesOff(); - SEQ_STOP_TIMER(); - SEQ_DUMPBUF(); - seqfd=-1; -} - -void MidiOut::initDev (void) -{ -#ifdef HAVE_OSS_SUPPORT - int chn; - if (!ok()) return; - uchar gm_reset[5]={0x7e, 0x7f, 0x09, 0x01, 0xf7}; - sysex(gm_reset, sizeof(gm_reset)); - for (chn=0;chn<16;chn++) - { - chnmute[chn]=0; - chnPatchChange(chn,0); - chnPressure(chn,127); - chnPitchBender(chn, 0x00, 0x40); - chnController(chn, CTL_MAIN_VOLUME,110*volumepercentage); - chnController(chn, CTL_EXT_EFF_DEPTH, 0); - chnController(chn, CTL_CHORUS_DEPTH, 0); - chnController(chn, 0x4a, 127); - } -#endif -} - -void MidiOut::setMidiMapper(MidiMapper *_map) -{ - delete map; - map=_map; -} - -void MidiOut::noteOn (uchar chn, uchar note, uchar vel) -{ - if (vel==0) - { - noteOff(chn,note,vel); - } - else - { - SEQ_MIDIOUT(device, MIDI_NOTEON + map->channel(chn)); - SEQ_MIDIOUT(device, map->key(chn,chnpatch[chn],note)); - SEQ_MIDIOUT(device, vel); - } -#ifdef MIDIOUTDEBUG - printfdebug("Note ON >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); -#endif -} - -void MidiOut::noteOff (uchar chn, uchar note, uchar vel) -{ - SEQ_MIDIOUT(device, MIDI_NOTEOFF + map->channel(chn)); - SEQ_MIDIOUT(device, map->key(chn,chnpatch[chn],note)); - SEQ_MIDIOUT(device, vel); -#ifdef MIDIOUTDEBUG - printfdebug("Note OFF >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); -#endif -} - -void MidiOut::keyPressure (uchar chn, uchar note, uchar vel) -{ - SEQ_MIDIOUT(device, MIDI_KEY_PRESSURE + map->channel(chn)); - SEQ_MIDIOUT(device, map->key(chn,chnpatch[chn],note)); - SEQ_MIDIOUT(device, vel); -} - -void MidiOut::chnPatchChange (uchar chn, uchar patch) -{ -#ifdef MIDIOUTDEBUG - printfdebug("PATCHCHANGE [%d->%d] %d -> %d\n", - chn,map->channel(chn),patch,map->patch(chn,patch)); -#endif - SEQ_MIDIOUT(device, MIDI_PGM_CHANGE + map->channel(chn)); - SEQ_MIDIOUT(device, map->patch(chn,patch)); - chnpatch[chn]=patch; -} - -void MidiOut::chnPressure (uchar chn, uchar vel) -{ - SEQ_MIDIOUT(device, MIDI_CHN_PRESSURE + map->channel(chn)); - SEQ_MIDIOUT(device, vel); - - chnpressure[chn]=vel; -} - -void MidiOut::chnPitchBender(uchar chn,uchar lsb, uchar msb) -{ - SEQ_MIDIOUT(device, MIDI_PITCH_BEND + map->channel(chn)); - /* -#ifdef AT_HOME - short pbs=((short)msb<<7) | (lsb & 0x7F); - pbs=pbs-0x2000; - short pbs2=(((long)pbs*672)/4096); - printfdebug("Pitch Bender (%d): %d -> %d \n",chn,pbs,pbs2); - pbs2=pbs2+0x2000; - lsb=pbs2 & 0x7F; - msb=(pbs2 >> 7)&0x7F; -#endif - */ - map->pitchBender(chn,lsb,msb); - SEQ_MIDIOUT(device, lsb); - SEQ_MIDIOUT(device, msb); - chnbender[chn]=(msb << 8) | (lsb & 0xFF); -} - -void MidiOut::chnController (uchar chn, uchar ctl, uchar v) -{ - SEQ_MIDIOUT(device, MIDI_CTL_CHANGE + map->channel(chn)); -#ifdef AT_HOME - if (ctl==11) ctl=7; -#endif - map->controller(chn,ctl,v); - if ((ctl==11)||(ctl==7)) - { - v=(v*volumepercentage)/100; - if (v>127) v=127; - } - - SEQ_MIDIOUT(device, ctl); - SEQ_MIDIOUT(device, v); - - chncontroller[chn][ctl]=v; -} - -void MidiOut::sysex(uchar *data, ulong size) -{ - ulong i=0; - SEQ_MIDIOUT(device, MIDI_SYSTEM_PREFIX); - while (ifilename() : ""; -} - -const char * MidiOut::deviceName(void) const -{ - switch (deviceType()) - { - case (KMID_EXTERNAL_MIDI) : return "External Midi"; - case (KMID_SYNTH) : return "Synth"; - case (KMID_FM) : return "FM"; - case (KMID_GUS) : return "GUS"; - case (KMID_AWE) : return "AWE"; - case (KMID_ALSA) : return reinterpret_cast(this)->deviceName(); - } - return "Unknown"; -} - -void MidiOut::sync(int i) -{ - if (deviceType()==KMID_ALSA) { // XXX : sync should be virtual after next bic - reinterpret_cast(this)->sync(i); - return; - } - SEQ_DUMPBUF(); -} diff --git a/libkmid/midiout.h b/libkmid/midiout.h deleted file mode 100644 index 93bbfff8c..000000000 --- a/libkmid/midiout.h +++ /dev/null @@ -1,251 +0,0 @@ -/* midiout.h - class midiOut which handles the /dev/sequencer device - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _MIDIOUT_H -#define _MIDIOUT_H - -#include -#include -#include -#include - -/** - * External MIDI port output class . This class is used to send midi - * events to external midi devices. - * - * MidiOut is inherited by other MIDI devices classes - * (like SynthOut or FMOut) to support a common API. - * - * In general, you don't want to use MidiOut directly, but within a - * DeviceManager object, which is the preferred way to generate music. - * - * If you want to add support for other devices (I don't think - * there are any) you just have to create a class that inherits from MidiOut - * and create one object of your new class in - * DeviceManager::initManager(). - * - * @short Sends MIDI events to external MIDI devices - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class MidiOut -{ - private: - class MidiOutPrivate; - MidiOutPrivate *d; - - protected: - - /** - * @internal - * This is the /dev/sequencer file handler. - * Remember _not_to_close_ it on MidiOut, but just on DeviceManager - */ - int seqfd; - - int device; - - int devicetype; - - int volumepercentage; - - MidiMapper *map; - - uchar chnpatch [16]; - int chnbender [16]; - uchar chnpressure [16]; - uchar chncontroller [16][256]; - int chnmute [16]; - - int _ok; - - void seqbuf_dump (void); - void seqbuf_clean(void); - - public: - - /** - * Constructor. After constructing a MidiOut device, you must open it - * (using openDev() ). Additionally you may want to initialize it - * (with initDev() ), - */ - MidiOut(int d=0); - - /** - * Destructor. It doesn't matter if you close the device ( closeDev() ) - * before you destruct the object because in other case, it will be closed - * here. - */ - virtual ~MidiOut(); - - /** - * Opens the device. This is generally called from DeviceManager , so you - * shouldn't call this yourself (except if you created the MidiOut object - * yourself. - * @param sqfd a file descriptor of /dev/sequencer - * @see closeDev - * @see initDev - */ - virtual void openDev (int sqfd); - - /** - * Closes the device. It basically tells the device (the file descriptor) - * is going to be closed. - * @see openDev - */ - virtual void closeDev (); - - /** - * Initializes the device sending generic standard midi events and controllers, - * such as changing the patches of each channel to an Acoustic Piano (000), - * setting the volume to a normal value, etc. - */ - virtual void initDev (); - - /** - * @return the device type of the object. This is to identify the - * inherited class that a given object is polymorphed to. - * The returned value is one of these : - * - * @li KMID_EXTERNAL_MIDI if it's a MidiOut object - * @li KMID_SYNTH if it's a SynthOut object (as an AWE device) - * @li KMID_FM if it's a FMOut object - * @li KMID_GUS if it's a GUSOut object - * - * which are defined in midispec.h - * - * @see deviceName - */ - int deviceType () const { return devicetype; } - - /** - * Returns the name and type of this MIDI device. - * @see deviceType - */ - const char * deviceName (void) const; - - /** - * Sets a MidiMapper object to be used to modify the midi events before - * sending them. - * - * @param map the MidiMapper to use. - * - * @see MidiMapper - * @see midiMapFilename - */ - void setMidiMapper ( MidiMapper *map ); - - /** - * See DeviceManager::noteOn() - */ - virtual void noteOn ( uchar chn, uchar note, uchar vel ); - - /** - * See DeviceManager::noteOff() - */ - virtual void noteOff ( uchar chn, uchar note, uchar vel ); - - /** - * See DeviceManager::keyPressure() - */ - virtual void keyPressure ( uchar chn, uchar note, uchar vel ); - - /** - * See DeviceManager::chnPatchChange() - */ - virtual void chnPatchChange ( uchar chn, uchar patch ); - - /** - * See DeviceManager::chnPressure() - */ - virtual void chnPressure ( uchar chn, uchar vel ); - - /** - * See DeviceManager::chnPitchBender() - */ - virtual void chnPitchBender ( uchar chn, uchar lsb, uchar msb ); - - /** - * See DeviceManager::chnController() - */ - virtual void chnController ( uchar chn, uchar ctl , uchar v ); - - /** - * See DeviceManager::sysex() - */ - virtual void sysex ( uchar *data,ulong size); - - /** - * Send a All Notes Off event to every channel - */ - void allNotesOff(void); - - /** - * Mutes all notes being played on a given channel. - * @param chn the channel - */ - virtual void channelSilence ( uchar chn ); - - /** - * Mute or "unmute" a given channel . - * @param chn channel to work on - * @param b if true, the device will ignore subsequent notes played on the chn - * channel, and mute all notes being played on it. If b is false, the channel - * is back to work. - */ - virtual void channelMute ( uchar chn, int b ); - - /** - * Change all channel volume events multiplying it by this percentage correction - * Instead of forcing a channel to a fixed volume, this method allows to - * music to fade out even when it was being played softly. - * @param volper is an integer value, where 0 is quiet, 100 is used to send - * an unmodified value, 200 play music twice louder than it should, etc. - */ - virtual void setVolumePercentage ( int volper ) - { volumepercentage = volper; } - - /** - * Returns true if everything's ok and false if there has been any problem - */ - int ok (void) - { if (seqfd<0) return 0; - return (_ok>0); - } - - /** - * Returns the path to the file where the current used MidiMapper object - * reads the configuration from, or an empty string if there's no MidiMapper. - */ - const char *midiMapFilename (); - - /** - * Sends the buffer to the device and returns when it's played, so you can - * synchronize - * XXX: sync should be virtual after next bic release - */ - void sync(int i=0); - -}; - -#endif diff --git a/libkmid/midispec.h b/libkmid/midispec.h deleted file mode 100644 index 3f60d49f2..000000000 --- a/libkmid/midispec.h +++ /dev/null @@ -1,60 +0,0 @@ -/* midispec.h - Some definitions to make the code more readable - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ - -#ifndef _MIDISPEC_H -#define _MIDISPEC_H - -#define META_EVENT 0xFF - -#define ME_TRACK_SEQ_NUMBER 0x00 -#define ME_TEXT 0x01 -#define ME_COPYRIGHT 0x02 -#define ME_SEQ_OR_TRACK_NAME 0x03 -#define ME_TRACK_INSTR_NAME 0x04 -#define ME_LYRIC 0x05 -#define ME_MARKER 0x06 -#define ME_CUE_POINT 0x07 -#define ME_CHANNEL_PREFIX 0x20 -#define ME_MIDI_PORT 0x21 -#define ME_SET_TEMPO 0x51 -#define ME_SMPTE_OFFSET 0x54 -#define ME_TIME_SIGNATURE 0x58 -#define ME_KEY_SIGNATURE 0x59 -/* sf=sharps/flats (-7=7 flats, 0=key of C, 7=7 sharps) - mi=major/minor (0=major, 1=minor) -*/ - -#define ME_END_OF_TRACK 0x2F - - -#define PERCUSSION_CHANNEL 9 - -#define KMID_EXTERNAL_MIDI 1 -#define KMID_SYNTH 2 -#define KMID_FM 3 -#define KMID_GUS 4 -#define KMID_AWE 5 //For future class aweOut -#define KMID_ALSA 6 - -#endif diff --git a/libkmid/midistat.cc b/libkmid/midistat.cc deleted file mode 100644 index 29d1436c8..000000000 --- a/libkmid/midistat.cc +++ /dev/null @@ -1,115 +0,0 @@ -/************************************************************************** - - midistat.cc - class MidiStatus, change it internally and then send it. - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "midistat.h" -#include "deviceman.h" -#include "sndcard.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -extern int MT32toGM[128]; - -MidiStatus::MidiStatus() -{ - int i; - tempo=1000000; - for (int chn=0;chn<16;chn++) - { - chn_patch[chn]=0; - chn_bender[chn]=0x4000; - chn_pressure[chn]=127; - for (i=0;i<256;i++) - chn_controller[chn][i]=0; - chn_controller[chn][CTL_MAIN_VOLUME]=127; - chn_controller[chn][11]=127; - chn_controller[chn][0x4a]=127; - chn_lastisvolumeev[chn]=1; - } -} - -MidiStatus::~MidiStatus() -{ -} - -// void noteOn ( uchar chn, uchar note, uchar vel ); -// void noteOff ( uchar chn, uchar note, uchar vel ); - -void MidiStatus::chnPatchChange ( uchar chn, uchar patch ) -{ - chn_patch[chn]=patch; -} - -void MidiStatus::chnPressure ( uchar chn, uchar vel ) -{ - chn_pressure[chn]=vel; -} - -void MidiStatus::chnPitchBender ( uchar chn, uchar lsb, uchar msb ) -{ - chn_bender[chn]=((int)msb<<8|lsb); -} - -void MidiStatus::chnController ( uchar chn, uchar ctl , uchar v ) -{ - if (ctl==7) chn_lastisvolumeev[chn]=1; - else if (ctl==11) chn_lastisvolumeev[chn]=0; - - chn_controller[chn][ctl]=v; -} - -void MidiStatus::tmrSetTempo(int v) -{ - tempo=v; -} - -void MidiStatus::sendData(DeviceManager *midi,int gm) -{ - for (int chn=0;chn<16;chn++) - { -#ifdef MIDISTATDEBUG - printf("Restoring channel %d\n",chn); -#endif - midi->chnPatchChange(chn, - (gm==1)?(chn_patch[chn]):(MT32toGM[chn_patch[chn]])); - midi->chnPitchBender(chn,chn_bender[chn]&0xFF,chn_bender[chn]>>8); - midi->chnPressure(chn,chn_pressure[chn]); - if (chn_lastisvolumeev[chn]) - { - midi->chnController(chn,11,chn_controller[chn][11]); - midi->chnController(chn,CTL_MAIN_VOLUME,chn_controller[chn][CTL_MAIN_VOLUME]); - } else { - midi->chnController(chn,CTL_MAIN_VOLUME,chn_controller[chn][CTL_MAIN_VOLUME]); - midi->chnController(chn,11,chn_controller[chn][11]); - } - /* - for (int i=0;i<256;i++) - midi->chnController(chn,i,chn_controller[chn][i]); - */ - } - midi->tmrSetTempo(tempo); - midi->sync(); -} diff --git a/libkmid/midistat.h b/libkmid/midistat.h deleted file mode 100644 index 17dda1269..000000000 --- a/libkmid/midistat.h +++ /dev/null @@ -1,143 +0,0 @@ -/* midistat.h - class midiStat, change it internally and then send it. - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - - ***************************************************************************/ -#ifndef _MIDISTAT_H -#define _MIDISTAT_H - -#include - -/** - * Stores the status of a MIDI device . That is, current patch in each channel, - * controller settings, pitch bender value, etc. - * - * This is used to "play" with all those values and then send them to the - * MIDI device just by using sendData() - * - * @short Stores the MIDI status. - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class MidiStatus -{ - private: - class MidiStatusPrivate; - MidiStatusPrivate *d; - - ulong tempo; - - unsigned char chn_patch [16]; - int chn_bender [16]; - unsigned char chn_pressure[16]; - unsigned char chn_controller[16][256]; - - int chn_lastisvolumeev[16]; - - public: - /** - * Constructor. - */ - MidiStatus(); - - /** - * Destructor. - */ - ~MidiStatus(); - - - // void noteOn ( uchar chn, uchar note, uchar vel ); - // void noteOff ( uchar chn, uchar note, uchar vel ); - - /** - * Stores a new value for the key aftertouch. - * @see MidiOut::keyPressure() - */ - void keyPressure ( uchar chn, uchar note, uchar vel ); - - /** - * Stores a new patch in channel @p chn. - * @see chnPatch() - * @see MidiOut::chnPatchChange() - */ - void chnPatchChange ( uchar chn, uchar patch ); - - /** - * Returns the patch currently used in channel @p chn. - */ - uchar chnPatch ( uchar chn ) { return chn_patch[chn]; } - - /** - * Stores a new channel pressure value in channel @p chn. - * @see MidiOut::chnPressure() - */ - void chnPressure ( uchar chn, uchar vel ); - - /** - * Returns the pressure value currently used in channel @p chn. - */ - uchar chnPressure ( uchar chn ) { return chn_pressure[chn]; } - - /** - * Stores a new pitch bender value in channel chn - */ - void chnPitchBender ( uchar chn, uchar lsb, uchar msb ); - - /** - * Returns the pitch bender value used in channel @p chn - */ - int chnPitchBender ( uchar chn) { return chn_bender[chn]; } - - /** - * Stores a new value for controller @p ctl in channel @p chn. - */ - void chnController ( uchar chn, uchar ctl , uchar v ); - - /** - * Returns the value used for controller @p ctl in channel @p chn - */ - uchar chnController ( uchar chn, uchar ctl ) - { return chn_controller[chn][ctl]; } - - /** - * Stores a sysex message that will be send in the next call to sendData - */ - void sysex ( uchar *data, ulong size); - - /** - * Sets the tempo. - * - * @see DeviceManager::tmrSetTempo() - */ - void tmrSetTempo ( int v ); - - - /** - * Sends the current MIDI state to the DeviceManager object used as - * parameter (you should have already set the default device to the one you - * want to use). The @p gm parameter specifies if the patches used follow - * the GM standard (1), or follow the MT32 standard (0), in which case, they - * will be converted to GM before being sent. - */ - void sendData ( class DeviceManager *midi, int gm=1 ); -}; - -#endif diff --git a/libkmid/mt32togm.cc b/libkmid/mt32togm.cc deleted file mode 100644 index a59eb959c..000000000 --- a/libkmid/mt32togm.cc +++ /dev/null @@ -1,18 +0,0 @@ -#include "mt32togm.h" - -int MT32toGM[128] = -{ - 0, 1, 2, 4, 4, 5, 5, 3, 16, 16, - 16, 16, 19, 19, 19, 21, 6, 6, 6, 7, - 7, 7, 8, 8, 62, 57, 63, 58, 38, 38, - 39, 39, 88, 33, 52, 35, 97, 100, 38, 39, - 14, 102, 68, 103, 44, 92, 46, 80, 48, 49, - 51, 45, 40, 40, 42, 42, 43, 46, 46, 24, - 25, 28, 27, 104, 32, 32, 34, 33, 36, 37, - 39, 35, 79, 73, 76, 72, 74, 75, 64, 65, - 66, 67, 71, 71, 69, 70, 60, 22, 56, 59, - 57, 63, 60, 60, 58, 61, 61, 11, 11, 99, - 100, 9, 14, 13, 12, 107, 106, 77, 78, 78, - 76, 111, 47, 117, 127, 115, 118, 116, 118, 126, - 121, 121, 55, 124, 120, 125, 126, 127 -}; diff --git a/libkmid/mt32togm.h b/libkmid/mt32togm.h deleted file mode 100644 index 74fb27875..000000000 --- a/libkmid/mt32togm.h +++ /dev/null @@ -1,31 +0,0 @@ -/* mt32togm.h - the translation map from MT32 patches to GM patches - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _MT32TOGM_H -#define _MT32TOGM_H - -#include - -extern int KMID_EXPORT MT32toGM[128]; - -#endif diff --git a/libkmid/notearray.cc b/libkmid/notearray.cc deleted file mode 100644 index 70652f16e..000000000 --- a/libkmid/notearray.cc +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************** - - notearray.cc - NoteArray class, which holds an array of notes - This file is part of LibKMid 0.9.5 - Copyright (C) 1998,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ - -#include "notearray.h" -#include - -NoteArray::NoteArray(void) -{ - totalAllocated=50; - data=new noteCmd[totalAllocated]; - lastAdded=0L; -} - -NoteArray::~NoteArray() -{ - delete data; - totalAllocated=0; -} - -NoteArray::noteCmd *NoteArray::pointerTo(ulong pos) -{ - if (pos=totalAllocated) - { - noteCmd *tmp=new noteCmd[totalAllocated*2]; - memcpy(tmp,data,sizeof(noteCmd)*totalAllocated); - delete data; - data=tmp; - totalAllocated*=2; - } - return &data[pos]; -} - -void NoteArray::at(ulong pos, ulong ms,int chn,int cmd,int note) -{ - noteCmd *tmp=pointerTo(pos); - tmp->ms=ms; - tmp->chn=chn; - tmp->cmd=cmd; - tmp->note=note; -} - -void NoteArray::at(ulong pos, noteCmd s) -{ - noteCmd *tmp=pointerTo(pos); - tmp->ms=s.ms; - tmp->chn=s.chn; - tmp->cmd=s.cmd; - tmp->note=s.note; -} - -NoteArray::noteCmd NoteArray::at(int pos) -{ - return *pointerTo(pos); -} - -void NoteArray::add(ulong ms,int chn,int cmd,int note) -{ - if (lastAdded==NULL) - { - lastAdded=data; - last=0; - } - else - { - last++; - if (last==totalAllocated) lastAdded=pointerTo(totalAllocated); - else lastAdded++; - } - lastAdded->ms=ms; - lastAdded->chn=chn; - lastAdded->cmd=cmd; - lastAdded->note=note; -} - -void NoteArray::next(void) -{ - if (it==lastAdded) {it=NULL;return;}; - it++; -} - -void NoteArray::moveIteratorTo(ulong ms,int *pgm) -{ - noteCmd *ncmd; - iteratorBegin(); - ncmd=get(); - int pgm2[16]; - for (int j=0;j<16;j++) pgm2[j]=0; - while ((ncmd!=NULL)&&(ncmd->mscmd==2) pgm2[ncmd->chn]=ncmd->note; - next(); - ncmd=get(); - } - if (pgm!=NULL) - { - for (int i=0;i<16;i++) pgm[i]=pgm2[i]; - } -} diff --git a/libkmid/notearray.h b/libkmid/notearray.h deleted file mode 100644 index b09e0dd1a..000000000 --- a/libkmid/notearray.h +++ /dev/null @@ -1,145 +0,0 @@ -/* notearray.h - NoteArray class, which holds an array of notes - This file is part of LibKMid 0.9.5 - Copyright (C) 1998,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef NOTEARRAY_H -#define NOTEARRAY_H - -#include -#include - -/** - * Holds a resizeable array of note on/off and patch change events. It can - * increase it size, but it doesn't decreases (until destruction :-) ) - * - * @short Stores an array of note on/off events - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class KMID_EXPORT NoteArray -{ - private: - class NoteArrayPrivate; - NoteArrayPrivate *d; - - public: - struct noteCmd { - /** - * ms from beginning of song - */ - ulong ms; - - /** - * The channel - */ - int chn; - - /** - * 0 note off, 1 note on, 2 change patch - */ - int cmd; - - /** - * The note. - * - * If cmd==2, then the patch is stored in "note" - */ - int note; - }; - - private: - noteCmd *data; - ulong totalAllocated; - - ulong last; - noteCmd *lastAdded; - - /** - * @internal - * The iterator - */ - noteCmd *it; - - noteCmd *pointerTo(ulong pos); - - public: - /** - * Constructor. Initializes internal variables. - */ - NoteArray(void); - /** - * Destructor. - */ - ~NoteArray(); - - /** - * Adds (or modifies) an event in the given position . - * - * Note that this has nothing to do with what is being played, this just - * modifies an internal array. - */ - void at(ulong pos, ulong ms,int chn,int cmd,int note); - - /** - * A convenience function, which differs from the above in the parameters - * it accepts. - */ - void at(ulong pos, noteCmd s); - - /** - * Returns the note event at a given position. - */ - noteCmd at(int pos); - - /** - * Adds a note/patch event at a given millisecond. - * - * Note: This method always appends at the end of the list. - */ - void add(ulong ms,int chn,int cmd,int note); - - /** - * Initializes the iterator. - * - * @see get() - * @see next() - */ - void iteratorBegin(void) { it=data; } - - /** - * Get the command currently pointed to by the iterator. - */ - noteCmd *get(void) { return it; } - - /** - * Advances the iterator to the next position. - */ - void next(void); - - /** - * Calls next() until the next event is over ms milliseconds - * and puts in @p pgm[16] the instruments used at this moment. - */ - void moveIteratorTo(ulong ms,int *pgm=NULL); -}; - -#endif diff --git a/libkmid/player.cc b/libkmid/player.cc deleted file mode 100644 index a68a9b147..000000000 --- a/libkmid/player.cc +++ /dev/null @@ -1,959 +0,0 @@ -/************************************************************************** - - player.cc - class MidiPlayer. Plays a set of tracks - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - $Id$ - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "player.h" -#include "sndcard.h" -#include "midispec.h" -#include -#include -#include -#include "midistat.h" -#include "mt32togm.h" - -//#define PLAYERDEBUG -//#define GENERAL_DEBUG_MESSAGES - -#define T2MS(ticks) (((double)ticks)*(double)60000L)/((double)tempoToMetronomeTempo(tempo)*(double)info->ticksPerCuarterNote) - -#define MS2T(ms) (((ms)*(double)tempoToMetronomeTempo(tempo)*(double)info->ticksPerCuarterNote)/((double)60000L)) - -#define REMOVEDUPSTRINGS - -MidiPlayer::MidiPlayer(DeviceManager *midi_,PlayerController *pctl) -{ - midi=midi_; - info=NULL; - tracks=NULL; - songLoaded=0; - ctl=pctl; - spev=NULL; - na=NULL; - parsesong=true; - generatebeats=false; -} - -MidiPlayer::~MidiPlayer() -{ - removeSpecialEvents(); - removeSong(); -} - -void MidiPlayer::removeSong(void) -{ - if ((songLoaded)&&(tracks!=NULL)) - { -#ifdef PLAYERDEBUG - printf("Removing song from memory\n"); -#endif - int i=0; - while (intracks) - { - if (tracks[i]!=NULL) delete tracks[i]; - i++; - } - delete tracks; - tracks=NULL; - if (info!=NULL) - { - delete info; - info=NULL; - } - } - songLoaded=0; -} - -int MidiPlayer::loadSong(const char *filename) -{ - removeSong(); -#ifdef PLAYERDEBUG - printf("Loading Song : %s\n",filename); -#endif - info=new MidiFileInfo; - int ok; - tracks=readMidiFile(filename,info,ok); - if (ok<0) return ok; - if (tracks==NULL) return -4; - - parseInfoData(info,tracks,ctl->ratioTempo); - - if (parsesong) - { - parseSpecialEvents(); - if (generatebeats) generateBeats(); - } - - songLoaded=1; - return 0; -} - -void MidiPlayer::insertBeat(SpecialEvent *ev,ulong ms,int num,int den) -{ - SpecialEvent *beat=new SpecialEvent; - beat->next=ev->next; - ev->next=beat; - beat->id=1; - beat->type=7; - beat->absmilliseconds=ms; - beat->num=num; - beat->den=den; -} - - -void MidiPlayer::generateBeats(void) -{ -#ifdef PLAYERDEBUG - printf("player::Generating Beats...\n"); -#endif - - if (spev==NULL) return; - SpecialEvent *ev=spev; - SpecialEvent *nextev=ev->next; - ulong tempo=(ulong)(500000 * ctl->ratioTempo); - int i=1; - int num=4; - int den=4; - // ulong beatstep=((double)tempo*4/(den*1000)); - // ulong beatstep=T2MS(info->ticksPerCuarterNote*(4/den)); - double ticksleft=(((double)info->ticksPerCuarterNote*4)/den); - - double beatstep=T2MS(ticksleft); - double nextbeatms=0; - double lastbeatms=0; - double measurems=0; - - while (nextev!=NULL) - { - switch (ev->type) - { - case (0): // End of list - { - };break; - case (1): // Text - case (2): // Lyrics - { - };break; - case (3): // Change Tempo - { - lastbeatms=ev->absmilliseconds; - ticksleft=MS2T(nextbeatms-lastbeatms); - tempo=ev->tempo; - nextbeatms=lastbeatms+T2MS(ticksleft); - // printf("Change at %lu to %d\n",ev->absmilliseconds,ev->tempo); - // beatstep=((double)tempo*4/(den*1000)); - beatstep=T2MS(((static_cast(info->ticksPerCuarterNote)*4)/den)); - };break; - case (6): // Change number of beats per measure - { - num=ev->num; - i=1; - den=ev->den; - // printf("Change at %lu to %d/%d\n",ev->absmilliseconds,num,den); - // beatstep=((double)tempo*4/(den*1000)); - // beatstep=T2MS(info->ticksPerCuarterNote*(4/den)); - beatstep=T2MS((((double)info->ticksPerCuarterNote*4)/den)); - nextbeatms=ev->absmilliseconds; - };break; - }; - if (nextev->absmilliseconds>nextbeatms) - { - //printf("Adding %d,%d\n",num,tot); - //printf("beat at %g , %d/%d\n",nextbeatms,i,num); - //printf(" %ld %d\n",nextev->absmilliseconds,nextev->type); - if (i == 1) { - measurems=nextbeatms; - } - insertBeat(ev, static_cast(nextbeatms), i++, num); - if (i > num) { - i=1; - } - lastbeatms=nextbeatms; - nextbeatms+=beatstep; - // nextbeatms=measurems+beatstep*i; - - ticksleft = ( (static_cast(info->ticksPerCuarterNote)*4) / den); - - } - - ev=ev->next; - nextev=ev->next; - } - - /* ev==NULL doesn't indicate the end of the song, so continue generating beats */ - - if (ev!=NULL) - { - if (ev->type==0) - { - ev=spev; - /* Looking if ev->next is NULL is not needed because - we are sure that a ev->type == 0 exists, we just have - to assure that the first spev is not the only one */ - if (ev->next!=NULL) - while (ev->next->type!=0) ev=ev->next; - } - while (nextbeatmsmillisecsTotal) - { - // printf("beat2 at %g , %d/%d\n",nextbeatms,i,num); - if (i==1) measurems=nextbeatms; - insertBeat(ev, static_cast(nextbeatms), i++, num); - if (i>num) i=1; - nextbeatms+=beatstep; - ev=ev->next; - } - } - - /* Regenerate IDs */ - - ev=spev; - i=1; - while (ev!=NULL) - { - ev->id=i++; - ev=ev->next; - } - - -#ifdef PLAYERDEBUG - printf("player::Beats Generated\n"); -#endif - -} - -void MidiPlayer::removeSpecialEvents(void) -{ - SpecialEvent * ev=spev; - while (spev!=NULL) - { - ev=spev->next; - delete spev; - spev=ev; - } - delete na; - na=0; -} - -void MidiPlayer::parseSpecialEvents(void) -{ -#ifdef PLAYERDEBUG - printf("player::Parsing...\n"); -#endif - removeSpecialEvents(); - spev=new SpecialEvent; - if (spev==NULL) return; - SpecialEvent *pspev=spev; - pspev->type=0; - pspev->ticks=0; - if (na) delete na; - na=new NoteArray(); - if (!na) { delete spev; spev=0L; return; }; - int trk; - int minTrk; - double minTime=0; - double maxTime; - ulong tempo=(ulong)(500000 * (ctl->ratioTempo)); - ulong firsttempo=0; - for (int i=0;intracks;i++) - { - tracks[i]->init(); - tracks[i]->changeTempo(tempo); - } - MidiEvent *ev=new MidiEvent; - //ulong mspass; - double prevms=0; - int spev_id=1; - int j; - int parsing=1; -#ifdef REMOVEDUPSTRINGS - char lasttext[1024]; - ulong lasttexttime=0; - lasttext[0]=0; - int lasttexttype=0; -#endif - while (parsing) - { - prevms=minTime; - trk=0; - minTrk=0; - maxTime=minTime + 2 * 60000L; - minTime=maxTime; - parsing=0; - while (trkntracks) - { - if (tracks[trk]->absMsOfNextEvent()absMsOfNextEvent(); - parsing=1; - } - trk++; - } - // if ((minTime==maxTime)) - if (parsing==0) - { - // parsing=0; -#ifdef PLAYERDEBUG - printf("END of parsing\n"); -#endif - } - else - { - // mspass=(ulong)(minTime-prevms); - trk=0; - while (trkntracks) - { - tracks[trk]->currentMs(minTime); - trk++; - } - } - trk=minTrk; - tracks[trk]->readEvent(ev); - switch (ev->command) - { - case (MIDI_NOTEON) : - if (ev->vel==0) na->add((ulong)minTime,ev->chn,0, ev->note); - else na->add((ulong)minTime,ev->chn,1,ev->note); - break; - case (MIDI_NOTEOFF) : - na->add((ulong)minTime,ev->chn,0, ev->note); - break; - case (MIDI_PGM_CHANGE) : - na->add((ulong)minTime,ev->chn, 2,ev->patch); - break; - case (MIDI_SYSTEM_PREFIX) : - { - if ((ev->command|ev->chn)==META_EVENT) - { - switch (ev->d1) - { - case (1) : - case (5) : - { - if (pspev!=NULL) - { - pspev->absmilliseconds=(ulong)minTime; - pspev->type=ev->d1; - pspev->id=spev_id++; -#ifdef PLAYERDEBUG - printf("ev->length %ld\n",ev->length); - -#endif - strncpy(pspev->text,(char *)ev->data, - (ev->length>= sizeof(lasttext))? sizeof(lasttext)-1 : (ev->length) ); - pspev->text[(ev->length>= sizeof(lasttext))? sizeof(lasttext)-1:(ev->length)]=0; -#ifdef PLAYERDEBUG - printf("(%s)(%s)\n",pspev->text,lasttext); -#endif -#ifdef REMOVEDUPSTRINGS - if ((strcmp(pspev->text,lasttext)!=0)||(pspev->absmilliseconds!=lasttexttime)||(pspev->type!=lasttexttype)) - { - lasttexttime=pspev->absmilliseconds; - lasttexttype=pspev->type; - strncpy(lasttext, pspev->text, 1024); - lasttext[sizeof(lasttext)-1] = 0; -#endif - pspev->next=new SpecialEvent; -#ifdef PLAYERDEBUG - if (pspev->next==NULL) printf("pspev->next=NULL\n"); -#endif - pspev=pspev->next; -#ifdef REMOVEDUPSTRINGS - } -#endif - } - } - break; - case (ME_SET_TEMPO) : - { - if (pspev!=NULL) - { - pspev->absmilliseconds=(ulong)minTime; - pspev->type=3; - pspev->id=spev_id++; - tempo=(ulong)(((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2])) * ctl->ratioTempo); - pspev->tempo=tempo; - if (firsttempo==0) firsttempo=tempo; - for (j=0;jntracks;j++) - { - tracks[j]->changeTempo(tempo); - } - pspev->next=new SpecialEvent; - pspev=pspev->next; - } - } - break; - case (ME_TIME_SIGNATURE) : - { - if (pspev!=NULL) - { - pspev->absmilliseconds=(ulong)minTime; - pspev->type=6; - pspev->id=spev_id++; - pspev->num=ev->d2; - pspev->den=ev->d3; - pspev->next=new SpecialEvent; - pspev=pspev->next; - } - } - break; - } - } - } - break; - } - } - - delete ev; - pspev->type=0; - pspev->absmilliseconds=(ulong)prevms; - pspev->next=NULL; - if (firsttempo==0) firsttempo=tempo; - ctl->tempo=firsttempo; - - //writeSPEV(); - for (int i=0;intracks;i++) - { - tracks[i]->init(); - } -} - -/* -NoteArray *MidiPlayer::parseNotes(void) -{ -#ifdef PLAYERDEBUG - printf("player::Parsing Notes...\n"); -#endif - NoteArray *na=new NoteArray(); - int trk; - int minTrk; - double minTime=0; - double maxTime; - for (int i=0;intracks;i++) - { - tracks[i]->init(); - }; - ulong tempo=1000000; - ulong tmp; - Midi_event *ev=new Midi_event; - //ulong mspass; - double prevms=0; - int j; - int parsing=1; - while (parsing) - { - prevms=minTime; - trk=0; - minTrk=0; - maxTime=minTime + 2 * 60000L; - minTime=maxTime; - while (trkntracks) - { - if (tracks[trk]->absMsOfNextEvent()absMsOfNextEvent(); - }; - trk++; - }; - if ((minTime==maxTime)) - { - parsing=0; -#ifdef PLAYERDEBUG - printf("END of parsing\n"); -#endif - } - else - { - // mspass=(ulong)(minTime-prevms); - trk=0; - while (trkntracks) - { - tracks[trk]->currentMs(minTime); - trk++; - }; - }; - trk=minTrk; - tracks[trk]->readEvent(ev); - if (ev->command==MIDI_NOTEON) - { - if (ev->vel==0) {printf("note off at %g\n",minTime);na->add((ulong)minTime,ev->chn,0, ev->note);} - else {printf("note on at %g\n",minTime);na->add((ulong)minTime,ev->chn,1,ev->note);} - } - else - if (ev->command==MIDI_NOTEOFF) na->add((ulong)minTime,ev->chn,0, ev->note); - if (ev->command==MIDI_PGM_CHANGE) na->add((ulong)minTime,ev->chn, 2,ev->patch); - if (ev->command==MIDI_SYSTEM_PREFIX) - { - if (((ev->command|ev->chn)==META_EVENT)&&(ev->d1==ME_SET_TEMPO)) - { - tempo=(ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2]); - for (j=0;jntracks;j++) - { - tracks[j]->changeTempo(tempo); - }; - }; - }; - - }; - - delete ev; - for (int i=0;intracks;i++) - { - tracks[i]->init(); - }; - return na; -}; -*/ - -void MidiPlayer::play(bool calloutput,void output(void)) -{ -#ifdef PLAYERDEBUG - printf("Playing...\n"); -#endif - - if (midi->midiPorts()+midi->synthDevices()==0) - { - fprintf(stderr,"Player :: There are no midi ports !\n"); - ctl->error=1; - return; - } - - midi->openDev(); - if (midi->ok()==0) - { - fprintf(stderr,"Player :: Couldn't play !\n"); - ctl->error=1; - return; - } - midi->setVolumePercentage(ctl->volumepercentage); - midi->initDev(); - // parsePatchesUsed(tracks,info,ctl->gm); - midi->setPatchesToUse(info->patchesUsed); - - int trk; - int minTrk; - double minTime=0; - double maxTime; - int i; - ulong tempo=(ulong)(500000 * ctl->ratioTempo); - for (i=0;intracks;i++) - { - tracks[i]->init(); - tracks[i]->changeTempo(tempo); - } - - midi->tmrStart(info->ticksPerCuarterNote); - MidiEvent *ev=new MidiEvent; - ctl->ev=ev; - ctl->ticksTotal=info->ticksTotal; - ctl->ticksPlayed=0; - //ctl->millisecsPlayed=0; - ulong ticksplayed=0; - double absTimeAtChangeTempo=0; - double absTime=0; - double diffTime=0; - MidiStatus *midistat; - //ulong mspass; - double prevms=0; - int j; - int halt=0; - ctl->tempo=tempo; - ctl->num=4; - ctl->den=4; - int playing; - ctl->paused=0; - if ((ctl->message!=0)&&(ctl->message & PLAYER_SETPOS)) - { - ctl->moving=1; - ctl->message&=~PLAYER_SETPOS; - midi->sync(1); - midi->tmrStop(); - midi->closeDev(); - midistat = new MidiStatus(); - setPos(ctl->gotomsec,midistat); - minTime=ctl->gotomsec; - prevms=(ulong)minTime; - midi->openDev(); - midi->tmrStart(info->ticksPerCuarterNote); - diffTime=ctl->gotomsec; - midistat->sendData(midi,ctl->gm); - delete midistat; - midi->setPatchesToUse(info->patchesUsed); - ctl->moving=0; - } else - for (i=0;i<16;i++) - { - if (ctl->forcepgm[i]) - { - midi->chnPatchChange(i, ctl->pgm[i]); - } - } - - timeval begintv; - gettimeofday(&begintv, NULL); - ctl->beginmillisec=begintv.tv_sec*1000+begintv.tv_usec/1000; - ctl->OK=1; - ctl->playing=playing=1; - - while (playing) - { - /* - if (ctl->message!=0) - { - if (ctl->message & PLAYER_DOPAUSE) - { - diffTime=minTime; - ctl->message&=~PLAYER_DOPAUSE; - midi->sync(1); - midi->tmrStop(); - ctl->paused=1; - midi->closeDev(); - while ((ctl->paused)&&(!(ctl->message&PLAYER_DOSTOP)) - &&(!(ctl->message&PLAYER_HALT))) sleep(1); - midi->openDev(); - midi->tmrStart(); - ctl->OK=1; - printf("Continue playing ... \n"); - }; - if (ctl->message & PLAYER_DOSTOP) - { - ctl->message&=~PLAYER_DOSTOP; - playing=0; - }; - if (ctl->message & PLAYER_HALT) - { - ctl->message&=~PLAYER_HALT; - playing=0; - halt=1; - }; - if (ctl->message & PLAYER_SETPOS) - { - ctl->moving=1; - ctl->message&=~PLAYER_SETPOS; - midi->sync(1); - midi->tmrStop(); - midi->closeDev(); - midistat = new midiStat(); - SetPos(ctl->gotomsec,midistat); - minTime=ctl->gotomsec; - prevms=(ulong)minTime; - midi->openDev(); - midi->tmrStart(); - diffTime=ctl->gotomsec; - ctl->moving=0; - midistat->sendData(midi,ctl->gm); - delete midistat; - ctl->OK=1; - while (ctl->OK==1) ; - ctl->moving=0; - }; - }; - */ - prevms=minTime; - // ctl->millisecsPlayed=minTime; - trk=0; - minTrk=0; - maxTime=minTime + 120000L /* milliseconds */; - minTime=maxTime; - playing=0; - while (trkntracks) - { - if (tracks[trk]->absMsOfNextEvent()absMsOfNextEvent(); - playing=1; - } - trk++; - } -#ifdef PLAYERDEBUG - printf("minTime %g\n",minTime); -#endif - // if ((minTime==maxTime)/* || (minTicks> 60000L)*/) - if (playing==0) - { - // playing=0; -#ifdef PLAYERDEBUG - printf("END of playing\n"); -#endif - } - else - { - // mspass=(ulong)(minTime-prevms); - trk=0; - while (trkntracks) - { - tracks[trk]->currentMs(minTime); - trk++; - } - midi->wait(minTime-diffTime); - } - trk=minTrk; - tracks[trk]->readEvent(ev); - switch (ev->command) - { - case (MIDI_NOTEON) : - midi->noteOn(ev->chn, ev->note, ev->vel);break; - case (MIDI_NOTEOFF): - midi->noteOff(ev->chn, ev->note, ev->vel);break; - case (MIDI_KEY_PRESSURE) : - midi->keyPressure(ev->chn, ev->note,ev->vel);break; - case (MIDI_PGM_CHANGE) : - if (!ctl->forcepgm[ev->chn]) - midi->chnPatchChange(ev->chn, (ctl->gm==1)?(ev->patch):(MT32toGM[ev->patch]));break; - case (MIDI_CHN_PRESSURE) : - midi->chnPressure(ev->chn, ev->vel);break; - case (MIDI_PITCH_BEND) : - midi->chnPitchBender(ev->chn, ev->d1,ev->d2);break; - case (MIDI_CTL_CHANGE) : - midi->chnController(ev->chn, ev->ctl,ev->d1);break; - case (MIDI_SYSTEM_PREFIX) : - if ((ev->command|ev->chn)==META_EVENT) - { - if ((ev->d1==5)||(ev->d1==1)) - { - ctl->SPEVplayed++; - } - if (ev->d1==ME_SET_TEMPO) - { - absTimeAtChangeTempo=absTime; - ticksplayed=0; - ctl->SPEVplayed++; - tempo=(ulong)(((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2]))*ctl->ratioTempo); -#ifdef PLAYERDEBUG - printf("Tempo : %ld %g (ratio : %g)\n",tempo,tempoToMetronomeTempo(tempo),ctl->ratioTempo); -#endif - midi->tmrSetTempo((int)tempoToMetronomeTempo(tempo)); - ctl->tempo=tempo; - for (j=0;jntracks;j++) - { - tracks[j]->changeTempo(tempo); - } - } - if (ev->d1==ME_TIME_SIGNATURE) - { - ctl->num=ev->d2; - ctl->den=ev->d3; - ctl->SPEVplayed++; - } - } - break; - } - if (calloutput) - { - midi->sync(); - output(); - } - - } - ctl->ev=NULL; - delete ev; -#ifdef PLAYERDEBUG - printf("Syncronizing ...\n"); -#endif - if (halt) - midi->sync(1); - else - midi->sync(); -#ifdef PLAYERDEBUG - printf("Closing device ...\n"); -#endif - midi->allNotesOff(); - midi->closeDev(); - ctl->playing=0; -#ifdef PLAYERDEBUG - printf("Bye...\n"); -#endif - ctl->OK=1; - ctl->finished=1; -} - - -void MidiPlayer::setPos(ulong gotomsec,MidiStatus *midistat) -{ - int trk,minTrk; - ulong tempo=(ulong)(500000 * ctl->ratioTempo); - double minTime=0,maxTime,prevms=0; - int i,j,likeplaying=1; - - MidiEvent *ev=new MidiEvent; - ctl->SPEVplayed=0; - for (i=0;intracks;i++) - { - tracks[i]->init(); - tracks[i]->changeTempo(tempo); - } - - for (i=0;i<16;i++) - { - if (ctl->forcepgm[i]) midistat->chnPatchChange(i, ctl->pgm[i]); - } - - while (likeplaying) - { - trk=0; - minTrk=0; - maxTime=minTime + 120000L; /*milliseconds (2 minutes)*/ - minTime=maxTime; - while (trkntracks) - { - if (tracks[trk]->absMsOfNextEvent()absMsOfNextEvent(); - } - trk++; - } - if (minTime==maxTime) - { - likeplaying=0; -#ifdef GENERAL_DEBUG_MESSAGES - printf("END of likeplaying\n"); -#endif - } - else - { - if (minTime>=gotomsec) - { - prevms=gotomsec; - likeplaying=0; -#ifdef GENERAL_DEBUG_MESSAGES - printf("Position reached !! \n"); -#endif - minTime=gotomsec; - } - else - { - prevms=minTime; - } - trk=0; - while (trkntracks) - { - tracks[trk]->currentMs(minTime); - trk++; - } - } - - if (likeplaying) - { - trk=minTrk; - tracks[trk]->readEvent(ev); - switch (ev->command) - { - /* case (MIDI_NOTEON) : - midistat->noteOn(ev->chn, ev->note, ev->vel);break; - case (MIDI_NOTEOFF): - midistat->noteOff(ev->chn, ev->note, ev->vel);break; - case (MIDI_KEY_PRESSURE) : - midistat->keyPressure(ev->chn, ev->note,ev->vel);break; - */ - case (MIDI_PGM_CHANGE) : - if (!ctl->forcepgm[ev->chn]) midistat->chnPatchChange(ev->chn, ev->patch);break; - case (MIDI_CHN_PRESSURE) : - midistat->chnPressure(ev->chn, ev->vel);break; - case (MIDI_PITCH_BEND) : - midistat->chnPitchBender(ev->chn, ev->d1,ev->d2);break; - case (MIDI_CTL_CHANGE) : - midistat->chnController(ev->chn, ev->ctl,ev->d1);break; - case (MIDI_SYSTEM_PREFIX) : - if ((ev->command|ev->chn)==META_EVENT) - { - if ((ev->d1==5)||(ev->d1==1)) - { - ctl->SPEVplayed++; - } - if (ev->d1==ME_SET_TEMPO) - { - ctl->SPEVplayed++; - tempo=(ulong)(((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2]))*ctl->ratioTempo); - - midistat->tmrSetTempo((int)tempoToMetronomeTempo(tempo)); - for (j=0;jntracks;j++) - { - tracks[j]->changeTempo(tempo); - } - } - if (ev->d1==ME_TIME_SIGNATURE) - { - ctl->num=ev->d2; - ctl->den=ev->d3; - ctl->SPEVplayed++; - } - } - break; - } - } - } - delete ev; - ctl->tempo=tempo; -} - - -void MidiPlayer::debugSpecialEvents(void) -{ - SpecialEvent *pspev=spev; - printf("**************************************\n"); - while ((pspev!=NULL)&&(pspev->type!=0)) - { - printf("t:%d ticks:%d diff:%ld abs:%ld s:%s tempo:%ld\n",pspev->type,pspev->ticks,pspev->diffmilliseconds,pspev->absmilliseconds,pspev->text,pspev->tempo); - pspev=pspev->next; - } - -} - -void MidiPlayer::setParseSong(bool b) -{ - parsesong=b; -} - -void MidiPlayer::setGenerateBeats(bool b) -{ - generatebeats=b; -} - -void MidiPlayer::setTempoRatio(double ratio) -{ - if (songLoaded) - { - ctl->ratioTempo=ratio; - parseInfoData(info,tracks,ctl->ratioTempo); - if (parsesong) - { - parseSpecialEvents(); - if (generatebeats) generateBeats(); - - } - } - else - { - ctl->tempo=(ulong)((ctl->tempo*ctl->ratioTempo)/ratio); - ctl->ratioTempo=ratio; - } - -} - -#undef T2MS -#undef MS2T diff --git a/libkmid/player.h b/libkmid/player.h deleted file mode 100644 index 6a9210292..000000000 --- a/libkmid/player.h +++ /dev/null @@ -1,396 +0,0 @@ -/* player.h - class MidiPlayer. Plays a set of tracks - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _PLAYER_H -#define _PLAYER_H - -#include -#include -#include -#include -#include -#include - -/** - * This struct stores text, lyrics and change tempo events among others. - * - * It includes the main information for an event. That is, the absolute - * millisecond at which this event is played (from the beginning of the song), - * the delta milliseconds from the previous SpecialEvent, an ID, etc. - * - * This struct is used as nodes for a linked list, which you can get using - * MidiPlayer::specialEvents(). - * - * @short Struct used to store certain events - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -struct SpecialEvent -{ - /** - * An integer ID, that is assigned in order to each SpecialEvent. - */ - int id; - - /** - * Delta milliseconds from the previous SpecialEvent. - * - * @see absmilliseconds - */ - ulong diffmilliseconds; - - /** - * The absolute millisecond (from the beginning of the song) at which this - * SpecialEvent object is played. - * - * @see diffmilliseconds - */ - ulong absmilliseconds; - - /** - * MIDI ticks (from the beginning of the song) at which this event is played. - */ - int ticks; - - /** - * Type of event. This currently includes: - * - * @li 0 - Nothing, end of linked list. - * @li 1 - Text Event . See text. - * @li 3 - Change Tempo Event . See tempo. - * @li 5 - Lyrics Event . See text. - * @li 6 - Change number of beats per measure . See num and den. - * @li 7 - Beat . See num and den. - * - * The "Change number of beats per measure" and "beat" events are not really - * in the midi file, but they are added to the linked list in case you have - * an use for it. - */ - int type; - - /** - * Text field . It has a meaning only for Text and Lyrics events. - */ - char text[1024]; - - /** - * Tempo field . It has a meaning only for Change Tempo events. - */ - ulong tempo; - /** - * Numerator . It has a meaning only for Change number of beats per measure and - * beat events. - */ - int num; - /** - * Denominator . It has a meaning only for Change number of beats per measure - * and beat events. - */ - int den; - - /** - * This struct stores text, lyrics and change tempo events among others. - * - * It includes the main information for an event. That is, the absolute - * millisecond at which this event is played (from the beginning of the song), - * the delta milliseconds from the previous SpecialEvent, an ID, etc. - * - * This struct is used as nodes for a linked list, which you can get using - * MidiPlayer::specialEvents(). - */ - struct SpecialEvent *next; - - /** - * Next node in the linked list. - */ - -}; - - -/** - * PlayerController is a struct that is used by the MidiPlayer object - * to tell other parts of the application about the status of the MIDI playing. - * - * @short Struct used to have control over the player engine - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -struct PlayerController -{ - volatile ulong ticksTotal; - volatile ulong ticksPlayed; - volatile double millisecsPlayed; - volatile ulong beginmillisec; - - volatile int tempo; - volatile int num; - volatile int den; - - volatile int SPEVprocessed; - volatile int SPEVplayed; - - /** - * When pause is released, if the caller must know when the player has - * opened the devices and is playing again, then it just has to check - * to see when OK changes the value to 1 - */ - volatile int OK; - - /** - * When the player is playing (or paused), playing is set to 1. - */ - volatile int playing; - - /** - * When the player is paused, paused is set to 1. - */ - volatile int paused; - - /** - * When the player seeking the position of the song, moving is set to 1. - */ - volatile int moving; - - /** - * When the player has finished playing a song, finished is set to 1. - */ - volatile int finished; - - /** - * @internal - * @deprecated - * Not used - */ - volatile int message KDE_DEPRECATED; // set one of the following : - -#define PLAYER_DOPAUSE 1 -#define PLAYER_DOSTOP 2 -#define PLAYER_SETPOS 4 -#define PLAYER_HALT 8 - - volatile ulong gotomsec; //milliseconds to go to,if player_setpos is set - - /** - * When error is 1, an error has ocurred (i.e. it coultn't open the device) - */ - volatile int error; - - /** - * If gm is 1, the song follows the General Midi standard, if gm is 0, the song - * is in MT 32 format. - */ - volatile int gm; - - /** - * 100 means no change, 50 halfs the volume, 200 doubles it (if possible), etc. - * - * @see DeviceManager::setVolumePercentage() - */ - volatile int volumepercentage ; - - /** - * Activate or disactivate the force to use a patch for a given channel. - * @see pgm - */ - volatile bool forcepgm[16]; - - /** - * Force a given patch in each channel at "this" moment, as determined by - * forcepgm. - */ - volatile int pgm[16]; - - /** - * Ratio to multiply the tempo to. - */ - volatile double ratioTempo; - - /** - * @internal Used to stop the main pid until the child has finished to - * send the all notes off event - */ - volatile bool isSendingAllNotesOff; - - volatile MidiEvent *ev; -}; - - -/** - * MIDI file player routines . This class reads a MIDI file and - * play it using a DeviceManager object. - * - * To use it, just call loadSong() with the filename you want to play, - * and then play(). - * - * Please have a look at the note in the play() documentation. - * - * MidiPlayer will write information about the playing process on a - * PlayerController() structure that you must supply to the constructor - * - * Alternatively, if everything you want is to play a midi file in a game or - * any other application that doesn't need to fine tune the midi playing, just - * use the kmidplay() function. - * - * @see KMidSimpleAPI - * - * @short The MIDI file player engine - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class KMID_EXPORT MidiPlayer -{ - class MidiPlayerPrivate; - MidiPlayerPrivate *d; - - DeviceManager *midi; - MidiFileInfo *info; - MidiTrack **tracks; - SpecialEvent *spev; - NoteArray *na; - - int songLoaded; - - PlayerController *ctl; - - bool parsesong; - bool generatebeats; - - void removeSpecialEvents(void); - void parseSpecialEvents(void); - void insertBeat(SpecialEvent *ev,ulong ms,int num,int den); - void generateBeats(void); - - //NoteArray *parseNotes(void); - void debugSpecialEvents(void); - public: - - /** - * Constructor . You must construct and pass a DeviceManager object and a - * PlayerController structure. None of them will be destroyed by this - * object, so you should do it after destroying the MidiPlayer object. - */ - MidiPlayer(DeviceManager *midi_,PlayerController *pctl); - - /** - * Destructor. - */ - ~MidiPlayer(); - - /** - * Loads a Song, and parses it (it the parse wasn't disabled with - * setParseSong() ) . It also generates the Beat events (see - * SpecialEvent::type() ) if you enabled this by using - * setGenerateBeats() . - */ - int loadSong(const char *filename); - - /** - * Unloads the current song, so that every internal variable is empty and clean - * for further usage. - */ - void removeSong(void); - - /** - * Returns true if there's a song already loaded (with a previous call to - * loadSong() ) and false if not. - */ - int isSongLoaded(void) { return songLoaded; } - - /** - * Returns the linked list of SpecialEvents objects . For this to work, - * the parse should be enabled (the default), by using setParseSong(). - */ - SpecialEvent *specialEvents() { return spev; } - - /** - * Returns and array with the notes playen through the song . MidiPlayer must - * parse the song to get the notes, so be sure not to disable the parsing of - * the song. - * - * Returns an array of notes, (just note on and note off events), in the form - * of a NoteArray object - */ - NoteArray *noteArray(void) { return na; } - - - /** - * Plays the song using the DeviceManager object supplied in the - * constructor. It should be already configured, as play doesn't change the - * volume, nor midi mapper, for example. - * - * Note: Calling this function will block the execution of your application - * until the song finishes playing. The solution for this is simple, fork - * before calling it, and create the PlayerController object on shared - * memory. - * - * As alternative, if everything you want is playing a midi file in a game or - * any other application that doesn't need to fine tune the midi playing, just - * use the KMidSimpleAPI::kMidPlay() function. - * - * @see KMidSimpleAPI::kMidInit - * @see KMidSimpleAPI::kMidPlay - * @see KMidSimpleAPI::kMidStop - * @see KMidSimpleAPI::kMidDestruct - */ - void play(bool calloutput=false,void output(void) = 0); - - /** - * Enables or disables the parsing of the song when loading it. This affects - * the SpecialEvents ( specialEvents() ) and the NoteArray - * ( noteArray() ). - */ - void setParseSong(bool b = true); - - /** - * Enables or disables the generation of beats event in a song when loading - * it. - */ - void setGenerateBeats(bool b = false); - - /** - * Returns information about the current MIDI file. - * - * @see loadSong - */ - MidiFileInfo *information(void) { return info; } - - /** - * Sets the position in a song. - * @param gotomsec the number of milliseconds to go to . A subsequent call to - * play() will start playing the song from that moment, instead of the - * beginning. - * @param midistat a MidiStatus object that will contain the status in - * which the MIDI device would be if it would have arrived to this situation by - * a normal playing of the song. - */ - void setPos(ulong gotomsec, class MidiStatus *midistat); - - /** - * Changes the speed at which a song is played. The song's tempo is multiplied - * by the specified ratio. - */ - void setTempoRatio(double ratio); - -}; - -#endif diff --git a/libkmid/sndcard.h b/libkmid/sndcard.h deleted file mode 100644 index c533451ed..000000000 --- a/libkmid/sndcard.h +++ /dev/null @@ -1,88 +0,0 @@ -/* sndcard.h - include the OSS' soundcard.h file - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ - -#ifndef _SNDCARD_H -#define _SNDCARD_H - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_SYS_SOUNDCARD_H - #include -#elif defined(HAVE_MACHINE_SOUNDCARD_H) - #include -#endif - -/* Check for OSS MIDI API */ -#if defined(SNDCTL_SEQ_NRSYNTHS) && defined(CTL_MAIN_VOLUME) - #define HAVE_OSS_SUPPORT -#else - #undef HAVE_OSS_SUPPORT -#endif - -#ifdef HAVE_OSS_SUPPORT - -#ifndef HZ -#define HZ 100 -#endif - -#ifndef MIDI_TYPE_MPU401 -#define MIDI_TYPE_MPU401 0x401 -#endif - -#else - -#define MIDI_NOTEON 0x80 -#define MIDI_NOTEOFF 0x90 -#define MIDI_KEY_PRESSURE 0xA0 -#define MIDI_CTL_CHANGE 0xB0 -#define MIDI_PGM_CHANGE 0xC0 -#define MIDI_CHN_PRESSURE 0xD0 -#define MIDI_PITCH_BEND 0xE0 -#define MIDI_SYSTEM_PREFIX 0xF0 -#define CTL_MAIN_VOLUME 7 - -#define SEQ_DEFINEBUF(a) -#define SEQ_USE_EXTBUF() -#define SEQ_MIDIOUT(a,b) {} -#define SEQ_START_NOTE(a,b,c,d) {} -#define SEQ_STOP_NOTE(a,b,c,d) {} -#define SEQ_SET_PATCH(a,b,c) {} -#define SEQ_CONTROL(a,b,c,d) {} -#define SEQ_BENDER(a,b,c) {} -#define SEQ_CHN_PRESSURE(a,b,c) {} -#define SEQ_KEY_PRESSURE(a,b,c,d) {} -#define SEQ_DUMPBUF() -#define SEQ_WAIT_TIME(a) -#define SEQ_START_TIMER() -#define SEQ_STOP_TIMER() -#define SEQ_CONTINUE_TIMER() - - -#endif - - - -#endif diff --git a/libkmid/synthout.cc b/libkmid/synthout.cc deleted file mode 100644 index 069bbd32f..000000000 --- a/libkmid/synthout.cc +++ /dev/null @@ -1,211 +0,0 @@ -/************************************************************************** - - synthout.cc - class synthOut which handles the /dev/sequencer device - for synths (as AWE32) - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98 Antonio Larrosa Jimenez and P.J.Leonard - 1999,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#include "synthout.h" -#include -#include -#include -#include "sndcard.h" -#include -#include -#include -#include -#include "awe_sup.h" -#include "midispec.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -SEQ_USE_EXTBUF(); - -SynthOut::SynthOut(int d) -{ - seqfd = -1; - devicetype=KMID_SYNTH; - device= d; - _ok=1; -} - -SynthOut::~SynthOut() -{ - closeDev(); -} - -void SynthOut::openDev (int sqfd) -{ - _ok=1; - seqfd = sqfd; - if (seqfd==-1) - { - printfdebug("ERROR: Could not open /dev/sequencer\n"); - return; - } -#ifdef HAVE_OSS_SUPPORT - /* - int i=1; - ioctl(seqfd,SNDCTL_SEQ_THRESHOLD,i); - printfdebug("Threshold : %d\n",i); - */ -#ifdef SYNTHOUTDEBUG - printfdebug("Number of synth devices : %d\n",ndevs); - printfdebug("Number of midi ports : %d\n",nmidiports); - printfdebug("Rate : %d\n",m_rate); -#endif - -#ifdef HAVE_AWE32 - - struct synth_info info; - - // Should really collect the possible devices and let the user choose ? - - info.device = device; - - if (ioctl (seqfd, SNDCTL_SYNTH_INFO, &info) == -1) - printfdebug(" ioctl SNDCTL_SYNTH_INFO FAILED \n"); - - if (info.synth_type == SYNTH_TYPE_SAMPLE - && info.synth_subtype == SAMPLE_TYPE_AWE32) - { - - // Enable layered patches .... - AWE_SET_CHANNEL_MODE(device,1); -#ifdef SYNTHOUTDEBUG - printfdebug(" Found AWE32 dev=%d \n",device); -#endif - } -#endif // HAVE_AWE32 -#endif // HAVE_OSS_SUPPORT - -} - -void SynthOut::closeDev (void) -{ - if (!ok()) return; - //if (seqfd>=0) close(seqfd); - seqfd=-1; -} - -void SynthOut::initDev (void) -{ -#ifdef HAVE_OSS_SUPPORT - int chn; - if (!ok()) return; - uchar gm_reset[5]={0x7e, 0x7f, 0x09, 0x01, 0xf7}; - sysex(gm_reset, sizeof(gm_reset)); - for (chn=0;chn<16;chn++) - { - chnmute[chn]=0; - chnPatchChange(chn,0); - chnPressure(chn,127); - chnPitchBender(chn, 0x00, 0x40); - chnController(chn, CTL_MAIN_VOLUME,127); - chnController(chn, CTL_EXT_EFF_DEPTH, 0); - chnController(chn, CTL_CHORUS_DEPTH, 0); - chnController(chn, 0x4a, 127); - } -#endif -} - -void SynthOut::noteOn (uchar chn, uchar note, uchar vel) -{ - if (vel==0) - { - noteOff(chn,note,vel); - } - else - { - SEQ_START_NOTE(device, map->channel(chn), - map->key(chn,chnpatch[chn],note), - vel); - } -#ifdef SYNTHOUTDEBUG - printfdebug("Note ON >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); -#endif -} - -void SynthOut::noteOff (uchar chn, uchar note, uchar) -{ - SEQ_STOP_NOTE(device, map->channel(chn), - map->key(chn,chnpatch[chn],note), 0); -#ifdef SYNTHOUTDEBUG - printfdebug("Note OFF >\t chn : %d\tnote : %d\tvel: %d\n",chn,note,vel); -#endif -} - -void SynthOut::keyPressure (uchar chn, uchar note, uchar vel) -{ - SEQ_KEY_PRESSURE(device, map->channel(chn), map->key(chn,chnpatch[chn],note),vel); -} - -void SynthOut::chnPatchChange (uchar chn, uchar patch) -{ - SEQ_SET_PATCH(device,map->channel(chn),map->patch(chn,patch)); - chnpatch[chn]=patch; -} - -void SynthOut::chnPressure (uchar chn, uchar vel) -{ - SEQ_CHN_PRESSURE(device, map->channel(chn) , vel); - chnpressure[chn]=vel; -} - -void SynthOut::chnPitchBender(uchar chn,uchar lsb, uchar msb) -{ - chnbender[chn]=((int)msb<<7) | (lsb & 0x7F); - SEQ_BENDER(device, map->channel(chn), chnbender[chn]); -} - -void SynthOut::chnController (uchar chn, uchar ctl, uchar v) -{ - if ((ctl==11)||(ctl==7)) - { - v=(v*volumepercentage)/100; - if (v>127) v=127; - } - - SEQ_CONTROL(device, map->channel(chn), ctl, v); - chncontroller[chn][ctl]=v; -} - -void SynthOut::sysex(uchar *, ulong ) -{ - // AWE32 doesn't respond to sysex (AFAIK) -/* -#ifndef HAVE_AWE32 - ulong i=0; - SEQ_MIDIOUT(device, MIDI_SYSTEM_PREFIX); - while (i - -***************************************************************************/ -#ifndef _SYNTHOUT_H -#define _SYNTHOUT_H - -#include - -/** - * Synth (AWE) device output class . SynthOut is used to send MIDI events to - * a general synthesizer, such as AWE synth. - * - * SynthOut inherits MidiOut and supports the same simple API. - * - * The preferred way to use this class is by selecting a synth (or AWE) - * device with MidiManager::setDefaultDevice(), and use a - * MidiManager object. - * - * @short Sends MIDI events to AWE synthesizers - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class SynthOut : public MidiOut -{ - private: - class SynthOutPrivate; - SynthOutPrivate *di; - - public: - /** - * Constructor. See MidiOut::MidiOut() for more information. - */ - SynthOut(int d=0); - - /** - * Destructor. - */ - ~SynthOut(); - - /** - * See MidiOut::openDev() - */ - void openDev (int sqfd); - - /** - * See MidiOut::closeDev() - */ - void closeDev(void); - - /** - * See MidiOut::initDev() - */ - void initDev (void); - - /** - * See MidiOut::noteOn() - */ - void noteOn ( uchar chn, uchar note, uchar vel ); - - /** - * See MidiOut::noteOff() - */ - void noteOff ( uchar chn, uchar note, uchar vel ); - - /** - * See MidiOut::keyPressure() - */ - void keyPressure ( uchar chn, uchar note, uchar vel ); - - /** - * See MidiOut::chnPatchChange() - */ - void chnPatchChange ( uchar chn, uchar patch ); - - /** - * See MidiOut::chnPressure() - */ - void chnPressure ( uchar chn, uchar vel ); - - /** - * See MidiOut::chnPitchBender() - */ - void chnPitchBender ( uchar chn, uchar lsb, uchar msb ); - - /** - * See MidiOut::chnController() - */ - void chnController ( uchar chn, uchar ctl , uchar v ); - - /** - * It's an empty function, as AWE devices don't support System Exclusive - * messages - */ - void sysex ( uchar *data,ulong size); -}; - -#endif diff --git a/libkmid/tests/Kathzy.mid b/libkmid/tests/Kathzy.mid deleted file mode 100644 index f3a857fba..000000000 Binary files a/libkmid/tests/Kathzy.mid and /dev/null differ diff --git a/libkmid/tests/Makefile.am b/libkmid/tests/Makefile.am deleted file mode 100644 index 58bf5d58b..000000000 --- a/libkmid/tests/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ - -INCLUDES = -I$(srcdir)/.. $(all_includes) - -noinst_PROGRAMS = ctest apitest notesoff - -ctest_SOURCES = ctest.c -ctest_LDADD = ../libkmid.la - -apitest_SOURCES = apitest.cc -apitest_LDADD = ../libkmid.la - -notesoff_SOURCES = notesoff.cc -notesoff_LDADD = ../libkmid.la - diff --git a/libkmid/tests/apitest.cc b/libkmid/tests/apitest.cc deleted file mode 100644 index 308fe2957..000000000 --- a/libkmid/tests/apitest.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -int main (int , char **) -{ - printf("Libkmid test2 . (C) 2000 Antonio Larrosa Jimenez . Malaga (Spain)\n"); - printf("Using libkmid from a simple C++ application\n"); - - KMidSimpleAPI::kMidInit(); - KMidSimpleAPI::kMidLoad("Kathzy.mid"); - KMidSimpleAPI::kMidPlay(); - - for (int i=0;i<30;i++) - { - printf("%d/30 seconds\n",i+1); - sleep(1); - }; - - KMidSimpleAPI::kMidStop(); - KMidSimpleAPI::kMidDestruct(); - - return 0; -}; - diff --git a/libkmid/tests/ctest.c b/libkmid/tests/ctest.c deleted file mode 100644 index 6e427a2c7..000000000 --- a/libkmid/tests/ctest.c +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include - -int main (int argc, char **argv) -{ - int i; - char c; - - printf("Test1 %s. Using libkmid from a simple C application\n",kMidVersion()); - printf("%s\n",kMidCopyright()); - - if (kMidInit()!=0) - { - printf("Error initializing libkmid\n"); - return 0; - } - - if (kMidDevices()!=0) - { - printf("Available devices :\n"); - for (i=0;i -#include -#include -#include - -int main (int , char **) -{ - printf("Libkmid Notes Off . (C) 2000 Antonio Larrosa Jimenez . Malaga (Spain)\n"); - printf("Using libkmid from a simple C++ application\n"); - - KMidSimpleAPI::kMidInit(); - - kMid.midi->checkInit(); - kMid.midi->openDev(); - kMid.midi->initDev(); - - kMid.midi->allNotesOff(); - kMid.midi->closeDev(); - - KMidSimpleAPI::kMidDestruct(); - - return 0; -}; - diff --git a/libkmid/track.cc b/libkmid/track.cc deleted file mode 100644 index ccaaf69d2..000000000 --- a/libkmid/track.cc +++ /dev/null @@ -1,566 +0,0 @@ -/************************************************************************** - - track.cc - class track, which has a midi file track and its events - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ - -#include "track.h" -#include -#include "sndcard.h" -#include "midispec.h" -#include "midfile.h" - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#define T2MS(ticks) (((double)ticks)*(double)60000L)/((double)tempoToMetronomeTempo(tempo)*(double)tPCN) - -#define MS2T(ms) (((ms)*(double)tempoToMetronomeTempo(tempo)*(double)tPCN)/((double)60000L)) - -#define PEDANTIC_TRACK -#define CHANGETEMPO_ONLY_IN_TRACK0 -//#define TRACKDEBUG -//#define TRACKDEBUG2 - -MidiTrack::MidiTrack(FILE *file,int tpcn,int Id) -{ - id=Id; - tPCN=tpcn; - currentpos=0; - size=0; - data=0L; - tempo=1000000; - if (feof(file)) - { - clear(); - return; - }; - size=readLong(file); -#ifdef TRACKDEBUG - printf("Track %d : Size %ld\n",id,size); -#endif - data=new uchar[size]; - if (data==NULL) - { - perror("track: Not enough memory ?"); - exit(-1); - } - ulong rsize=0; - if ((rsize=fread(data,1,size,file))!=size) - { - fprintf(stderr,"track (%d): File is corrupt : Couldn't load track (%ld!=%ld) !!\n", id, rsize, size); - size=rsize; - }; - /* - ptrdata=data; - current_ticks=0; - delta_ticks=readVariableLengthValue(); - wait_ticks=delta_ticks; - endoftrack=0; - */ - init(); -} - -MidiTrack::~MidiTrack() -{ - delete data; - endoftrack=1; - currentpos=0; - size=0; -} - -int MidiTrack::power2to(int i) -{ - return 1<=size) - { - endoftrack=1; - fprintf(stderr, "track (%d) : EndofTrack found by accident !\n",id); - delta_ticks = wait_ticks = ~0; - time_at_next_event=10000 * 60000L; - return 0; - } - else -#endif - { - dticks=(dticks << 7) | (*ptrdata) & 0x7F; - ptrdata++;currentpos++; - } - - } - dticks=((dticks << 7) | (*ptrdata) & 0x7F); - ptrdata++;currentpos++; - -#ifdef PEDANTIC_TRACK - - if (currentpos>=size) - { - endoftrack=1; - fprintf(stderr,"track (%d): EndofTrack found by accident 2 !\n",id); - dticks=0; - delta_ticks = wait_ticks = ~0; - time_at_next_event=10000 * 60000L; - return 0; - } -#endif -#ifdef TRACKDEBUG - printfdebug("track(%d): DTICKS : %ld\n",id,dticks); - usleep(10); -#endif - return dticks; -} - -int MidiTrack::ticksPassed (ulong ticks) -{ - if (endoftrack==1) return 0; - if (ticks>wait_ticks) - { - printfdebug("track (%d): ERROR : TICKS PASSED > WAIT TICKS\n", id); - return 1; - } - wait_ticks-=ticks; - return 0; -} - -int MidiTrack::msPassed (ulong ms) -{ - if (endoftrack==1) return 0; - current_time+=ms; - //fprintf(stderr, "old + %ld = CURR %g ", ms,current_time); - if ( current_time>time_at_next_event ) - { - fprintf(stderr, "track (%d): ERROR : MS PASSED > WAIT MS\n", id); - return 1; - } -#ifdef TRACKDEBUG - if (current_time==time_at_next_event) printfdebug("track(%d): _OK_",id); -#endif - return 0; -} - -int MidiTrack::currentMs(double ms) -{ - if (endoftrack==1) return 0; - current_time=ms; - //printfdebug("CURR %g",current_time); -#ifdef PEDANTIC_TRACK - if (current_time>time_at_next_event) - { - fprintf(stderr,"track(%d): ERROR : MS PASSED > WAIT MS\n", id); - exit(-1); - return 1; - } -#endif - return 0; -} - -void MidiTrack::readEvent(MidiEvent *ev) -{ - int i,j; - if (endoftrack==1) - { - ev->command=0; - return; - } - /* - printfdebug("...... %d\n",id); - printfdebug("current : %g , tane : %g\n",current_time,time_at_next_event); - printfdebug("......\n"); - */ - int skip_event=0; - current_time=time_at_next_event; - if (((*ptrdata)&0x80)!=0) - { - ev->command=(*ptrdata); - ptrdata++;currentpos++; - lastcommand=ev->command; - } - else - { - ev->command=lastcommand; - } - -#ifdef PEDANTIC_TRACK - if (currentpos>=size) - { - endoftrack=1; - delta_ticks = wait_ticks = ~0; - time_at_next_event=10000 * 60000L; - ev->command=MIDI_SYSTEM_PREFIX; - ev->chn=0xF; - ev->d1=ME_END_OF_TRACK; - fprintf(stderr, "track (%d): EndofTrack found by accident 3\n",id); - return; - } -#endif - - ev->chn=ev->command & 0xF; - ev->command=ev->command & 0xF0; - switch (ev->command) - { - case (MIDI_NOTEON) : - ev->note = *ptrdata;ptrdata++;currentpos++; - ev->vel = *ptrdata;ptrdata++;currentpos++; - if (ev->vel==0) - note[ev->chn][ev->note]=FALSE; - else - note[ev->chn][ev->note]=TRUE; - -#ifdef TRACKDEBUG2 - if (ev->chn==6) { - if (ev->vel==0) printfdebug("Note Onf\n"); - else printfdebug("Note On\n"); - }; -#endif - break; - case (MIDI_NOTEOFF) : -#ifdef TRACKDEBUG2 - if (ev->chn==6) printfdebug("Note Off\n"); -#endif - ev->note = *ptrdata;ptrdata++;currentpos++; - ev->vel = *ptrdata;ptrdata++;currentpos++; - note[ev->chn][ev->note]=FALSE; - - break; - case (MIDI_KEY_PRESSURE) : -#ifdef TRACKDEBUG2 - if (ev->chn==6) printfdebug ("Key press\n"); -#endif - ev->note = *ptrdata;ptrdata++;currentpos++; - ev->vel = *ptrdata;ptrdata++;currentpos++; - break; - case (MIDI_PGM_CHANGE) : -#ifdef TRACKDEBUG2 - if (ev->chn==6) printfdebug ("Pgm\n"); -#endif - ev->patch = *ptrdata;ptrdata++;currentpos++; - break; - case (MIDI_CHN_PRESSURE) : -#ifdef TRACKDEBUG2 - if (ev->chn==6) printfdebug ("Chn press\n"); -#endif - ev->vel = *ptrdata;ptrdata++;currentpos++; - break; - case (MIDI_PITCH_BEND) : -#ifdef TRACKDEBUG2 - if (ev->chn==6) printfdebug ("Pitch\n"); -#endif - ev->d1 = *ptrdata;ptrdata++;currentpos++; - ev->d2 = *ptrdata;ptrdata++;currentpos++; - break; - case (MIDI_CTL_CHANGE) : -#ifdef TRACKDEBUG2 - if (ev->chn==6) printfdebug (stderr, "Ctl\n"); -#endif - ev->ctl = *ptrdata;ptrdata++; currentpos++; - ev->d1 = *ptrdata;ptrdata++;currentpos++; - /* - switch (ev->ctl) - { - case (96) : printfdebug("RPN Increment\n");break; - case (97) : printfdebug("RPN Decrement\n");break; - case (98) : printfdebug("nRPN 98 %d\n",ev->d1);break; - case (99) : printfdebug("nRPN 99 %d\n",ev->d1);break; - case (100) : printfdebug("RPN 100 %d\n",ev->d1);break; - case (101) : printfdebug("RPN 101 %d\n",ev->d1);break; - }; - */ - break; - - case (MIDI_SYSTEM_PREFIX) : -#ifdef TRACKDEBUG2 - if (ev->chn==6) printfdebug ("Sys Prefix\n"); -#endif - switch ((ev->command|ev->chn)) - { - case (0xF0) : - case (0xF7) : - ev->length=readVariableLengthValue(); -#ifdef PEDANTIC_TRACK - if (endoftrack) - { - ev->command=MIDI_SYSTEM_PREFIX; - ev->chn=0xF; - ev->d1=ME_END_OF_TRACK; - } - else -#endif - { - ev->data=ptrdata; - ptrdata+=ev->length;currentpos+=ev->length; - } - break; - case (0xFE): - case (0xF8): - // printfdebug("Active sensing\n"); - break; - case (META_EVENT) : - ev->d1=*ptrdata;ptrdata++;currentpos++; - switch (ev->d1) - { - case (ME_END_OF_TRACK) : - i=0; - j=0; - while ((i<16)&&(note[i][j]==FALSE)) - { - j++; - if (j==128) { j=0; i++; }; - } - if (i<16) // that is, if there is any key still pressed - { - ptrdata--;currentpos--; - ev->chn=i; - ev->command=MIDI_NOTEOFF; - ev->note = j; - ev->vel = 0; - note[ev->chn][ev->note]=FALSE; - fprintf(stderr,"Note Off(simulated)\n"); - return; - } - else - { - endoftrack=1; - delta_ticks = wait_ticks = ~0; - time_at_next_event=10000 * 60000L; -#ifdef TRACKDEBUG - printfdebug("EndofTrack %d event\n",id); -#endif - } - break; - case (ME_SET_TEMPO): - ev->length=readVariableLengthValue(); -#ifdef PEDANTIC_TRACK - if (endoftrack) - { - ev->command=MIDI_SYSTEM_PREFIX; - ev->chn=0xF; - ev->d1=ME_END_OF_TRACK; - } - else -#endif - { - ev->data=ptrdata; - ptrdata+=ev->length;currentpos+=ev->length; - // tempo=((ev->data[0]<<16)|(ev->data[1]<<8)|(ev->data[2])); - // ticks_from_previous_tempochange=0; - // time_at_previous_tempochange=current_time; -#ifdef TRACKDEBUG - printfdebug("Track %d : Set Tempo : %ld\n",id,tempo); -#endif -#ifdef CHANGETEMPO_ONLY_IN_TRACK0 - if (id!=0) skip_event=1; -#endif - } - break; - case (ME_TIME_SIGNATURE) : - ev->length=*ptrdata;ptrdata++;currentpos++; - ev->d2=*ptrdata;ptrdata++;currentpos++; - ev->d3=power2to(*ptrdata);ptrdata++;currentpos++; - ev->d4=*ptrdata;ptrdata++;currentpos++; - ev->d5=*ptrdata;ptrdata++;currentpos++; -#ifdef TRACKDEBUG - printfdebug("TIME SIGNATURE :\n"); - printfdebug("%d\n",ev->d2); - printfdebug("---- %d metronome , %d number of 32nd notes per quarter note\n",ev->d4,ev->d5); - printfdebug("%d\n",ev->d3); -#endif - break; - case (ME_TRACK_SEQ_NUMBER) : - case (ME_TEXT) : - case (ME_COPYRIGHT) : - case (ME_SEQ_OR_TRACK_NAME) : - case (ME_TRACK_INSTR_NAME) : - case (ME_LYRIC) : - case (ME_MARKER) : - case (ME_CUE_POINT) : - case (ME_CHANNEL_PREFIX) : - case (ME_MIDI_PORT) : - case (ME_SMPTE_OFFSET) : - case (ME_KEY_SIGNATURE) : - ev->length=readVariableLengthValue(); -#ifdef PEDANTIC_TRACK - if (endoftrack) - { - ev->command=MIDI_SYSTEM_PREFIX; - ev->chn=0xF; - ev->d1=ME_END_OF_TRACK; - } - else -#endif - { - ev->data=ptrdata; - ptrdata+=ev->length;currentpos+=ev->length; - } - break; - default: -#ifdef GENERAL_DEBUG_MESSAGES - fprintf(stderr,"track (%d) : Default handler for meta event " \ - "0x%x\n", id, ev->d1); -#endif - ev->length=readVariableLengthValue(); -#ifdef PEDANTIC_TRACK - if (endoftrack) - { - ev->command=MIDI_SYSTEM_PREFIX; - ev->chn=0xF; - ev->d1=ME_END_OF_TRACK; - } - else -#endif - { - ev->data=ptrdata; - ptrdata+=ev->length;currentpos+=ev->length; - } - break; - } - break; - default : - fprintf(stderr,"track (%d): Default handler for system event 0x%x\n", - id, (ev->command|ev->chn)); - break; - } - break; - default : - fprintf(stderr,"track (%d): Default handler for event 0x%x\n", - id, (ev->command|ev->chn)); - break; - } -#ifdef PEDANTIC_TRACK - if (currentpos>=size) - { - endoftrack=1; - delta_ticks = wait_ticks = ~0; - time_at_next_event=10000 * 60000L; - printfdebug("track (%d): EndofTrack reached\n",id); - } -#endif - if (endoftrack==0) - { - current_ticks+=delta_ticks; - delta_ticks=readVariableLengthValue(); -#ifdef PEDANTIC_TRACK - if (endoftrack) - { - ev->command=MIDI_SYSTEM_PREFIX; - ev->chn=0xF; - ev->d1=ME_END_OF_TRACK; - return; - } -#endif - ticks_from_previous_tempochange+=delta_ticks; - - time_at_next_event=T2MS(ticks_from_previous_tempochange)+time_at_previous_tempochange; - /* - printf("tane2 : %g, ticks : %g, delta_ticks %ld, tempo : %ld\n", - time_at_next_event,ticks_from_previous_tempochange,delta_ticks,tempo); - printf("timeatprevtc %g , curr %g\n",time_at_previous_tempochange,current_time); - */ - wait_ticks=delta_ticks; - - } - if (skip_event) readEvent(ev); -} - - -void MidiTrack::clear(void) -{ - endoftrack=1; - ptrdata=data; - current_ticks=0; - currentpos=0; - - for (int i=0;i<16;i++) - for (int j=0;j<128;j++) - note[i][j]=FALSE; - - delta_ticks = wait_ticks = ~0; - time_at_previous_tempochange=0; - current_time=0; - ticks_from_previous_tempochange=0; - tempo=1000000; - time_at_next_event=10000 * 60000L; - -} - - -void MidiTrack::init(void) -{ - if (data==0L) { clear(); return; }; - endoftrack=0; - ptrdata=data; - current_ticks=0; - currentpos=0; - - for (int i=0;i<16;i++) - for (int j=0;j<128;j++) - note[i][j]=FALSE; - - delta_ticks=readVariableLengthValue(); - if (endoftrack) return; - wait_ticks=delta_ticks; - - - time_at_previous_tempochange=0; - current_time=0; - ticks_from_previous_tempochange=wait_ticks; - tempo=1000000; - time_at_next_event=T2MS(delta_ticks); - //printf("tane1 : %g\n",time_at_next_event); -} - -void MidiTrack::changeTempo(ulong t) -{ - if (endoftrack==1) return; - if (tempo==t) return; - double ticks; - time_at_previous_tempochange=current_time; - ticks=MS2T(time_at_next_event-current_time); - tempo=t; - time_at_next_event=T2MS(ticks)+current_time; - ticks_from_previous_tempochange=ticks; - -} - -/* -double MidiTrack::absMsOfNextEvent (void) -{ - //printf("%d : %g\n",id,time_at_next_event); - return time_at_next_event; -} -*/ - -#undef T2MS -#undef MS2T diff --git a/libkmid/track.h b/libkmid/track.h deleted file mode 100644 index 073fc9825..000000000 --- a/libkmid/track.h +++ /dev/null @@ -1,237 +0,0 @@ -/* track.h - class track, which has a midi file track and its events - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _TRACK_H -#define _TRACK_H - -#include -#include - -/** - * An structure that represents a MIDI event. - * - * @short Represents a MIDI event - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -struct MidiEvent -{ - /** - * MIDI Command - * - * Caution, if a command doesn't use a variable, it may contain garbage. - */ - uchar command; - - /** - * Channel - */ - uchar chn; - - /** - * Note - */ - uchar note; - - /** - * Velocity - */ - uchar vel; - - /** - * Patch (if command was a change patch command) - */ - uchar patch; - - /** - * Patch (if command was a controller command) - */ - uchar ctl; - - /** - * Data 1 - */ - uchar d1; - - /** - * Data 2 - */ - uchar d2; - - /** - * Data 3 - */ - uchar d3; - - /** - * Data 4 - */ - uchar d4; - - /** - * Data 5 - */ - uchar d5; - - /** - * Data 6 - */ - uchar d6; - - /** - * Length of the generic data variable - */ - ulong length; - - /** - * The data for commands like text, sysex, etc. - */ - uchar *data; - -}; - -/** - * Stores a MIDI track. This can be thought of as a list of MIDI events. - * - * The data types used to store the track is similar to how events are - * stored on a MIDI file, but used in a way that allows for faster parses. - * - * This class is used on MidiPlayer::loadSong() to load the song and - * later play it with MidiPlayer::play(). - * - * @short Stores a MIDI track with a simple API - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class MidiTrack -{ - private: - class MidiTrackPrivate; - MidiTrackPrivate *d; - - int id; - - ulong size; - uchar *data; - uchar *ptrdata; - - bool note[16][128]; // Notes that are set on or off by this track - ulong current_ticks; // Total number of ticks since beginning of song - ulong delta_ticks; // Delta ticks from previous event to next event - ulong wait_ticks; // Wait ticks from previous event in other track - // to next event in this track - - ulong currentpos; // Some songs don't have a endoftrack event, so - // we have to see when currentpos > size - int endoftrack; - - ulong readVariableLengthValue(void); - - uchar lastcommand; // This is to run light without overbyte :-) - - - double current_time; // in ms. - double time_at_previous_tempochange; // in ms. - double ticks_from_previous_tempochange; // in ticks - // double time_to_next_event; // in ms. - double time_at_next_event; // in ms. - int tPCN; - ulong tempo; - - int power2to(int i); - - public: - /** - * Constructor. - * @param file the file to read the track from. It should be ready at the - * start of a track. MidiTrack reads just that track and the file is left at - * the end of this track). - * @param tpcn the ticks per cuarter note used in this file. - * @param Id the ID for this track. - */ - MidiTrack(FILE *file,int tpcn,int Id); - - /** - * Destructor - */ - ~MidiTrack(); - - /** - * Makes the iterator advance the given number of ticks. - * - * @return 0 if OK, and 1 if you didn't handle this track well and you - * forgot to take an event (thing that will never happen if you use - * MidiPlayer::play() ). - */ - int ticksPassed (ulong ticks); - - /** - * Makes the iterator advance the given number of milliseconds. - * - * @return 0 if OK, and 1 if you didn't handle this track well and you - * forgot to take an event (thing that will never happen if you use - * MidiPlayer::play() ). - */ - int msPassed (ulong ms); - - /** - * Returns the current millisecond which the iterator is at. - */ - int currentMs (double ms); - - /** - * Returns the number of ticks left for the next event. - */ - ulong waitTicks (void) { return wait_ticks; } - - // ulong waitMs (void) {return time_to_next_event;}; - - /** - * Returns the absolute number of milliseconds of the next event. - */ - double absMsOfNextEvent (void) { return time_at_next_event; } - - /** - * Change the tempo of the song. - */ - void changeTempo(ulong t); - - /** - * Reads the event at the iterator position, and puts it on the structure - * pointed to by @p ev. - */ - void readEvent(MidiEvent *ev); - - /** - * Initializes the iterator. - */ - void init(void); - - /** - * Clears the internal variables. - */ - void clear(void); - -}; - -#endif diff --git a/libkmid/voiceman.cc b/libkmid/voiceman.cc deleted file mode 100644 index 8e7863720..000000000 --- a/libkmid/voiceman.cc +++ /dev/null @@ -1,279 +0,0 @@ -/************************************************************************** - - voiceman.cc - The VoiceManager class handles a set of voices for synths - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ - -#include "voiceman.h" -#include -#ifdef HAVE_CONFIG_H -#include -#endif - -VoiceManager::VoiceManager(int totalvoices) -{ - nvoices=totalvoices; - - FirstVoice=new voice; - FirstVoice->id=0; - FirstVoice->channel=0; - FirstVoice->note=0; - FirstVoice->used=0; - FirstVoice->prev=NULL; - - voice *ptrb=FirstVoice; - voice *ptr=NULL; - int i; - for (i=1;inext=ptr; - ptr->id=i; - ptr->channel=0; - ptr->note=0; - ptr->used=0; - ptr->prev=ptrb; - ptrb=ptr; - } - LastVoice=ptr; - LastVoice->next=NULL; - LastnotusedVoice=LastVoice; - - VoiceList=new voice *[nvoices]; - ptr=FirstVoice; - for (i=0;inext; - } - searcher_aid=new voice; -} - -VoiceManager::~VoiceManager() -{ - voice *ptr=FirstVoice; - voice *ptr2; - while (ptr!=NULL) - { - ptr2=ptr->next; - delete ptr; - ptr=ptr2; - } - FirstVoice=NULL; - LastVoice=NULL; - LastnotusedVoice=NULL; - - delete [] VoiceList; - VoiceList=NULL; - - delete searcher_aid; -} - -void VoiceManager::clearLists(void) -{ -#ifdef VOICEMANDEBUG - printf("voicemanager::cleanLists\n"); -#endif - voice *ptr=FirstVoice; - voice *ptr2=FirstVoice; - while (ptr!=NULL) - { - ptr->used=0; - ptr2=ptr; - ptr=ptr->next; - } - LastVoice=ptr2; - LastnotusedVoice=ptr2; - -} - -int VoiceManager::allocateVoice(int chn,int key) -{ - // First, we take the allocated voice out of the first place of the list - if ((LastnotusedVoice!=NULL)&&(LastnotusedVoice->id==FirstVoice->id)) - { -#ifdef VOICEMANDEBUG - printf("Used last voice !\n"); -#endif - LastnotusedVoice=NULL; - } - voice *newvoice=FirstVoice; - FirstVoice=FirstVoice->next; - FirstVoice->prev=NULL; - -#ifdef VOICEMANDEBUG - printf("Allocating id :%d\n",newvoice->id); -#endif - // then we put the allocated voice at the end of the list - LastVoice->next=newvoice; - newvoice->prev=LastVoice; - LastVoice=newvoice; - LastVoice->next=NULL; - - newvoice->channel=chn; - newvoice->note=key; - -#ifdef VOICEMANDEBUG - if (newvoice->used==1) - { - printf("Replacing voice : %d\n",newvoice->id); - } -#endif - newvoice->used=1; - - //dispStat(); - return newvoice->id; -} - -void VoiceManager::deallocateVoice(int id) -{ - voice *delvoice=VoiceList[id]; -#ifdef VOICEMANDEBUG - printf("Deallocating id :%d\n",id); -#endif - if (delvoice->id==LastVoice->id) - { - LastVoice=delvoice->prev; - LastVoice->next=NULL; - - if (LastnotusedVoice==NULL) - { - delvoice->next=FirstVoice; - FirstVoice->prev=delvoice; - FirstVoice=delvoice; - FirstVoice->prev=NULL; - LastnotusedVoice=FirstVoice; - } - else - { - if (LastnotusedVoice->next==NULL) - { - LastnotusedVoice->next=delvoice; - delvoice->prev=LastnotusedVoice; - delvoice->next=NULL; - LastnotusedVoice=delvoice; - LastVoice=delvoice; - } - else - { - delvoice->next=LastnotusedVoice->next; - delvoice->next->prev=delvoice; - delvoice->prev=LastnotusedVoice; - LastnotusedVoice->next=delvoice; - LastnotusedVoice=delvoice; - } - } - } - else - { - if (delvoice->prev!=NULL) - { - delvoice->prev->next=delvoice->next; - delvoice->next->prev=delvoice->prev; - if (LastnotusedVoice==NULL) - { - delvoice->next=FirstVoice; - FirstVoice->prev=delvoice; - FirstVoice=delvoice; - FirstVoice->prev=NULL; - LastnotusedVoice=FirstVoice; } - else - { - if (LastnotusedVoice->next==NULL) - { - LastnotusedVoice->next=delvoice; - delvoice->prev=LastnotusedVoice; - delvoice->next=NULL; - LastnotusedVoice=delvoice; - LastVoice=delvoice; - } - else - { - delvoice->next=LastnotusedVoice->next; - delvoice->next->prev=delvoice; - delvoice->prev=LastnotusedVoice; - LastnotusedVoice->next=delvoice; - LastnotusedVoice=delvoice; - } - } - } - } - delvoice->used=0; - - // dispStat(); -} - -void VoiceManager::initSearch(void) -{ - searcher=searcher_aid; - searcher_aid->prev=LastVoice; -} - -int VoiceManager::search(int chn) -{ - if (searcher==NULL) return -1; - searcher=searcher->prev; - - while (searcher!=NULL) - { - if (searcher->used==0) return -1; - if (searcher->channel==chn) - { - return searcher->id; - } - searcher=searcher->prev; - } - return -1; -} - -int VoiceManager::search(int chn,int note) -{ - if (searcher==NULL) return -1; - searcher=searcher->prev; - while ((searcher!=NULL)) - { - if (searcher->used==0) return -1; - if ((searcher->channel==chn)&&(searcher->note==note)) - { - return searcher->id; - } - searcher=searcher->prev; - } - return -1; -} - -/* -void VoiceManager::dispStat(void) -{ -#ifdef VOICEMANDEBUG - printf("Stats\n"); - voice *ptr=FirstVoice; - while (ptr!=NULL) - { - printf("Voice %d is %s\n",ptr->id,(ptr->used==0)?("off"):("on")); - ptr=ptr->next; - } - if (LastnotusedVoice!=NULL) printf("LnuV = %d\n",LastnotusedVoice->id); -#endif -} -*/ diff --git a/libkmid/voiceman.h b/libkmid/voiceman.h deleted file mode 100644 index 79dee9d3d..000000000 --- a/libkmid/voiceman.h +++ /dev/null @@ -1,172 +0,0 @@ -/* voiceman.h - The VoiceManager class handles a set of voices for synths - This file is part of LibKMid 0.9.5 - Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez - LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - Send comments and bug fixes to Antonio Larrosa - -***************************************************************************/ -#ifndef _VOICEMAN_H -#define _VOICEMAN_H - -/** - * @internal - * Manages the voices used by synthesizers. - * - * @short Manages internally the voices used by synth devices. - * @version 0.9.5 17/01/2000 - * @author Antonio Larrosa Jimenez - */ -class VoiceManager -{ - private: - class VoiceManagerPrivate; - VoiceManagerPrivate *d; - - /** - * Number of voices managed by this object. - */ - int nvoices; - - /** - * @internal - */ - struct voice - { - int id; - int channel; - int note; - int used; - - struct voice *prev; - struct voice *next; - }; - - /** - * Points to the beginning of the voice list, that is, to - * the older voice which is ready to be used. - */ - voice *FirstVoice; - - /** - * Points to the last voice, that is, the latest (most recently) used voice. - */ - voice *LastVoice; - - /** - * Points to the latest (list order) not used voice, - * that is, to where deallocated voices will be moved. - */ - voice *LastnotusedVoice; - - /** - * Array with pointers to the voices, arranged by ID for allow faster searches. - */ - voice **VoiceList; - - /** - * @internal - * This variable is used to search channels. - */ - voice *searcher; - - /** - * @internal - * An auxiliary variable for simpler searches. - */ - voice *searcher_aid; - - public: - /** - * Cronstructor. - */ - VoiceManager(int totalvoices); - - /** - * Destructor. - */ - ~VoiceManager(); - - /** - * Allocates a voice used in channel @p chn, and playing key @p key - * @return the voice that should be used. - * - * @see deallocateVoice - */ - - int allocateVoice(int chn,int key); - - /** - * Deallocates the voice with ID @p id. - * - * @see allocateVoice - */ - void deallocateVoice(int id); - - /** - * initSearch() must be called always before search() to initialize - * internal variables. - * - * @see search - */ - void initSearch(void); - - /** - * Returns -1 if channel chn is not currently used, or a voice using - * channel @p chn if any. - * - * Calling search repeteadly, will return all the voices using channel - * @p chn, and a -1 after the last one. - * - * @see initSearch - */ - int search(int chn); - //returns -1 if channel chn is not currently used - // Continue searching for more voices which - // use the channel chn - - /** - * This is a convenience function that differs from the above in that it also - * looks for a specific note (the second parameter) - * - * @see initSearch - */ - int search(int chn,int note); - - /** - * Returns the channel that voice @p v is using. - */ - int channel(int v) {return VoiceList[v]->channel;} - - /** - * Returns the note that voice @p v is playing. - */ - int note(int v) {return VoiceList[v]->note;} - - /** - * Returns true or false if the voice @p v is being used or not respectively. - */ - int used(int v) {return VoiceList[v]->used;} - - /** - * Clears the lists of used voices. - */ - void clearLists(void); -}; - -#endif -- cgit v1.2.1