aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt36
-rw-r--r--cmake/FindLIBVLC.cmake92
-rw-r--r--include/adlmidi.h4
-rw-r--r--src/adlmidi.cpp31
-rw-r--r--utils/vlc_codec/.gitignore16
-rw-r--r--utils/vlc_codec/Makefile.am13
-rwxr-xr-xutils/vlc_codec/autogen.sh15
-rw-r--r--utils/vlc_codec/configure.ac32
-rw-r--r--utils/vlc_codec/libadlmidi.c363
9 files changed, 575 insertions, 27 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4446231..031152b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,6 +36,7 @@ ENDIF()
option(WITH_MIDIPLAY "Build also demo MIDI player" OFF)
option(MIDIPLAY_WAVE_ONLY "Build Demo MIDI player without support of real time playing. It will output into WAV only." OFF)
option(WITH_ADLMIDI2 "Build also classic ADLMIDI player [EXPERIMENTAL]" OFF)
+option(WITH_VLC_PLUGIN "Build also a plugin for VLC Media Player" OFF)
option(WITH_OLD_UTILS "Build also old utilities" OFF)
option(WITH_EMBEDDED_BANKS "Use embedded banks" ON)
option(WITH_GENADLDATA "Build and run full rebuild of embedded banks cache" OFF)
@@ -46,6 +47,7 @@ option(WITH_CPP_EXTRAS "Build with support for C++ extras (features are can
option(libADLMIDI_STATIC "Build static library of libADLMIDI" ON)
option(libADLMIDI_SHARED "Build shared library of libADLMIDI" OFF)
+
if(CMAKE_VERSION VERSION_EQUAL "3.1" OR CMAKE_VERSION VERSION_GREATER "3.1")
set(CMAKE_CXX_STANDARD 11)
endif()
@@ -292,6 +294,40 @@ if(WITH_ADLMIDI2)
list(APPEND libADLMIDI_INSTALLS adlmidi2)
endif()
+if(WITH_VLC_PLUGIN)
+ include(cmake/FindLIBVLC.cmake)
+ include_directories(${LIBVLC_INCLUDE_DIR}/vlc/plugins)
+ include_directories(${LIBVLC_INCLUDE_DIR}/vlc)
+ message("Found ${LIBVLC_LIBRARY} of version ${LIBVLC_VERSION} with includes ${LIBVLC_INCLUDE_DIR}")
+
+ set(adlmidi_vlc_src)
+ list(APPEND adlmidi_vlc_src
+ ${libADLMIDI_SOURCE_DIR}/utils/vlc_codec/libadlmidi.c)
+
+ add_library(adlmidi_plugin MODULE ${adlmidi_vlc_src})
+ target_compile_options(adlmidi_plugin PUBLIC "-DVLC_MODULE_COPYRIGHT=\"Copyright \(c\) Vitaly Novichkov\"")
+ target_compile_options(adlmidi_plugin PUBLIC "-DVLC_MODULE_LICENSE=\"GPLv3\"")
+ target_compile_options(adlmidi_plugin PUBLIC "-DMODULE_STRING=\"adlmidi\"")
+ #target_link_options()
+ #target_compile_definitions(adlmidi_plugin
+ # PUBLIC -DVLC_MODULE_COPYRIGHT="Copyright \(c\) Vitaly Novichkov" -DVLC_MODULE_LICENSE="GPLv3" -DMODULE_STRING="adlmidi")
+ target_link_libraries(adlmidi_plugin ADLMIDI vlccore m stdc++)
+ target_link_libraries(adlmidi_plugin INTERFACE "-export-symbol-regex ^vlc_entry")
+ #target_compile_definitions(adlmidi_plugin -DVLC_MODULE_LICENSE="GPLv3")
+ #target_compile_definitions(adlmidi_plugin -DMODULE_STRING="adlmidi")
+
+ if(libADLMIDI_SHARED)
+ add_dependencies(adlmidi_plugin ADLMIDI_shared)
+ # ========= WIP =========
+ # set_target_properties(adlmidiplay PROPERTIES COMPILE_FLAGS "-Wl,-rpath='$$ORIGIN/../lib'")
+ else()
+ if(NOT libADLMIDI_STATIC)
+ message(FATAL_ERROR "libADLMIDI is required to be built!")
+ endif()
+ add_dependencies(adlmidi_plugin ADLMIDI_static)
+ endif()
+
+endif()
install(TARGETS ${libADLMIDI_INSTALLS}
RUNTIME DESTINATION "bin"
diff --git a/cmake/FindLIBVLC.cmake b/cmake/FindLIBVLC.cmake
new file mode 100644
index 0000000..abbfb6c
--- /dev/null
+++ b/cmake/FindLIBVLC.cmake
@@ -0,0 +1,92 @@
+
+# CMake module to search for LIBVLC (VLC library)
+# Authors: Rohit Yadav <rohityadav89@gmail.com>
+# Harald Sitter <apachelogger@ubuntu.com>
+#
+# If it's found it sets LIBVLC_FOUND to TRUE
+# and following variables are set:
+# LIBVLC_INCLUDE_DIR
+# LIBVLC_LIBRARY
+# LIBVLC_VERSION
+
+if(NOT LIBVLC_MIN_VERSION)
+ set(LIBVLC_MIN_VERSION "0.0")
+endif(NOT LIBVLC_MIN_VERSION)
+
+# find_path and find_library normally search standard locations
+# before the specified paths. To search non-standard paths first,
+# FIND_* is invoked first with specified paths and NO_DEFAULT_PATH
+# and then again with no specified paths to search the default
+# locations. When an earlier FIND_* succeeds, subsequent FIND_*s
+# searching for the same item do nothing.
+
+if (NOT WIN32)
+ find_package(PkgConfig)
+ pkg_check_modules(PC_LIBVLC libvlc)
+ set(LIBVLC_DEFINITIONS ${PC_LIBVLC_CFLAGS_OTHER})
+endif (NOT WIN32)
+
+#Put here path to custom location
+#example: /home/user/vlc/include etc..
+find_path(LIBVLC_INCLUDE_DIR vlc/vlc.h
+HINTS "$ENV{LIBVLC_INCLUDE_PATH}"
+PATHS
+ "$ENV{LIB_DIR}/include"
+ "$ENV{LIB_DIR}/include/vlc"
+ "/usr/include"
+ "/usr/include/vlc"
+ "/usr/local/include"
+ "/usr/local/include/vlc"
+ #mingw
+ c:/msys/local/include
+)
+find_path(LIBVLC_INCLUDE_DIR PATHS "${CMAKE_INCLUDE_PATH}/vlc" NAMES vlc.h
+ HINTS ${PC_LIBVLC_INCLUDEDIR} ${PC_LIBVLC_INCLUDE_DIRS})
+
+#Put here path to custom location
+#example: /home/user/vlc/lib etc..
+find_library(LIBVLC_LIBRARY NAMES vlc libvlc
+HINTS "$ENV{LIBVLC_LIBRARY_PATH}" ${PC_LIBVLC_LIBDIR} ${PC_LIBVLC_LIBRARY_DIRS}
+PATHS
+ "$ENV{LIB_DIR}/lib"
+ #mingw
+ c:/msys/local/lib
+)
+find_library(LIBVLC_LIBRARY NAMES vlc libvlc)
+find_library(LIBVLCCORE_LIBRARY NAMES vlccore libvlccore
+HINTS "$ENV{LIBVLC_LIBRARY_PATH}" ${PC_LIBVLC_LIBDIR} ${PC_LIBVLC_LIBRARY_DIRS}
+PATHS
+ "$ENV{LIB_DIR}/lib"
+ #mingw
+ c:/msys/local/lib
+)
+find_library(LIBVLCCORE_LIBRARY NAMES vlccore libvlccore)
+
+set(LIBVLC_VERSION ${PC_LIBVLC_VERSION})
+if (NOT LIBVLC_VERSION)
+# TODO: implement means to detect version on windows (vlc --version && regex? ... ultimately we would get it from a header though...)
+endif (NOT LIBVLC_VERSION)
+
+if (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY)
+set(LIBVLC_FOUND TRUE)
+endif (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY)
+
+if (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}")
+ message(WARNING "LibVLC version not found: version searched: ${LIBVLC_MIN_VERSION}, found ${LIBVLC_VERSION}\nUnless you are on Windows this is bound to fail.")
+# TODO: only activate once version detection can be garunteed (which is currently not the case on windows)
+# set(LIBVLC_FOUND FALSE)
+endif (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}")
+
+if (LIBVLC_FOUND)
+ if (NOT LIBVLC_FIND_QUIETLY)
+ message(STATUS "Found LibVLC include-dir path: ${LIBVLC_INCLUDE_DIR}")
+ message(STATUS "Found LibVLC library path:${LIBVLC_LIBRARY}")
+ message(STATUS "Found LibVLCcore library path:${LIBVLCCORE_LIBRARY}")
+ message(STATUS "Found LibVLC version: ${LIBVLC_VERSION} (searched for: ${LIBVLC_MIN_VERSION})")
+ endif (NOT LIBVLC_FIND_QUIETLY)
+else (LIBVLC_FOUND)
+ if (LIBVLC_FIND_REQUIRED)
+ message(FATAL_ERROR "Could not find LibVLC")
+ endif (LIBVLC_FIND_REQUIRED)
+endif (LIBVLC_FOUND)
+
diff --git a/include/adlmidi.h b/include/adlmidi.h
index bc1b2d3..49dcbc0 100644
--- a/include/adlmidi.h
+++ b/include/adlmidi.h
@@ -35,7 +35,7 @@ extern "C" {
typedef uint8_t ADL_UInt8;
typedef uint16_t ADL_UInt16;
typedef int8_t ADL_SInt8;
-typedef int16_t ADL_Sint16;
+typedef int16_t ADL_SInt16;
#else
typedef unsigned char ADL_UInt8;
typedef unsigned short ADL_UInt16;
@@ -239,7 +239,7 @@ extern void adl_rt_controllerChange(struct ADL_MIDIPlayer *device, ADL_UInt8 cha
extern void adl_rt_patchChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 patch);
/*Apply pitch bend change*/
-extern void adl_rt_pitchBend(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 pitch);
+extern void adl_rt_pitchBend(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt16 pitch);
/*Apply pitch bend change*/
extern void adl_rt_pitchBendML(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 msb, ADL_UInt8 lsb);
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp
index dd4a3e1..b9e67cb 100644
--- a/src/adlmidi.cpp
+++ b/src/adlmidi.cpp
@@ -653,34 +653,21 @@ ADLMIDI_EXPORT int adl_generate(struct ADL_MIDIPlayer *device, int sampleCount,
ssize_t n_periodCountStereo = 512;
int left = sampleCount;
- bool hasSkipped = setup.tick_skip_samples_delay > 0;
-
double delay = double(sampleCount) / double(setup.PCM_RATE);
while(left > 0)
{
{//...
const double eat_delay = delay < setup.maxdelay ? delay : setup.maxdelay;
- if(hasSkipped)
- {
- size_t samples = setup.tick_skip_samples_delay > sampleCount ? sampleCount : setup.tick_skip_samples_delay;
- n_periodCountStereo = samples / 2;
- }
- else
- {
- delay -= eat_delay;
- setup.carry += setup.PCM_RATE * eat_delay;
- n_periodCountStereo = static_cast<ssize_t>(setup.carry);
- setup.carry -= n_periodCountStereo;
- }
+ delay -= eat_delay;
+ setup.carry += setup.PCM_RATE * eat_delay;
+ n_periodCountStereo = static_cast<ssize_t>(setup.carry);
+ setup.carry -= n_periodCountStereo;
{
ssize_t leftSamples = left / 2;
if(n_periodCountStereo > leftSamples)
- {
- setup.tick_skip_samples_delay = (n_periodCountStereo - leftSamples) * 2;
n_periodCountStereo = leftSamples;
- }
//! Count of stereo samples
ssize_t in_generatedStereo = (n_periodCountStereo > 512) ? 512 : n_periodCountStereo;
//! Total count of samples
@@ -719,13 +706,7 @@ ADLMIDI_EXPORT int adl_generate(struct ADL_MIDIPlayer *device, int sampleCount,
gotten_len += (in_generatedPhys) /* - setup.stored_samples*/;
}
- if(hasSkipped)
- {
- setup.tick_skip_samples_delay -= n_periodCountStereo * 2;
- hasSkipped = setup.tick_skip_samples_delay > 0;
- }
- else
- player->TickIteratos(eat_delay);
+ player->TickIteratos(eat_delay);
}//...
}
@@ -833,7 +814,7 @@ void adl_rt_patchChange(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UI
player->realTime_PatchChange(channel, patch);
}
-void adl_rt_pitchBend(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt8 pitch)
+void adl_rt_pitchBend(struct ADL_MIDIPlayer *device, ADL_UInt8 channel, ADL_UInt16 pitch)
{
if(!device)
return;
diff --git a/utils/vlc_codec/.gitignore b/utils/vlc_codec/.gitignore
new file mode 100644
index 0000000..75ea9cb
--- /dev/null
+++ b/utils/vlc_codec/.gitignore
@@ -0,0 +1,16 @@
+Makefile
+m4/*
+compile
+config.*
+configure
+missing
+libtool
+ltmain.sh
+depcomp
+install-sh
+autom*.cache
+aclocal.m4
+Makefile.in
+.deps
+.libs
+
diff --git a/utils/vlc_codec/Makefile.am b/utils/vlc_codec/Makefile.am
new file mode 100644
index 0000000..8992451
--- /dev/null
+++ b/utils/vlc_codec/Makefile.am
@@ -0,0 +1,13 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+lib_LTLIBRARIES = libadlmidi_plugin.la
+
+CFLAGS = -DVLC_MODULE_COPYRIGHT="\"Copyright \(c\) Vitaly Novichkov\""
+CFLAGS += -DVLC_MODULE_LICENSE=\"GPLv3\"
+
+libadlmidi_plugin_la_SOURCES = libadlmidi.c
+libadlmidi_plugin_la_CFLAGS = -DMODULE_STRING=\"adlmidi\" $(vlc_CFLAGS)
+libadlmidi_plugin_la_CPPFLAGS = -DMODULE_STRING=\"adlmidi\" $(vlc_CFLAGS)
+libadlmidi_plugin_la_LIBADD = $(vlc_LIBS)
+libadlmidi_plugin_la_LDFLAGS = -avoid-version -module -export-symbol-regex ^vlc_entry -lADLMIDI -lm -lstdc++ $(vlc_LDFLAGS)
+
diff --git a/utils/vlc_codec/autogen.sh b/utils/vlc_codec/autogen.sh
new file mode 100755
index 0000000..57eeb94
--- /dev/null
+++ b/utils/vlc_codec/autogen.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+if [ -x "`which autoreconf 2>/dev/null`" ] ; then
+ exec autoreconf -ivf
+fi
+
+LIBTOOLIZE=libtoolize
+SYSNAME=`uname`
+if [ "x$SYSNAME" = "xDarwin" ] ; then
+ LIBTOOLIZE=glibtoolize
+fi
+aclocal -I m4 && \
+ autoheader && \
+ $LIBTOOLIZE && \
+ autoconf && \
+ automake --add-missing --force-missing --copy
diff --git a/utils/vlc_codec/configure.ac b/utils/vlc_codec/configure.ac
new file mode 100644
index 0000000..3afee7a
--- /dev/null
+++ b/utils/vlc_codec/configure.ac
@@ -0,0 +1,32 @@
+# Process this file with autoconf to produce a configure script.
+AC_PREREQ([2.68])
+AC_INIT([vlc-libadlmidi], [1.0.0], [admin@wohlnet.ru])
+AC_CONFIG_SRCDIR([libadlmidi.c])
+AC_CONFIG_MACRO_DIR([m4])
+AC_USE_SYSTEM_EXTENSIONS
+LT_INIT
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+AC_PROG_CC_C99
+AC_PROG_INSTALL
+AC_PROG_LN_S
+PKG_PROG_PKG_CONFIG
+
+# Initialize automake stuff
+AM_INIT_AUTOMAKE([foreign])
+
+AC_C_INLINE
+AC_FUNC_MALLOC
+AC_FUNC_REALLOC
+AC_FUNC_STRNLEN
+AC_SEARCH_LIBS([sqrt], [m])
+AC_CHECK_FUNCS([memset sqrt strcasecmp strcspn strdup strndup strstr strtol])
+
+PKG_CHECK_MODULES([vlc], [vlc-plugin >= 2.0])
+PKG_CHECK_MODULES([vlc212], [vlc-plugin >= 2.1])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+
diff --git a/utils/vlc_codec/libadlmidi.c b/utils/vlc_codec/libadlmidi.c
new file mode 100644
index 0000000..4a86b64
--- /dev/null
+++ b/utils/vlc_codec/libadlmidi.c
@@ -0,0 +1,363 @@
+/*****************************************************************************
+ * libadlmidi.c: Software MIDI synthesizer using OPL3 Synth emulation
+ *****************************************************************************
+ * Copyright © 2017 Vitaly Novichkov
+ * $Id$
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************/
+
+//#ifdef HAVE_CONFIG_H
+//# include "config.h"
+//#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_codec.h>
+#include <vlc_dialog.h>
+
+#include <unistd.h>
+
+#ifndef N_
+#define N_(x) (x)
+#endif
+
+#ifndef _
+#define _(x) (x)
+#endif
+
+#include <adlmidi.h>
+
+#define SOUNDFONT_TEXT N_("Custom bank file")
+#define SOUNDFONT_LONGTEXT N_( \
+ "Custom bank file to use for software synthesis." )
+
+//#define CHORUS_TEXT N_("Chorus")
+
+//#define GAIN_TEXT N_("Synthesis gain")
+//#define GAIN_LONGTEXT N_("This gain is applied to synthesis output. " \
+// "High values may cause saturation when many notes are played at a time." )
+
+//#define POLYPHONY_TEXT N_("Polyphony")
+//#define POLYPHONY_LONGTEXT N_( \
+// "The polyphony defines how many voices can be played at a time. " \
+// "Larger values require more processing power.")
+
+//#define REVERB_TEXT N_("Reverb")
+
+#define SAMPLE_RATE_TEXT N_("Sample rate")
+
+static int Open (vlc_object_t *);
+static void Close (vlc_object_t *);
+
+vlc_module_begin ()
+ set_description (N_("ADLMIDI OPL3 Synth MIDI synthesizer"))
+ set_capability ("decoder", 150)
+ set_shortname (N_("ADLMIDI"))
+ set_category (CAT_INPUT)
+ set_subcategory (SUBCAT_INPUT_ACODEC)
+ set_callbacks (Open, Close)
+ add_loadfile ("custombank", "",
+ SOUNDFONT_TEXT, SOUNDFONT_LONGTEXT, false)
+ //add_bool ("synth-chorus", true, CHORUS_TEXT, CHORUS_TEXT, false)
+ //add_float ("synth-gain", .5, GAIN_TEXT, GAIN_LONGTEXT, false)
+ // change_float_range (0., 10.)
+ //add_integer ("synth-polyphony", 256, POLYPHONY_TEXT, POLYPHONY_LONGTEXT, false)
+ // change_integer_range (1, 65535)
+ //add_bool ("synth-reverb", true, REVERB_TEXT, REVERB_TEXT, true)
+ add_integer ("synth-sample-rate", 44100, SAMPLE_RATE_TEXT, SAMPLE_RATE_TEXT, true)
+ change_integer_range (22050, 96000)
+vlc_module_end ()
+
+
+struct decoder_sys_t
+{
+ struct ADL_MIDIPlayer *synth;
+ int sample_rate;
+ int soundfont;
+ date_t end_date;
+};
+
+
+//static int DecodeBlock (decoder_t *p_dec, block_t *p_block); //For different version
+static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block);
+static void Flush (decoder_t *);
+
+static int Open (vlc_object_t *p_this)
+{
+ decoder_t *p_dec = (decoder_t *)p_this;
+
+ if (p_dec->fmt_in.i_codec != VLC_CODEC_MIDI)
+ return VLC_EGENERIC;
+
+ decoder_sys_t *p_sys = malloc (sizeof (*p_sys));
+ if (unlikely(p_sys == NULL))
+ return VLC_ENOMEM;
+
+ p_sys->sample_rate = 44100;//var_InheritInteger (p_this, "synth-sample-rate");
+ p_sys->synth = adl_init( p_sys->sample_rate );
+
+ char *font_path = var_InheritString (p_this, "custombank");
+ if (font_path != NULL)
+ {
+ msg_Dbg (p_this, "loading custom bank file %s", font_path);
+ if (adl_openBankFile(p_sys->synth, font_path))
+ msg_Err (p_this, "cannot load custom bank file %s: %s", font_path, adl_errorInfo(p_sys->synth));
+ free (font_path);
+ }
+ else
+ {
+ adl_setBank(p_sys->synth, 58);
+ }
+
+ p_dec->fmt_out.i_cat = AUDIO_ES;
+
+ p_dec->fmt_out.audio.i_rate = p_sys->sample_rate;
+ p_dec->fmt_out.audio.i_channels = 2;
+ p_dec->fmt_out.audio.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
+
+ p_dec->fmt_out.i_codec = VLC_CODEC_S16L;
+ p_dec->fmt_out.audio.i_bitspersample = 16;
+ date_Init (&p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1);
+ date_Set (&p_sys->end_date, 0);
+
+ p_dec->p_sys = p_sys;
+ //==For different version==
+ //p_dec->pf_decode = DecodeBlock;
+ //p_dec->pf_flush = Flush;
+ p_dec->pf_decode_audio = DecodeBlock;
+ return VLC_SUCCESS;//VLCDEC_SUCCESS
+}
+
+
+static void Close (vlc_object_t *p_this)
+{
+ decoder_sys_t *p_sys = ((decoder_t *)p_this)->p_sys;
+
+ adl_close(p_sys->synth);
+ free (p_sys);
+}
+
+static void Flush (decoder_t *p_dec)
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ date_Set (&p_sys->end_date, VLC_TS_INVALID);
+ adl_panic(p_sys->synth);
+}
+
+
+
+static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block)
+{
+ block_t *p_block;
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_out = NULL;
+
+ if (pp_block == NULL)
+ return NULL;
+ p_block = *pp_block;
+ if (p_block == NULL)
+ return NULL;
+ *pp_block = NULL;
+
+ if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
+ {
+ date_Set (&p_sys->end_date, 0);
+ //fluid_synth_system_reset (p_sys->synth);
+ adl_panic(p_sys->synth);
+ adl_rt_resetState(p_sys->synth);
+ }
+
+ if (p_block->i_pts > VLC_TS_INVALID && !date_Get (&p_sys->end_date))
+ date_Set (&p_sys->end_date, p_block->i_pts);
+ else
+ if (p_block->i_pts < date_Get (&p_sys->end_date))
+ {
+ msg_Warn (p_dec, "MIDI message in the past?");
+ goto drop;
+ }
+
+ if (p_block->i_buffer < 1)
+ goto drop;
+
+ uint8_t event = p_block->p_buffer[0];
+ uint8_t channel = p_block->p_buffer[0] & 0xf;
+ event &= 0xF0;
+
+ if (event == 0xF0)
+ switch (channel)
+ {
+ case 0:
+ if (p_block->p_buffer[p_block->i_buffer - 1] != 0xF7)
+ {
+ case 7:
+ msg_Warn (p_dec, "fragmented SysEx not implemented");
+ goto drop;
+ }
+ //fluid_synth_sysex (p_sys->synth, (char *)p_block->p_buffer + 1,
+ // p_block->i_buffer - 2, NULL, NULL, NULL, 0);
+ break;
+ case 0xF:
+ adl_rt_resetState(p_sys->synth);
+ break;
+ }
+
+ uint8_t p1 = (p_block->i_buffer > 1) ? (p_block->p_buffer[1] & 0x7f) : 0;
+ uint8_t p2 = (p_block->i_buffer > 2) ? (p_block->p_buffer[2] & 0x7f) : 0;
+
+ switch (event & 0xF0)
+ {
+ case 0x80:
+ adl_rt_noteOff(p_sys->synth, channel, p1);
+ break;
+ case 0x90:
+ adl_rt_noteOn(p_sys->synth, channel, p1, p2);
+ break;
+ /*case 0xA0: note aftertouch not implemented */
+ case 0xB0:
+ adl_rt_controllerChange(p_sys->synth, channel, p1, p2);
+ break;
+ case 0xC0:
+ adl_rt_patchChange(p_sys->synth, channel, p1);
+ break;
+ case 0xD0:
+ adl_rt_channelAfterTouch(p_sys->synth, channel, p1);
+ break;
+ case 0xE0:
+ adl_rt_pitchBend(p_sys->synth, channel, (p2 << 7) | p1);
+ break;
+ }
+
+ unsigned samples =
+ (p_block->i_pts - date_Get (&p_sys->end_date)) * 441 / 10000;
+ if (samples == 0)
+ goto drop;
+
+ p_out = decoder_NewAudioBuffer (p_dec, samples);
+ if (p_out == NULL)
+ goto drop;
+
+ p_out->i_pts = date_Get (&p_sys->end_date );
+ samples = adl_generate(p_sys->synth, samples * 2, (short*)p_out->p_buffer);
+ samples /= 2;
+ p_out->i_length = date_Increment (&p_sys->end_date, samples) - p_out->i_pts;
+
+drop:
+ block_Release (p_block);
+ return p_out;
+}
+
+#if 0
+static int DecodeBlock (decoder_t *p_dec, block_t *p_block)
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_out = NULL;
+
+ if (p_block == NULL) /* No Drain */
+ return VLC_SUCCESS;//VLCDEC_SUCCESS
+
+ if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
+ {
+ Flush (p_dec);
+ if (p_block->i_flags & BLOCK_FLAG_CORRUPTED)
+ {
+ block_Release(p_block);
+ return VLC_SUCCESS;//VLCDEC_SUCCESS
+ }
+ }
+
+ if (p_block->i_pts > VLC_TS_INVALID && !date_Get (&p_sys->end_date))
+ date_Set (&p_sys->end_date, p_block->i_pts);
+ else
+ if (p_block->i_pts < date_Get (&p_sys->end_date))
+ {
+ msg_Warn (p_dec, "MIDI message in the past?");
+ goto drop;
+ }
+
+ if (p_block->i_buffer < 1)
+ goto drop;
+
+ uint8_t event = p_block->p_buffer[0];
+ uint8_t channel = p_block->p_buffer[0] & 0xf;
+ event &= 0xF0;
+
+ if (event == 0xF0)
+ switch (channel)
+ {
+ case 0:
+ if (p_block->p_buffer[p_block->i_buffer - 1] != 0xF7)
+ {
+ case 7:
+ msg_Warn (p_dec, "fragmented SysEx not implemented");
+ goto drop;
+ }
+ //fluid_synth_sysex (p_sys->synth, (char *)p_block->p_buffer + 1,
+ // p_block->i_buffer - 2, NULL, NULL, NULL, 0);
+ break;
+ case 0xF:
+ adl_rt_resetState(p_sys->synth);
+ break;
+ }
+
+ uint8_t p1 = (p_block->i_buffer > 1) ? (p_block->p_buffer[1] & 0x7f) : 0;
+ uint8_t p2 = (p_block->i_buffer > 2) ? (p_block->p_buffer[2] & 0x7f) : 0;
+
+ switch (event & 0xF0)
+ {
+ case 0x80:
+ adl_rt_noteOff(p_sys->synth, channel, p1);
+ break;
+ case 0x90:
+ adl_rt_noteOn(p_sys->synth, channel, p1, p2);
+ break;
+ /*case 0xA0: note aftertouch not implemented */
+ case 0xB0:
+ adl_rt_controllerChange(p_sys->synth, channel, p1, p2);
+ break;
+ case 0xC0:
+ adl_rt_patchChange(p_sys->synth, channel, p1);
+ break;
+ case 0xD0:
+ adl_rt_channelAfterTouch(p_sys->synth, channel, p1);
+ break;
+ case 0xE0:
+ adl_rt_pitchBendML(p_sys->synth, channel, p2, p1);
+ break;
+ }
+
+ unsigned samples =
+ (p_block->i_pts - date_Get (&p_sys->end_date)) * 441 / 10000;
+ if (samples == 0)
+ goto drop;
+
+ if (decoder_UpdateAudioFormat (p_dec))
+ goto drop;
+ p_out = decoder_NewAudioBuffer (p_dec, samples);
+ if (p_out == NULL)
+ goto drop;
+
+ p_out->i_pts = date_Get (&p_sys->end_date );
+ p_out->i_length = date_Increment (&p_sys->end_date, samples)
+ - p_out->i_pts;
+ adl_generate(p_sys->synth, samples * 2, p_out->p_buffer);
+drop:
+ block_Release (p_block);
+ if (p_out != NULL)
+ decoder_QueueAudio (p_dec, p_out);
+ return VLC_SUCCESS;//VLCDEC_SUCCESS
+}
+
+#endif