[AD] BeOS MIDI driver and more

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Here's a patch that adds a MIDI driver to BeAllegro.
MIDI synthesis under BeOS is done via hardware synthetizer or via software
wavetable like the Allegro DIGMID driver; the choice is automatic and BeOS
itself decides what to use depending on your hardware.
The software synthetizer allows to specify the instruments set (among two set
files in a private format), the samples interpolation method and the sampling
rate.
Also, BeOS allows to use a built-in reverberator.
All these things made me to add 4 sound config variables to allegro.cfg, and
I've already documented them in allegro._tx.

Can someone test this driver on his computer?

To Jason Wilkins: this patch also sets the "refresh_rate" variable in
bgfxapi.cpp as static, so that linking problems are solved.

I've used the debugger as you said, but it couldn't trace the stack calls when
the programs crash after setting the gfx mode, so it's useless.
BTW, have you found the problem?

-- 
Angelo Mottola
a.mottola@xxxxxxxxxx
diff -Nru allegro.cvs/allegro.cfg allegro/allegro.cfg
--- allegro.cvs/allegro.cfg	Sat Oct 14 15:50:10 2000
+++ allegro/allegro.cfg	Mon Oct 16 23:34:58 2000
@@ -240,7 +240,12 @@
 #
 #  OSSM     - Open Sound System
 #  DIGI     - DIGMID software wavetable
-
+#
+# BeOS music drivers:
+#
+#  BMID     - BeOS MIDI synthetizer
+#  DIGI     - DIGMID software wavetable
+# 
 midi_card = 
 
 
@@ -358,6 +363,26 @@
 
 # Unix only: size of ALSA driver fragments (buffers)
 alsa_numfrags = 
+
+
+
+# BeOS only: MIDI synthetizer instruments quality (0=low, 1=high)
+be_midi_quality = 
+
+
+
+# BeOS only: MIDI sample mixing frequency in Hz (11025, 22050 or 44100)
+be_midi_freq = 
+
+
+
+# BeOS only: MIDI interpolation (0=none, 1=fast linear, 2=linear)
+be_midi_interpolation = 
+
+
+
+# BeOS only: MIDI reverberation intensity (0 to 5)
+be_midi_reverb = 
 
 
 
diff -Nru allegro.cvs/docs/allegro._tx allegro/docs/allegro._tx
--- allegro.cvs/docs/allegro._tx	Sat Oct 14 15:50:11 2000
+++ allegro/docs/allegro._tx	Mon Oct 16 23:30:05 2000
@@ -883,6 +883,25 @@
 alsa_fragsize = x<br>
    Unix only: size of each ALSA fragment, in samples.
 <li>
+be_midi_quality = x<br>
+   BeOS only: system MIDI synthentetizer instruments quality. 0 uses low
+   quality 8-bit 11 kHz samples, 1 uses 16-bit 22 kHz samples.
+<li>
+be_midi_freq = x<br>
+   BeOS only: MIDI sample mixing frequency in Hz. Can be 11025, 22050 or
+   44100.
+<li>
+be_midi_interpolation = x<br>
+   BeOS only: specifies the MIDI samples interpolation method. 0 doesn't
+   interpolate, it's fast but has the worst quality; 1 does a fast
+   interpolation with better performances, but it's a bit slower than the
+   previous method; 2 does a linear interpolation between samples, it is the
+   slowest method but gives the best performances.
+<li>
+be_midi_reverb = x<br>
+   BeOS only: reverberation intensity, from 0 to 5. 0 disables it, 5 is the
+   strongest one. 
+<li>
 patches = x<br>
    Specifies where to find the sample set for the DIGMID driver. This can 
    either be a Gravis style directory containing a collection of .pat files 
diff -Nru allegro.cvs/include/allegro/aintbeos.h allegro/include/allegro/aintbeos.h
--- allegro.cvs/include/allegro/aintbeos.h	Sat Oct 14 15:50:15 2000
+++ allegro/include/allegro/aintbeos.h	Sun Oct 15 11:08:52 2000
@@ -79,6 +79,16 @@
 int be_sound_buffer_size();
 int be_sound_mixer_volume(int volume);
 
+int be_midi_detect(int input);
+int be_midi_init(int input, int voices);
+void be_midi_exit(int input);
+int be_midi_mixer_volume(int volume);
+void be_midi_key_on(int inst, int note, int bend, int vol, int pan);
+void be_midi_key_off(int voice);
+void be_midi_set_volume(int voice, int vol);
+void be_midi_set_pitch(int voice, int note, int bend);
+void be_midi_set_pan(int voice, int pan);
+
 #ifdef __cplusplus
 }
 #endif
diff -Nru allegro.cvs/include/allegro/albeos.h allegro/include/allegro/albeos.h
--- allegro.cvs/include/allegro/albeos.h	Sat Oct 14 15:50:15 2000
+++ allegro/include/allegro/albeos.h	Sat Oct 14 16:40:08 2000
@@ -60,7 +60,7 @@
 
 /* midi drivers */
 #define MIDI_BEOS             AL_ID('B','M','I','D')
-//AL_VAR(MIDI_DRIVER, midi_beos);
+AL_VAR(MIDI_DRIVER, midi_beos);
 
 #define GFX_DRIVER_BEOS                                                 \
    { GFX_BEOS_FULLSCREEN,      &gfx_beos_fullscreen,      TRUE },	\
@@ -72,7 +72,7 @@
    {  DIGI_BEOS,       &digi_beos,      TRUE  },
 
 #define MIDI_DRIVER_BEOS                                                \
-   /* {  MIDI_BEOS,       &midi_beos,      TRUE  }, */
+   {  MIDI_BEOS,       &midi_beos,      TRUE  },
 
 #define JOYSTICK_DRIVER_BEOS                                            \
    {  JOYSTICK_BEOS,   &joystick_beos,  TRUE  },
diff -Nru allegro.cvs/makefile.be allegro/makefile.be
--- allegro.cvs/makefile.be	Sat Oct 14 15:50:19 2000
+++ allegro/makefile.be	Sat Oct 14 20:52:32 2000
@@ -42,7 +42,7 @@
 # -------- debugging build --------
 CFLAGS = -DDEBUGMODE=$(DEBUGMODE) $(WFLAGS) -g -O0
 SFLAGS = -DDEBUGMODE=$(DEBUGMODE) $(WFLAGS)
-LFLAGS = -lbe -lgame -ldevice -g
+LFLAGS = -lbe -lgame -ldevice -lmidi -g
 
 
 else
@@ -51,7 +51,7 @@
 # -------- profiling build --------
 CFLAGS = $(WFLAGS) $(OFLAGS) -pg
 SFLAGS = $(WFLAGS)
-LFLAGS = -lbe -lgame -ldevice -pg
+LFLAGS = -lbe -lgame -ldevice -lmidi -pg
 
 else
 
@@ -60,9 +60,9 @@
 SFLAGS = $(WFLAGS)
 
 ifdef SYMBOLMODE
-LFLAGS = -lbe -lgame -ldevice -s
+LFLAGS = -lbe -lgame -ldevice -lmidi -s
 else
-LFLAGS = -lbe -lgame -ldevice
+LFLAGS = -lbe -lgame -ldevice -lmidi
 endif
 
 endif
diff -Nru allegro.cvs/makefile.lst allegro/makefile.lst
--- allegro.cvs/makefile.lst	Sat Oct 14 15:50:19 2000
+++ allegro/makefile.lst	Sat Oct 14 20:31:02 2000
@@ -196,6 +196,7 @@
 	src/beos/bkeydrv.c \
 	src/beos/bmidi.c \
 	src/beos/bmididrv.c \
+	src/beos/bmidiapi.cpp \
 	src/beos/bmousapi.cpp \
 	src/beos/bmousdrv.c \
 	src/beos/bmouse.c \
diff -Nru allegro.cvs/src/beos/bgfxapi.cpp allegro/src/beos/bgfxapi.cpp
--- allegro.cvs/src/beos/bgfxapi.cpp	Sat Oct 14 15:50:31 2000
+++ allegro/src/beos/bgfxapi.cpp	Mon Oct 16 13:21:37 2000
@@ -129,7 +129,7 @@
 sem_id fullscreen_lock = -1;
 int32  lock_count      = 0;
 
-int refresh_rate = 70;
+static int refresh_rate = 70;
 
 BeAllegroWindow *be_allegro_window = NULL;
 BeAllegroView   *be_allegro_view   = NULL;
diff -Nru allegro.cvs/src/beos/bmidi.c allegro/src/beos/bmidi.c
--- allegro.cvs/src/beos/bmidi.c	Sat Oct 14 15:50:31 2000
+++ allegro/src/beos/bmidi.c	Mon Oct 16 16:36:14 2000
@@ -8,18 +8,43 @@
  *                                           /\____/
  *                                           \_/__/
  *
- *      Stuff for BeOS.
+ *      MIDI driver for BeOS.
  *
- *      By Jason Wilkins.
+ *      By Angelo Mottola.
  *
  *      See readme.txt for copyright information.
  */
 
 #include "allegro.h"
 #include "allegro/aintern.h"
+#include "allegro/aintbeos.h"
 
 #ifndef ALLEGRO_BEOS
 #error something is wrong with the makefile
 #endif                
 
-//MIDI_DRIVER midi_beos;
+MIDI_DRIVER midi_beos =
+{
+   MIDI_BEOS,               /* driver ID code */
+   empty_string,            /* driver name */
+   empty_string,            /* description string */
+   "BeOS MIDI",             /* ASCII format name string */
+   16,                      /* available voices */
+   0,                       /* voice number offset */
+   28,                      /* maximum voices we can support */
+   0,                       /* default number of voices to use */
+   10, 10,                  /* reserved voice range */
+   be_midi_detect,          /* AL_METHOD(int,  detect, (int input)); */
+   be_midi_init,            /* AL_METHOD(int,  init, (int input, int voices)); */
+   be_midi_exit,            /* AL_METHOD(void, exit, (int input)); */
+   be_midi_mixer_volume,    /* AL_METHOD(int,  mixer_volume, (int volume)); */
+   NULL,                    /* AL_METHOD(void, raw_midi, (int data)); */
+   _dummy_load_patches,     /* AL_METHOD(int,  load_patches, (AL_CONST char *patches, AL_CONST char *drums)); */
+   _dummy_adjust_patches,   /* AL_METHOD(void, adjust_patches, (AL_CONST char *patches, AL_CONST char *drums)); */
+   be_midi_key_on,          /* AL_METHOD(void, key_on, (int inst, int note, int bend, int vol, int pan)); */
+   be_midi_key_off,         /* AL_METHOD(void, key_off, (int voice)); */
+   be_midi_set_volume,      /* AL_METHOD(void, set_volume, (int voice, int vol)); */
+   be_midi_set_pitch,       /* AL_METHOD(void, set_pitch, (int voice, int note, int bend)); */
+   be_midi_set_pan,         /* AL_METHOD(void, set_pan, (int voice, int pan)); */
+   _dummy_noop2,            /* AL_METHOD(void, set_vibrato, (int voice, int amount)); */
+};
diff -Nru allegro.cvs/src/beos/bmidiapi.cpp allegro/src/beos/bmidiapi.cpp
--- allegro.cvs/src/beos/bmidiapi.cpp	Thu Jan  1 00:00:00 1970
+++ allegro/src/beos/bmidiapi.cpp	Tue Oct 17 01:35:11 2000
@@ -0,0 +1,237 @@
+/*         ______   ___    ___ 
+ *        /\  _  \ /\_ \  /\_ \ 
+ *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___ 
+ *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
+ *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
+ *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
+ *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
+ *                                           /\____/
+ *                                           \_/__/
+ *
+ *      MIDI driver routines for BeOS.
+ *
+ *      By Angelo Mottola.
+ *
+ *      See readme.txt for copyright information.
+ */
+
+#include "bealleg.h"
+#include "allegro/aintern.h"
+#include "allegro/aintbeos.h"
+
+#ifndef ALLEGRO_BEOS
+#error something is wrong with the makefile
+#endif                
+
+
+static char be_midi_driver_desc[256] = EMPTY_STRING;
+static BMidiSynth *be_midisynth = NULL;
+static int cur_patch[17];
+static int cur_note[17];
+static int cur_vol[17];
+
+
+
+/* be_midi_detect:
+ *  BeOS MIDI detection.
+ */
+extern "C" int be_midi_detect(int input)
+{
+   if (input) {
+      usprintf(allegro_error, get_config_text("Input is not supported"));
+      return FALSE;
+   }
+   
+   return TRUE;
+}
+
+
+
+/* be_midi_init:
+ *  Initializes the BeOS MIDI driver.
+ */
+extern "C" int be_midi_init(int input, int voices)
+{
+   char tmp[128], tmp2[128] = EMPTY_STRING;
+   char *sound = uconvert_ascii("sound", tmp);
+   int mode, freq, quality, reverb;
+   synth_mode sm = B_BIG_SYNTH;
+   interpolation_mode im = B_2_POINT_INTERPOLATION;
+   char *reverb_name[] =
+      { "no", "closet", "garage", "ballroom", "cavern", "dungeon" };
+   
+   if (input) {
+      usprintf(allegro_error, get_config_text("Input is not supported"));
+      return -1;
+   }
+         
+   be_midisynth = new BMidiSynth();
+   if (!be_midisynth) {
+      ustrcpy(allegro_error, get_config_text("Not enough memory"));
+      return -1;
+   }
+   
+   /* Checks if instruments are available */
+   mode = MID(0, get_config_int(sound, uconvert_ascii("be_midi_quality", tmp), 1), 1);
+   if (mode)
+      sm = B_BIG_SYNTH;
+   else
+      sm = B_LITTLE_SYNTH;
+   if ((be_synth->LoadSynthData(sm) != B_OK) ||
+       (!be_synth->IsLoaded())) {
+      delete be_midisynth;
+      be_midisynth = NULL;
+      usprintf(allegro_error, get_config_text("Can not load MIDI instruments data file"));
+      return -1;
+   }
+   
+   /* Sets up synthetizer and loads instruments */
+   be_midisynth->EnableInput(true, true);
+   
+   /* Prevents other apps from changing instruments on the fly */
+   be_midisynth->FlushInstrumentCache(true);
+   
+   /* Reverberation is cool */
+   reverb = MID(0, get_config_int(sound, uconvert_ascii("be_midi_reverb", tmp), 3), 5);
+   if (reverb) {
+      be_synth->SetReverb((reverb_mode)reverb);
+      be_synth->EnableReverb(true);
+   }
+   else
+      be_synth->EnableReverb(false);
+         
+   /* Sets sampling rate and sample interpolation method */
+   freq = get_config_int(sound, uconvert_ascii("be_midi_freq", tmp), 22050);
+   quality = MID(0, get_config_int(sound, uconvert_ascii("be_midi_interpolation", tmp), 1), 2);
+   be_synth->SetSamplingRate(freq);
+   switch (quality) {
+      case 0:
+         im = B_DROP_SAMPLE;
+         break;
+      case 1:
+         im = B_2_POINT_INTERPOLATION;
+         usprintf(tmp2, uconvert_ascii("fast", tmp));
+         break;
+      case 2:
+         im = B_LINEAR_INTERPOLATION;
+         usprintf(tmp2, uconvert_ascii("linear", tmp));
+         break;
+   }
+   be_synth->SetInterpolation(im);
+   
+   /* Sets up driver description */
+   usprintf(be_midi_driver_desc, uconvert_ascii("BeOS %s quality synth, %s %d kHz, %s reverberation", tmp),
+            (mode ? "high" : "low"), tmp2, (be_synth->SamplingRate() / 1000), reverb_name[reverb]);
+   midi_beos.desc = be_midi_driver_desc;
+
+   return 0;
+}
+
+
+
+/* be_midi_exit:
+ *  Shuts down MIDI subsystem.
+ */
+extern "C" void be_midi_exit(int input)
+{
+   if (be_midisynth) {
+      be_midisynth->AllNotesOff(false);
+      delete be_midisynth;
+      be_midisynth = NULL;
+   }
+}
+
+
+
+/* be_midi_mixer_volume:
+ *  Sets MIDI mixer output volume.
+ */
+extern "C" int be_midi_mixer_volume(int volume)
+{
+   be_midisynth->SetVolume((double)volume / 255.0);
+   return 0;
+}
+
+
+
+/* be_midi_key_on:
+ *  Triggers a specified voice.
+ */
+extern "C" void be_midi_key_on(int inst, int note, int bend, int vol, int pan)
+{
+   int voice;
+   
+   if (inst > 127) {
+      /* percussion */
+      
+      /* hack to use channel 10 only */
+      midi_beos.xmin = midi_beos.xmax = -1;
+      voice = _midi_allocate_voice(10, 10);
+      midi_beos.xmin = midi_beos.xmax = 10;
+      
+      if (voice < 0)
+         return;
+      cur_note[10] = inst - 128;
+      cur_vol[10] = vol;
+      be_midi_set_pan(voice, pan);
+      be_midisynth->NoteOn(10, inst - 128, vol, B_NOW);
+   }
+   else {
+      /* normal instrument */
+      voice = _midi_allocate_voice(1, 16);
+      if (voice < 0)
+         return;
+      if (inst != cur_patch[voice]) {
+         be_midisynth->ProgramChange(voice, inst);
+         cur_patch[voice] = inst;
+      }
+ 
+      cur_note[voice] = note;
+      cur_vol[voice] = vol;
+      be_midi_set_pitch(voice, note, bend);
+      be_midi_set_pan(voice, pan);
+      be_midisynth->NoteOn(voice, note, vol, B_NOW);
+   }
+}
+
+
+
+/* be_midi_key_off:
+ *  Turns off specified voice.
+ */
+extern "C" void be_midi_key_off(int voice)
+{
+   be_midisynth->NoteOff(voice, cur_note[voice], cur_vol[voice], B_NOW);
+}
+
+
+
+/* be_midi_set_volume:
+ *  Sets volume for a specified voice.
+ */
+extern "C" void be_midi_set_volume(int voice, int vol)
+{
+   /* This seems to work */
+   be_midisynth->ChannelPressure(voice, vol, B_NOW);
+}
+
+
+
+/* be_midi_set_pitch:
+ *  Sets pitch of specified voice.
+ */
+extern "C" void be_midi_set_pitch(int voice, int note, int bend)
+{
+   /* ?? Is this correct? */
+   be_midisynth->PitchBend(voice, bend & 0x7F, bend >> 7, B_NOW);
+}
+
+
+
+/* be_midi_set_pan:
+ *  Sets pan value on specified voice.
+ */
+extern "C" void be_midi_set_pan(int voice, int pan)
+{
+   be_midisynth->ControlChange(voice, B_PAN, pan);
+}
diff -Nru allegro.cvs/src/beos/bmididrv.c allegro/src/beos/bmididrv.c
--- allegro.cvs/src/beos/bmididrv.c	Sat Oct 14 15:50:31 2000
+++ allegro/src/beos/bmididrv.c	Mon Oct 16 16:00:47 2000
@@ -8,7 +8,7 @@
  *                                           /\____/
  *                                           \_/__/
  *
- *      Stuff for BeOS.
+ *      MIDI drivers list for BeOS.
  *
  *      By Jason Wilkins.
  *
@@ -24,4 +24,5 @@
 
 BEGIN_MIDI_DRIVER_LIST
 MIDI_DRIVER_BEOS
+MIDI_DRIVER_DIGMID
 END_MIDI_DRIVER_LIST


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/