summaryrefslogtreecommitdiffstats
path: root/arm-wt-22k
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-04 03:30:38 (GMT)
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-04 03:30:38 (GMT)
commit7df30109963092559d3760c0661a020f9daf1030 (patch)
tree5780537d7996618fb7e1754bbd27361f3ccb9286 /arm-wt-22k
parent1b52a76815aa068a3477bfdfaf58718d41d7f9b4 (diff)
downloadandroid_external_sonivox-7df30109963092559d3760c0661a020f9daf1030.zip
android_external_sonivox-7df30109963092559d3760c0661a020f9daf1030.tar.gz
android_external_sonivox-7df30109963092559d3760c0661a020f9daf1030.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'arm-wt-22k')
-rw-r--r--arm-wt-22k/Android.mk104
-rw-r--r--arm-wt-22k/bin/arm-wt-22kbin0 -> 610752 bytes
-rw-r--r--arm-wt-22k/host_src/arm-wt-22k.mak25
-rw-r--r--arm-wt-22k/host_src/eas.h1062
-rw-r--r--arm-wt-22k/host_src/eas_build.h36
-rw-r--r--arm-wt-22k/host_src/eas_chorus.h53
-rw-r--r--arm-wt-22k/host_src/eas_config.c619
-rw-r--r--arm-wt-22k/host_src/eas_config.h191
-rw-r--r--arm-wt-22k/host_src/eas_debugmsgs.h87
-rw-r--r--arm-wt-22k/host_src/eas_host.h87
-rw-r--r--arm-wt-22k/host_src/eas_hostmm.c687
-rw-r--r--arm-wt-22k/host_src/eas_main.c464
-rw-r--r--arm-wt-22k/host_src/eas_report.c264
-rw-r--r--arm-wt-22k/host_src/eas_report.h77
-rw-r--r--arm-wt-22k/host_src/eas_reverb.h54
-rw-r--r--arm-wt-22k/host_src/eas_types.h273
-rw-r--r--arm-wt-22k/host_src/eas_wave.c423
-rw-r--r--arm-wt-22k/host_src/eas_wave.h74
-rw-r--r--arm-wt-22k/host_src/jet.h199
-rw-r--r--arm-wt-22k/lib/libarm-wt-22k.abin0 -> 322180 bytes
-rw-r--r--arm-wt-22k/lib_src/ARM-E_filter_gnu.s134
-rw-r--r--arm-wt-22k/lib_src/ARM-E_interpolate_loop_gnu.s131
-rw-r--r--arm-wt-22k/lib_src/ARM-E_interpolate_noloop_gnu.s130
-rw-r--r--arm-wt-22k/lib_src/ARM-E_mastergain_gnu.s109
-rw-r--r--arm-wt-22k/lib_src/ARM-E_voice_gain_gnu.s166
-rw-r--r--arm-wt-22k/lib_src/ARM_synth_constants_gnu.inc153
-rw-r--r--arm-wt-22k/lib_src/arm-wt-22k_lib.mak25
-rw-r--r--arm-wt-22k/lib_src/dls.h268
-rw-r--r--arm-wt-22k/lib_src/dls2.h122
-rw-r--r--arm-wt-22k/lib_src/eas_audioconst.h97
-rw-r--r--arm-wt-22k/lib_src/eas_chorus.c604
-rw-r--r--arm-wt-22k/lib_src/eas_chorusdata.c34
-rw-r--r--arm-wt-22k/lib_src/eas_chorusdata.h160
-rw-r--r--arm-wt-22k/lib_src/eas_ctype.h41
-rw-r--r--arm-wt-22k/lib_src/eas_data.c37
-rw-r--r--arm-wt-22k/lib_src/eas_data.h133
-rw-r--r--arm-wt-22k/lib_src/eas_dlssynth.c578
-rw-r--r--arm-wt-22k/lib_src/eas_dlssynth.h41
-rw-r--r--arm-wt-22k/lib_src/eas_effects.h61
-rw-r--r--arm-wt-22k/lib_src/eas_flog.c96
-rw-r--r--arm-wt-22k/lib_src/eas_ima_tables.c54
-rw-r--r--arm-wt-22k/lib_src/eas_imaadpcm.c368
-rw-r--r--arm-wt-22k/lib_src/eas_imelody.c1742
-rw-r--r--arm-wt-22k/lib_src/eas_imelodydata.c43
-rw-r--r--arm-wt-22k/lib_src/eas_imelodydata.h73
-rw-r--r--arm-wt-22k/lib_src/eas_math.c168
-rw-r--r--arm-wt-22k/lib_src/eas_math.h412
-rw-r--r--arm-wt-22k/lib_src/eas_mdls.c2668
-rw-r--r--arm-wt-22k/lib_src/eas_mdls.h295
-rw-r--r--arm-wt-22k/lib_src/eas_midi.c569
-rw-r--r--arm-wt-22k/lib_src/eas_midi.h71
-rw-r--r--arm-wt-22k/lib_src/eas_midictrl.h64
-rw-r--r--arm-wt-22k/lib_src/eas_mididata.c34
-rw-r--r--arm-wt-22k/lib_src/eas_miditypes.h138
-rw-r--r--arm-wt-22k/lib_src/eas_mixbuf.c36
-rw-r--r--arm-wt-22k/lib_src/eas_mixer.c464
-rw-r--r--arm-wt-22k/lib_src/eas_mixer.h137
-rw-r--r--arm-wt-22k/lib_src/eas_ota.c1077
-rw-r--r--arm-wt-22k/lib_src/eas_otadata.c41
-rw-r--r--arm-wt-22k/lib_src/eas_otadata.h81
-rw-r--r--arm-wt-22k/lib_src/eas_pan.c98
-rw-r--r--arm-wt-22k/lib_src/eas_pan.h66
-rw-r--r--arm-wt-22k/lib_src/eas_parser.h98
-rw-r--r--arm-wt-22k/lib_src/eas_pcm.c1482
-rw-r--r--arm-wt-22k/lib_src/eas_pcm.h359
-rw-r--r--arm-wt-22k/lib_src/eas_pcmdata.c35
-rw-r--r--arm-wt-22k/lib_src/eas_pcmdata.h157
-rw-r--r--arm-wt-22k/lib_src/eas_public.c2601
-rw-r--r--arm-wt-22k/lib_src/eas_reverb.c1154
-rw-r--r--arm-wt-22k/lib_src/eas_reverbdata.c34
-rw-r--r--arm-wt-22k/lib_src/eas_reverbdata.h486
-rw-r--r--arm-wt-22k/lib_src/eas_rtttl.c1197
-rw-r--r--arm-wt-22k/lib_src/eas_rtttldata.c41
-rw-r--r--arm-wt-22k/lib_src/eas_rtttldata.h70
-rw-r--r--arm-wt-22k/lib_src/eas_smf.c1207
-rw-r--r--arm-wt-22k/lib_src/eas_smf.h49
-rw-r--r--arm-wt-22k/lib_src/eas_smfdata.c66
-rw-r--r--arm-wt-22k/lib_src/eas_smfdata.h66
-rw-r--r--arm-wt-22k/lib_src/eas_sndlib.h406
-rw-r--r--arm-wt-22k/lib_src/eas_synth.h395
-rw-r--r--arm-wt-22k/lib_src/eas_synth_protos.h60
-rw-r--r--arm-wt-22k/lib_src/eas_synthcfg.h70
-rw-r--r--arm-wt-22k/lib_src/eas_tcdata.c43
-rw-r--r--arm-wt-22k/lib_src/eas_tcdata.h65
-rw-r--r--arm-wt-22k/lib_src/eas_tonecontrol.c941
-rw-r--r--arm-wt-22k/lib_src/eas_vm_protos.h1086
-rw-r--r--arm-wt-22k/lib_src/eas_voicemgt.c3971
-rw-r--r--arm-wt-22k/lib_src/eas_wavefile.c867
-rw-r--r--arm-wt-22k/lib_src/eas_wavefile.h63
-rw-r--r--arm-wt-22k/lib_src/eas_wavefiledata.c33
-rw-r--r--arm-wt-22k/lib_src/eas_wt_IPC_frame.h82
-rw-r--r--arm-wt-22k/lib_src/eas_wtengine.c661
-rw-r--r--arm-wt-22k/lib_src/eas_wtengine.h171
-rw-r--r--arm-wt-22k/lib_src/eas_wtsynth.c1257
-rw-r--r--arm-wt-22k/lib_src/eas_wtsynth.h66
-rw-r--r--arm-wt-22k/lib_src/eas_xmf.c850
-rw-r--r--arm-wt-22k/lib_src/eas_xmf.h60
-rw-r--r--arm-wt-22k/lib_src/eas_xmfdata.c44
-rw-r--r--arm-wt-22k/lib_src/eas_xmfdata.h55
-rw-r--r--arm-wt-22k/lib_src/jet.c1125
-rw-r--r--arm-wt-22k/lib_src/jet_data.h183
-rw-r--r--arm-wt-22k/lib_src/wt_22khz.c11423
-rw-r--r--arm-wt-22k/misc/MMAPI.zipbin0 -> 1050817 bytes
-rw-r--r--arm-wt-22k/misc/eas_host.c787
-rw-r--r--arm-wt-22k/vectors/Leadsol.mxmfbin0 -> 565820 bytes
-rw-r--r--arm-wt-22k/vectors/Leadsol_out.wavbin0 -> 2678828 bytes
-rw-r--r--arm-wt-22k/vectors/WAVEtest.wavbin0 -> 286838 bytes
-rw-r--r--arm-wt-22k/vectors/WAVEtest_out.wavbin0 -> 147500 bytes
-rw-r--r--arm-wt-22k/vectors/abba.imy10
-rw-r--r--arm-wt-22k/vectors/abba_out.wavbin0 -> 2457644 bytes
-rw-r--r--arm-wt-22k/vectors/ants.midbin0 -> 2956 bytes
-rw-r--r--arm-wt-22k/vectors/ants_out.wavbin0 -> 1728556 bytes
-rw-r--r--arm-wt-22k/vectors/greensleeves.rtttl1
-rw-r--r--arm-wt-22k/vectors/greensleeves_out.wavbin0 -> 1712172 bytes
-rw-r--r--arm-wt-22k/vectors/test.otabin0 -> 30 bytes
-rw-r--r--arm-wt-22k/vectors/test_out.wavbin0 -> 528428 bytes
116 files changed, 50475 insertions, 0 deletions
diff --git a/arm-wt-22k/Android.mk b/arm-wt-22k/Android.mk
new file mode 100644
index 0000000..71fbcf8
--- /dev/null
+++ b/arm-wt-22k/Android.mk
@@ -0,0 +1,104 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES = \
+ lib_src/eas_chorus.c \
+ lib_src/eas_chorusdata.c \
+ lib_src/eas_data.c \
+ lib_src/eas_dlssynth.c \
+ lib_src/eas_flog.c \
+ lib_src/eas_ima_tables.c \
+ lib_src/eas_imaadpcm.c \
+ lib_src/eas_imelody.c \
+ lib_src/eas_imelodydata.c \
+ lib_src/eas_math.c \
+ lib_src/eas_mdls.c \
+ lib_src/eas_midi.c \
+ lib_src/eas_mididata.c \
+ lib_src/eas_mixbuf.c \
+ lib_src/eas_mixer.c \
+ lib_src/eas_ota.c \
+ lib_src/eas_otadata.c \
+ lib_src/eas_pan.c \
+ lib_src/eas_pcm.c \
+ lib_src/eas_pcmdata.c \
+ lib_src/eas_public.c \
+ lib_src/eas_reverb.c \
+ lib_src/eas_reverbdata.c \
+ lib_src/eas_rtttl.c \
+ lib_src/eas_rtttldata.c \
+ lib_src/eas_smf.c \
+ lib_src/eas_smfdata.c \
+ lib_src/eas_voicemgt.c \
+ lib_src/eas_wtengine.c \
+ lib_src/eas_wtsynth.c \
+ lib_src/eas_xmf.c \
+ lib_src/eas_xmfdata.c \
+ lib_src/wt_22khz.c \
+ lib_src/jet.c \
+ host_src/eas_config.c \
+ host_src/eas_hostmm.c \
+ host_src/eas_main.c \
+ host_src/eas_report.c \
+ host_src/eas_wave.c
+
+# not using these modules
+# lib_src/eas_wavefile.c \
+# lib_src/eas_wavefiledata.c \
+
+LOCAL_CFLAGS+= -O2 -D UNIFIED_DEBUG_MESSAGES -D EAS_WT_SYNTH \
+ -D _IMELODY_PARSER -D _RTTTL_PARSER -D _OTA_PARSER \
+ -D _XMF_PARSER -D NUM_OUTPUT_CHANNELS=2 \
+ -D _SAMPLE_RATE_22050 -D MAX_SYNTH_VOICES=64 \
+ -D _8_BIT_SAMPLES -D _FILTER_ENABLED \
+ -D DLS_SYNTHESIZER \
+ -D _REVERB_ENABLED
+
+# not using these options
+# -D _WAVE_PARSER
+# -D _IMA_DECODER (needed for IMA-ADPCM wave files)
+# -D _CHORUS_ENABLED
+
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/host_src \
+ $(LOCAL_PATH)/lib_src
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_MODULE := libsonivox
+
+LOCAL_COPY_HEADERS_TO := libsonivox
+LOCAL_COPY_HEADERS := \
+ host_src/eas.h \
+ host_src/eas_types.h \
+ host_src/eas_reverb.h \
+ host_src/jet.h
+
+ifeq ($(TARGET_ARCH),arm)
+LOCAL_SRC_FILES+= \
+ lib_src/ARM-E_filter_gnu.s \
+ lib_src/ARM-E_interpolate_loop_gnu.s \
+ lib_src/ARM-E_interpolate_noloop_gnu.s \
+ lib_src/ARM-E_mastergain_gnu.s \
+ lib_src/ARM-E_voice_gain_gnu.s
+
+asm_flags := \
+ -I $(LOCAL_PATH)/lib_src \
+ --defsym SAMPLE_RATE_22050=1 \
+ --defsym STEREO_OUTPUT=1 \
+ --defsym FILTER_ENABLED=1 \
+ --defsym SAMPLES_8_BIT=1
+
+LOCAL_CFLAGS+= -D NATIVE_EAS_KERNEL \
+ $(foreach f,$(asm_flags),-Wa,"$(f)")
+
+LOCAL_COPY_HEADERS += lib_src/ARM_synth_constants_gnu.inc
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils libcutils
+
+LOCAL_LDLIBS := -lpthread
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/arm-wt-22k/bin/arm-wt-22k b/arm-wt-22k/bin/arm-wt-22k
new file mode 100644
index 0000000..2e54640
--- /dev/null
+++ b/arm-wt-22k/bin/arm-wt-22k
Binary files differ
diff --git a/arm-wt-22k/host_src/arm-wt-22k.mak b/arm-wt-22k/host_src/arm-wt-22k.mak
new file mode 100644
index 0000000..222d174
--- /dev/null
+++ b/arm-wt-22k/host_src/arm-wt-22k.mak
@@ -0,0 +1,25 @@
+#
+# Auto-generated sample makefile
+#
+# This makefile is intended for use with GNU make.
+# Set the paths to the tools (CC, AR, LD, etc.)
+#
+
+vpath %.c host_src
+
+CC = C:\Program Files\GNUARM\bin\arm-elf-gcc.exe
+AS = C:\Program Files\GNUARM\bin\arm-elf-as.exe
+LD = C:\Program Files\GNUARM\bin\arm-elf-gcc.exe
+AR = C:\Program Files\GNUARM\bin\arm-elf-ar.exe
+
+%.o: %.c
+ $(CC) -c -O2 -o $@ -I host_src -D UNIFIED_DEBUG_MESSAGES -D EAS_WT_SYNTH -D _IMELODY_PARSER -D _RTTTL_PARSER -D _OTA_PARSER -D _XMF_PARSER -D _WAVE_PARSER -D _REVERB_ENABLED -D _CHORUS_ENABLED -D MMAPI_SUPPORT -D JET_INTERFACE $<
+
+%.o: %.s
+ $(AS) -o $@ -EL -mcpu=arm946e-s -mfpu=softfpa -I lib_src --defsym CHECK_STACK=0 --defsym REVERB=0 --defsym CHORUS=0 --defsym STEREO_OUTPUT=1 --defsym SAMPLE_RATE_22050=1 --defsym SAMPLES_8_BIT=1 --defsym FILTER_ENABLED=1 $<
+
+OBJS = eas_main.o eas_report.o eas_wave.o eas_hostmm.o eas_config.o
+
+arm-wt-22k: $(OBJS)
+ $(LD) -o $@ $(OBJS) libarm-wt-22k.a -lm
+
diff --git a/arm-wt-22k/host_src/eas.h b/arm-wt-22k/host_src/eas.h
new file mode 100644
index 0000000..524601e
--- /dev/null
+++ b/arm-wt-22k/host_src/eas.h
@@ -0,0 +1,1062 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas.h
+ *
+ * Contents and purpose:
+ * The public interface header for the EAS synthesizer.
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2005, 2006
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 852 $
+ * $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_H
+#define _EAS_H
+
+#include "eas_types.h"
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* library version macro */
+#define MAKE_LIB_VERSION(a,b,c,d) (((((((EAS_U32) a <<8) | (EAS_U32) b) << 8) | (EAS_U32) c) << 8) | (EAS_U32) d)
+#define LIB_VERSION MAKE_LIB_VERSION(3, 6, 10, 14)
+
+typedef struct
+{
+ EAS_U32 libVersion;
+ EAS_BOOL checkedVersion;
+ EAS_I32 maxVoices;
+ EAS_I32 numChannels;
+ EAS_I32 sampleRate;
+ EAS_I32 mixBufferSize;
+ EAS_BOOL filterEnabled;
+ EAS_U32 buildTimeStamp;
+ EAS_CHAR *buildGUID;
+} S_EAS_LIB_CONFIG;
+
+/* enumerated effects module numbers for configuration */
+typedef enum
+{
+ EAS_MODULE_ENHANCER = 0,
+ EAS_MODULE_COMPRESSOR,
+ EAS_MODULE_REVERB,
+ EAS_MODULE_CHORUS,
+ EAS_MODULE_WIDENER,
+ EAS_MODULE_GRAPHIC_EQ,
+ EAS_MODULE_WOW,
+ EAS_MODULE_MAXIMIZER,
+ EAS_MODULE_TONECONTROLEQ,
+ NUM_EFFECTS_MODULES
+} E_FX_MODULES;
+
+/* enumerated optional module numbers for configuration */
+typedef enum
+{
+ EAS_MODULE_MMAPI_TONE_CONTROL = 0,
+ EAS_MODULE_METRICS
+} E_OPT_MODULES;
+#define NUM_OPTIONAL_MODULES 2
+
+/* enumerated audio decoders for configuration */
+typedef enum
+{
+ EAS_DECODER_PCM = 0,
+ EAS_DECODER_SMAF_ADPCM,
+ EAS_DECODER_IMA_ADPCM,
+ EAS_DECODER_7BIT_SMAF_ADPCM,
+ EAS_DECODER_NOT_SUPPORTED
+} E_DECODER_MODULES;
+#define NUM_DECODER_MODULES 4
+
+/* defines for EAS_PEOpenStream flags parameter */
+#define PCM_FLAGS_STEREO 0x00000100 /* stream is stereo */
+#define PCM_FLAGS_8_BIT 0x00000001 /* 8-bit format */
+#define PCM_FLAGS_UNSIGNED 0x00000010 /* unsigned format */
+#define PCM_FLAGS_STREAMING 0x80000000 /* streaming mode */
+
+/* maximum volume setting */
+#define EAS_MAX_VOLUME 100
+
+/*----------------------------------------------------------------------------
+ * EAS_Init()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize the synthesizer library
+ *
+ * Inputs:
+ * polyphony - number of voices to play (dynamic memory model only)
+ * ppLibData - pointer to data handle variable for this instance
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Init (EAS_DATA_HANDLE *ppEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_Config()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns a pointer to a structure containing the configuration options
+ * in this library build.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC const S_EAS_LIB_CONFIG *EAS_Config (void);
+
+/*----------------------------------------------------------------------------
+ * EAS_Shutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the library. Deallocates any memory associated with the
+ * synthesizer (dynamic memory model only)
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Shutdown (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_Render()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the Midi data and render PCM audio data.
+ *
+ * Inputs:
+ * pEASData - buffer for internal EAS data
+ * pOut - output buffer pointer
+ * nNumRequested - requested num samples to generate
+ * pnNumGenerated - actual number of samples generated
+ *
+ * Outputs:
+ * EAS_SUCCESS if PCM data was successfully rendered
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Render (EAS_DATA_HANDLE pEASData, EAS_PCM *pOut, EAS_I32 numRequested, EAS_I32 *pNumGenerated);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetRepeat()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the selected stream to repeat.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * repeatCount - repeat count (0 = no repeat, -1 = repeat forever)
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
+ * -1 = repeat forever
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 repeatCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetRepeat()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the current repeat count for the selected stream.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * pRrepeatCount - pointer to variable to hold repeat count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * 0 = no repeat
+ * 1 = repeat once, i.e. play through twice
+ * -1 = repeat forever
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetRepeat (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pRepeatCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPlaybackRate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the playback rate.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * rate - rate (28-bit fractional amount)
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPlaybackRate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U32 rate);
+#define MAX_PLAYBACK_RATE (EAS_U32)(1L << 29)
+#define MIN_PLAYBACK_RATE (EAS_U32)(1L << 27)
+
+/*----------------------------------------------------------------------------
+ * EAS_SetTransposition)
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the key tranposition for the synthesizer. Transposes all
+ * melodic instruments by the specified amount. Range is limited
+ * to +/-12 semitones.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * streamHandle - handle to stream
+ * transposition - +/-12 semitones
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetTransposition (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 transposition);
+#define MAX_TRANSPOSE 12
+
+/*----------------------------------------------------------------------------
+ * EAS_SetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the polyphony of the synthesizer. Value must be >= 1 and <= the
+ * maximum number of voices. This function will pin the polyphony
+ * at those limits
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetSynthPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting of the synthesizer
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * synthNum - synthesizer number (0 = onboard, 1 = DSP)
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetSynthPolyphony (EAS_DATA_HANDLE pEASData, EAS_I32 synthNum, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the polyphony of the stream. Value must be >= 1 and <= the
+ * maximum number of voices. This function will pin the polyphony
+ * at those limits
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 polyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetPolyphony()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current polyphony setting of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPolyphonyCount - pointer to variable to receive polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetPolyphony (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPolyphonyCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the priority of the stream. Determines which stream's voices
+ * are stolen when there are insufficient voices for all notes.
+ * Value must be in the range of 1-255, lower values are higher
+ * priority. The default priority is 50.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * polyphonyCount - the desired polyphony count
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 priority);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetPriority()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current priority setting of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * pPriority - pointer to variable to receive priority
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetPriority (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPriority);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the master volume for the mixer. The default volume setting is
+ * 90 (-10 dB). The volume range is 0 to 100 in 1dB increments.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 volume);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the master volume for the mixer in 1dB increments.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * volume - the desired master volume
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * overrides any previously set master volume from sysex
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_I32 EAS_GetVolume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetMaxLoad()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the maximum workload the parsers will do in a single call to
+ * EAS_Render. The units are currently arbitrary, but should correlate
+ * well to the actual CPU cycles consumed. The primary effect is to
+ * reduce the occasional peaks in CPU cycles consumed when parsing
+ * dense parts of a MIDI score. Setting maxWorkLoad to zero disables
+ * the workload limiting function.
+ *
+ * Inputs:
+ * pEASData - handle to data for this instance
+ * maxLoad - the desired maximum workload
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetMaxLoad (EAS_DATA_HANDLE pEASData, EAS_I32 maxLoad);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetMaxPCMStreams()
+ *----------------------------------------------------------------------------
+ * Sets the maximum number of PCM streams allowed in parsers that
+ * use PCM streaming.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - handle returned by EAS_OpenFile
+ * maxNumStreams - maximum number of PCM streams
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetMaxPCMStreams (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 maxNumStreams);
+
+/*----------------------------------------------------------------------------
+ * EAS_OpenFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a file for audio playback.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * locator - pointer to filename or other locating information
+ * pStreamHandle - pointer to stream handle variable
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_OpenFile (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle);
+
+#ifdef MMAPI_SUPPORT
+/*----------------------------------------------------------------------------
+ * EAS_MMAPIToneControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a ToneControl file for audio playback.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * locator - pointer to filename or other locating information
+ * pStreamHandle - pointer to stream handle variable
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MMAPIToneControl (EAS_DATA_HANDLE pEASData, EAS_FILE_LOCATOR locator, EAS_HANDLE *pStreamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetWaveFmtChunk
+ *----------------------------------------------------------------------------
+ * Helper function to retrieve WAVE file fmt chunk for MMAPI
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * streamHandle - stream handle
+ * pFmtChunk - pointer to pointer to FMT chunk data
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetWaveFmtChunk (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_VOID_PTR *ppFmtChunk);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_GetFileType
+ *----------------------------------------------------------------------------
+ * Returns the file type (see eas_types.h for enumerations)
+ *----------------------------------------------------------------------------
+ * pEASData - pointer to EAS persistent data object
+ * streamHandle - stream handle
+ * pFileType - pointer to variable to receive file type
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetFileType (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pFileType);
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * playLength - pointer to variable to store the play length (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - resets the parser to the start of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_ParseMetaData (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pPlayLength);
+
+/*----------------------------------------------------------------------------
+ * EAS_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the synthesizer to play the file or stream. Parses the first
+ * frame of data from the file and arms the synthesizer.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Prepare (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the state of an audio file or stream.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_State (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_STATE *pState);
+
+/*----------------------------------------------------------------------------
+ * EAS_RegisterMetaDataCallback()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Registers a metadata callback function for parsed metadata. To
+ * de-register the callback, call this function again with parameter
+ * cbFunc set to NULL.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * cbFunc - pointer to host callback function
+ * metaDataBuffer - pointer to metadata buffer
+ * metaDataBufSize - maximum size of the metadata buffer
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_RegisterMetaDataCallback (
+ EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE streamHandle,
+ EAS_METADATA_CBFUNC cbFunc,
+ char *metaDataBuffer,
+ EAS_I32 metaDataBufSize,
+ EAS_VOID_PTR pUserData);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetNoteCount ()
+ *----------------------------------------------------------------------------
+ * Returns the total number of notes played in this stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * pNoteCount - pointer to variable to receive note count
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetNoteCount (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 *pNoteCount);
+
+/*----------------------------------------------------------------------------
+ * EAS_CloseFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Closes an audio file or stream. Playback should have either paused or
+ * completed (EAS_State returns EAS_PAUSED or EAS_STOPPED).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_CloseFile (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_OpenMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Opens a raw MIDI stream allowing the host to route MIDI cable data directly to the synthesizer
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pStreamHandle - pointer to variable to hold file or stream handle
+ * streamHandle - open stream or NULL for new synthesizer instance
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_OpenMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE *pStreamHandle, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_WriteMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Send data to the MIDI stream device
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - stream handle
+ * pBuffer - pointer to buffer
+ * count - number of bytes to write
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_WriteMIDIStream(EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 *pBuffer, EAS_I32 count);
+
+/*----------------------------------------------------------------------------
+ * EAS_CloseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Closes a raw MIDI stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_CloseMIDIStream (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_Locate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locate into the file associated with the handle.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file handle
+ * milliseconds - playback offset from start of file in milliseconds
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * the actual offset will be quantized to the closest update period, typically
+ * a resolution of 5.9ms. Notes that are started prior to this time will not
+ * sound. Any notes currently playing will be shut off.
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Locate (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 milliseconds, EAS_BOOL offset);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetRenderTime()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current playback offset
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * Gets the render time clock in msecs.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetRenderTime (EAS_DATA_HANDLE pEASData, EAS_I32 *pTime);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetLocation()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current playback offset
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file handle
+ *
+ * Outputs:
+ * The offset in milliseconds from the start of the current sequence, quantized
+ * to the nearest update period. Actual resolution is typically 5.9 ms.
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetLocation (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_I32 *pTime);
+
+/*----------------------------------------------------------------------------
+ * EAS_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the playback of the data associated with this handle. The audio
+ * is gracefully ramped down to prevent clicks and pops. It may take several
+ * buffers of audio before the audio is muted.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Pause (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resumes the playback of the data associated with this handle. The audio
+ * is gracefully ramped up to prevent clicks and pops.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_Resume (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the parameter of a module. See E_MODULES for a list of modules
+ * and the header files of the modules for a list of parameters.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * pValue - pointer to variable to receive parameter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 *pValue);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set the parameter of a module. See E_MODULES for a list of modules
+ * and the header files of the modules for a list of parameters.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ * handle - file or stream handle
+ * module - enumerated module number
+ * param - enumerated parameter number
+ * value - new parameter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetParameter (EAS_DATA_HANDLE pEASData, EAS_I32 module, EAS_I32 param, EAS_I32 value);
+
+#ifdef _METRICS_ENABLED
+/*----------------------------------------------------------------------------
+ * EAS_MetricsReport()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the current metrics through the EAS_Report interface.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MetricsReport (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_MetricsReset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the current metrics through the EAS_Report interface.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_MetricsReset (EAS_DATA_HANDLE pEASData);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetSoundLibrary()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the location of the sound library.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * streamHandle - file or stream handle
+ * pSoundLib - pointer to sound library
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetSoundLibrary (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_SNDLIB_HANDLE pSndLib);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetHeaderSearchFlag()
+ *----------------------------------------------------------------------------
+ * By default, when EAS_OpenFile is called, the parsers check the
+ * first few bytes of the file looking for a specific header. Some
+ * mobile devices may add a header to the start of a file, which
+ * will prevent the parser from recognizing the file. If the
+ * searchFlag is set to EAS_TRUE, the parser will search the entire
+ * file looking for the header. This may enable EAS to recognize
+ * some files that it would ordinarily reject. The negative is that
+ * it make take slightly longer to process the EAS_OpenFile request.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * searchFlag - search flag (EAS_TRUE or EAS_FALSE)
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetHeaderSearchFlag (EAS_DATA_HANDLE pEASData, EAS_BOOL searchFlag);
+
+/*----------------------------------------------------------------------------
+ * EAS_SetPlayMode()
+ *----------------------------------------------------------------------------
+ * Some file formats support special play modes, such as iMode partial
+ * play mode. This call can be used to change the play mode. The
+ * default play mode (usually straight playback) is always zero.
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * handle - file or stream handle
+ * playMode - play mode (see eas_types.h for enumerations)
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetPlayMode (EAS_DATA_HANDLE pEASData, EAS_HANDLE pStream, EAS_I32 playMode);
+
+#ifdef DLS_SYNTHESIZER
+/*----------------------------------------------------------------------------
+ * EAS_LoadDLSCollection()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Downloads a DLS collection
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * streamHandle - file or stream handle
+ * locator - file locator
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * May overlay instruments in the GM sound set
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_LoadDLSCollection (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_FILE_LOCATOR locator);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetFrameBuffer()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the frame buffer pointer passed to the IPC communications functions
+ *
+ * Inputs:
+ * pEASData - instance data handle
+ * locator - file locator
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * May overlay instruments in the GM sound set
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_SetFrameBuffer (EAS_DATA_HANDLE pEASData, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
+
+#ifdef EXTERNAL_AUDIO
+/*----------------------------------------------------------------------------
+ * EAS_RegExtAudioCallback()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Registers callback functions for audio events.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * cbProgChgFunc - pointer to host callback function for program change
+ * cbEventFunc - pointer to host callback functio for note events
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_RegExtAudioCallback (EAS_DATA_HANDLE pEASData,
+ EAS_HANDLE streamHandle,
+ EAS_VOID_PTR pInstData,
+ EAS_EXT_PRG_CHG_FUNC cbProgChgFunc,
+ EAS_EXT_EVENT_FUNC cbEventFunc);
+
+/*----------------------------------------------------------------------------
+ * EAS_GetMIDIControllers()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of MIDI controllers on the requested channel.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * streamHandle - file or stream handle
+ * pControl - pointer to structure to receive data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SearchFile
+ *----------------------------------------------------------------------------
+ * Search file for specific sequence starting at current file
+ * position. Returns offset to start of sequence.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS persistent data object
+ * fileHandle - file handle
+ * searchString - pointer to search sequence
+ * len - length of search sequence
+ * pOffset - pointer to variable to store offset to sequence
+ *
+ * Returns EAS_EOF if end-of-file is reached
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_SearchFile (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, const EAS_U8 *searchString, EAS_I32 len, EAS_I32 *pOffset);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* #ifndef _EAS_H */
diff --git a/arm-wt-22k/host_src/eas_build.h b/arm-wt-22k/host_src/eas_build.h
new file mode 100644
index 0000000..4ff15cc
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_build.h
@@ -0,0 +1,36 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * host_src\eas_build.h
+ *
+ * Contents and purpose:
+ * This file contains the build configuration for this
+ * build. The buildGUIDStr is a GUID created during
+ * the build process and is guaranteed to be unique
+ * for each build.
+ *
+ * Copyright Sonic Network Inc. 2006
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file was autogenerated by buildid.exe
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _GUID_1feda229b9a845e996f473c0a80e7220_
+#define _GUID_1feda229b9a845e996f473c0a80e7220_
+
+#define _BUILD_VERSION_ "1feda229-b9a8-45e9-96f4-73c0a80e7220"
+#define _BUILD_TIME_ 0x4743badd
+
+#endif /* _GUID_1feda229b9a845e996f473c0a80e7220_ */
diff --git a/arm-wt-22k/host_src/eas_chorus.h b/arm-wt-22k/host_src/eas_chorus.h
new file mode 100644
index 0000000..0e9057f
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_chorus.h
@@ -0,0 +1,53 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorus.h
+ *
+ * Contents and purpose:
+ * Contains parameter enumerations for the Chorus effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 309 $
+ * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_CHORUS_H
+#define EAS_CHORUS_H
+
+/* enumerated parameter settings for Chorus effect */
+typedef enum
+{
+ EAS_PARAM_CHORUS_BYPASS,
+ EAS_PARAM_CHORUS_PRESET,
+ EAS_PARAM_CHORUS_RATE,
+ EAS_PARAM_CHORUS_DEPTH,
+ EAS_PARAM_CHORUS_LEVEL
+} E_CHORUS_PARAMS;
+
+typedef enum
+{
+ EAS_PARAM_CHORUS_PRESET1,
+ EAS_PARAM_CHORUS_PRESET2,
+ EAS_PARAM_CHORUS_PRESET3,
+ EAS_PARAM_CHORUS_PRESET4
+} E_CHORUS_PRESETS;
+
+
+#endif \ No newline at end of file
diff --git a/arm-wt-22k/host_src/eas_config.c b/arm-wt-22k/host_src/eas_config.c
new file mode 100644
index 0000000..c45fbb7
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_config.c
@@ -0,0 +1,619 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_config.c
+ *
+ * Contents and purpose:
+ * This file contains the Configuration Module interface (CM). The CM
+ * is a module compiled external to the library that sets the configuration
+ * for this build. It allows the library to find optional components and
+ * links to static memory allocations (when used in a static configuration).
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * NOTE: This module is not intended to be modified by the customer. It
+ * needs to be included in the build process with the correct configuration
+ * defines (see the library documentation for information on how to configure
+ * the library).
+ *
+ * Copyright Sonic Network Inc. 2004-2006
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 796 $
+ * $Date: 2007-08-01 00:15:25 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas.h"
+#include "eas_config.h"
+
+
+#ifdef _MFI_PARSER
+/*----------------------------------------------------------------------------
+ * Vendor/Device ID for MFi Extensions
+ *
+ * Define the preprocessor symbols to establish the vendor ID and
+ * device ID for the MFi PCM/ADPCM extensions.
+ *----------------------------------------------------------------------------
+*/
+const EAS_U8 eas_MFIVendorIDMSB = (MFI_VENDOR_ID >> 8) & 0xff;
+const EAS_U8 eas_MFIVendorIDLSB = MFI_VENDOR_ID & 0xff;
+const EAS_U8 eas_MFIDeviceID = MFI_DEVICE_ID;
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * parserModules
+ *
+ * This structure is used by the EAS library to locate file parsing
+ * modules.
+ *----------------------------------------------------------------------------
+*/
+
+/* define the external file parsers */
+extern EAS_VOID_PTR EAS_SMF_Parser;
+
+#ifdef _XMF_PARSER
+extern EAS_VOID_PTR EAS_XMF_Parser;
+#endif
+
+#ifdef _SMAF_PARSER
+extern EAS_VOID_PTR EAS_SMAF_Parser;
+#endif
+
+#ifdef _WAVE_PARSER
+extern EAS_VOID_PTR EAS_Wave_Parser;
+#endif
+
+#ifdef _OTA_PARSER
+extern EAS_VOID_PTR EAS_OTA_Parser;
+#endif
+
+#ifdef _IMELODY_PARSER
+extern EAS_VOID_PTR EAS_iMelody_Parser;
+#endif
+
+#ifdef _RTTTL_PARSER
+extern EAS_VOID_PTR EAS_RTTTL_Parser;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+extern EAS_VOID_PTR EAS_CMF_Parser;
+#endif
+
+/* initalize pointers to parser interfaces */
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const parserModules[] =
+{
+ &EAS_SMF_Parser,
+
+#ifdef _XMF_PARSER
+ &EAS_XMF_Parser,
+#endif
+
+#ifdef _WAVE_PARSER
+ &EAS_Wave_Parser,
+#endif
+
+#ifdef _SMAF_PARSER
+ &EAS_SMAF_Parser,
+#endif
+
+#ifdef _OTA_PARSER
+ &EAS_OTA_Parser,
+#endif
+
+#ifdef _IMELODY_PARSER
+ &EAS_iMelody_Parser,
+#endif
+
+#ifdef _RTTTL_PARSER
+ &EAS_RTTTL_Parser,
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+ &EAS_CMF_Parser
+#endif
+};
+#define NUM_PARSER_MODULES (sizeof(parserModules) / sizeof(EAS_VOID_PTR))
+
+/*----------------------------------------------------------------------------
+ * Data Modules
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_SMFData;
+extern EAS_VOID_PTR eas_Data;
+extern EAS_VOID_PTR eas_MixBuffer;
+extern EAS_VOID_PTR eas_Synth;
+extern EAS_VOID_PTR eas_MIDI;
+extern EAS_VOID_PTR eas_PCMData;
+extern EAS_VOID_PTR eas_MIDIData;
+
+#ifdef _XMF_PARSER
+extern EAS_VOID_PTR eas_XMFData;
+#endif
+
+#ifdef _SMAF_PARSER
+extern EAS_VOID_PTR eas_SMAFData;
+#endif
+
+#ifdef _OTA_PARSER
+extern EAS_VOID_PTR eas_OTAData;
+#endif
+
+#ifdef _IMELODY_PARSER
+extern EAS_VOID_PTR eas_iMelodyData;
+#endif
+
+#ifdef _RTTTL_PARSER
+extern EAS_VOID_PTR eas_RTTTLData;
+#endif
+
+#ifdef _WAVE_PARSER
+extern EAS_VOID_PTR eas_WaveData;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+extern EAS_VOID_PTR eas_CMFData;
+#endif
+#endif
+
+/*----------------------------------------------------------------------------
+ *
+ * Effects Modules
+ *
+ * These declarations are used by the EAS library to locate
+ * effects modules.
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _ENHANCER_ENABLED
+extern EAS_VOID_PTR EAS_Enhancer;
+#define EAS_ENHANCER_INTERFACE &EAS_Enhancer
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_EnhancerData;
+#define EAS_ENHANCER_DATA &eas_EnhancerData
+#else
+#define EAS_ENHANCER_DATA NULL
+#endif
+#else
+#define EAS_ENHANCER_INTERFACE NULL
+#define EAS_ENHANCER_DATA NULL
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+extern EAS_VOID_PTR EAS_Compressor;
+#define EAS_COMPRESSOR_INTERFACE &EAS_Compressor
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_CompressorData;
+#define EAS_COMPRESSOR_DATA &eas_CompressorData
+#else
+#define EAS_COMPRESSOR_DATA NULL
+#endif
+#else
+#define EAS_COMPRESSOR_INTERFACE NULL
+#define EAS_COMPRESSOR_DATA NULL
+#endif
+
+#ifdef _MAXIMIZER_ENABLED
+extern EAS_VOID_PTR EAS_Maximizer;
+#define EAS_MAXIMIZER_INTERFACE &EAS_Maximizer
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_MaximizerData;
+#define EAS_MAXIMIZER_DATA &eas_MaximizerData
+#else
+#define EAS_MAXIMIZER_DATA NULL
+#endif
+#else
+#define EAS_MAXIMIZER_INTERFACE NULL
+#define EAS_MAXIMIZER_DATA NULL
+#endif
+
+
+#ifdef _REVERB_ENABLED
+extern EAS_VOID_PTR EAS_Reverb;
+#define EAS_REVERB_INTERFACE &EAS_Reverb
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ReverbData;
+#define EAS_REVERB_DATA &eas_ReverbData
+#else
+#define EAS_REVERB_DATA NULL
+#endif
+#else
+#define EAS_REVERB_INTERFACE NULL
+#define EAS_REVERB_DATA NULL
+#endif
+
+#ifdef _CHORUS_ENABLED
+extern EAS_VOID_PTR EAS_Chorus;
+#define EAS_CHORUS_INTERFACE &EAS_Chorus
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ChorusData;
+#define EAS_CHORUS_DATA &eas_ChorusData
+#else
+#define EAS_CHORUS_DATA NULL
+#endif
+#else
+#define EAS_CHORUS_INTERFACE NULL
+#define EAS_CHORUS_DATA NULL
+#endif
+
+#ifdef _WIDENER_ENABLED
+extern EAS_VOID_PTR EAS_Widener;
+#define EAS_WIDENER_INTERFACE &EAS_Widener
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_WidenerData;
+#define EAS_WIDENER_DATA &eas_WidenerData
+#else
+#define EAS_WIDENER_DATA NULL
+#endif
+#else
+#define EAS_WIDENER_INTERFACE NULL
+#define EAS_WIDENER_DATA NULL
+#endif
+
+#ifdef _GRAPHIC_EQ_ENABLED
+extern EAS_VOID_PTR EAS_GraphicEQ;
+#define EAS_GRAPHIC_EQ_INTERFACE &EAS_GraphicEQ
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_GraphicEQData;
+#define EAS_GRAPHIC_EQ_DATA &eas_GraphicEQData
+#else
+#define EAS_GRAPHIC_EQ_DATA NULL
+#endif
+#else
+#define EAS_GRAPHIC_EQ_INTERFACE NULL
+#define EAS_GRAPHIC_EQ_DATA NULL
+#endif
+
+#ifdef _WOW_ENABLED
+extern EAS_VOID_PTR EAS_Wow;
+#define EAS_WOW_INTERFACE &EAS_Wow
+#ifdef _STATIC_MEMORY
+#error "WOW module requires dynamic memory model"
+#else
+#define EAS_WOW_DATA NULL
+#endif
+#else
+#define EAS_WOW_INTERFACE NULL
+#define EAS_WOW_DATA NULL
+#endif
+
+#ifdef _TONECONTROLEQ_ENABLED
+extern EAS_VOID_PTR EAS_ToneControlEQ;
+#define EAS_TONECONTROLEQ_INTERFACE &EAS_ToneControlEQ
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_ToneControlEQData;
+#define EAS_TONECONTROLEQ_DATA &eas_ToneControlEQData
+#else
+#define EAS_TONECONTROLEQ_DATA NULL
+#endif
+#else
+#define EAS_TONECONTROLEQ_INTERFACE NULL
+#define EAS_TONECONTROLEQ_DATA NULL
+#endif
+
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const effectsModules[] =
+{
+ EAS_ENHANCER_INTERFACE,
+ EAS_COMPRESSOR_INTERFACE,
+ EAS_REVERB_INTERFACE,
+ EAS_CHORUS_INTERFACE,
+ EAS_WIDENER_INTERFACE,
+ EAS_GRAPHIC_EQ_INTERFACE,
+ EAS_WOW_INTERFACE,
+ EAS_MAXIMIZER_INTERFACE,
+ EAS_TONECONTROLEQ_INTERFACE
+};
+
+EAS_VOID_PTR const effectsData[] =
+{
+ EAS_ENHANCER_DATA,
+ EAS_COMPRESSOR_DATA,
+ EAS_REVERB_DATA,
+ EAS_CHORUS_DATA,
+ EAS_WIDENER_DATA,
+ EAS_GRAPHIC_EQ_DATA,
+ EAS_WOW_DATA,
+ EAS_MAXIMIZER_DATA,
+ EAS_TONECONTROLEQ_DATA
+};
+
+/*----------------------------------------------------------------------------
+ *
+ * Optional Modules
+ *
+ * These declarations are used by the EAS library to locate
+ * effects modules.
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _METRICS_ENABLED
+extern EAS_VOID_PTR EAS_Metrics;
+#define EAS_METRICS_INTERFACE &EAS_Metrics
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_MetricsData;
+#define EAS_METRICS_DATA &eas_MetricsData
+#else
+#define EAS_METRICS_DATA NULL
+#endif
+#else
+#define EAS_METRICS_INTERFACE NULL
+#define EAS_METRICS_DATA NULL
+#endif
+
+#ifdef MMAPI_SUPPORT
+extern EAS_VOID_PTR EAS_TC_Parser;
+#define EAS_TONE_CONTROL_PARSER &EAS_TC_Parser
+#ifdef _STATIC_MEMORY
+extern EAS_VOID_PTR eas_TCData;
+#define EAS_TONE_CONTROL_DATA &eas_TCData
+#else
+#define EAS_TONE_CONTROL_DATA NULL
+#endif
+#else
+#define EAS_TONE_CONTROL_PARSER NULL
+#define EAS_TONE_CONTROL_DATA NULL
+#endif
+
+/*lint -e{605} not pretty, but it works */
+EAS_VOID_PTR const optionalModules[] =
+{
+ EAS_TONE_CONTROL_PARSER,
+ EAS_METRICS_INTERFACE
+};
+
+EAS_VOID_PTR const optionalData[] =
+{
+ EAS_TONE_CONTROL_DATA,
+ EAS_METRICS_DATA
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_CMStaticMemoryModel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function returns true if EAS has been configured for
+ * a static memory model. There are some limitations in the
+ * static memory model, see the documentation for more
+ * information.
+ *
+ * Outputs:
+ * returns EAS_TRUE if a module is found
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL EAS_CMStaticMemoryModel (void)
+{
+#ifdef _STATIC_MEMORY
+ return EAS_TRUE;
+#else
+ return EAS_FALSE;
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - module number
+ *
+ * Outputs:
+ * returns a pointer to the module function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module)
+{
+
+ if (module >= (EAS_INT) NUM_PARSER_MODULES)
+ return NULL;
+ return parserModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, dataModule) used only when _STATIC_MEMORY is defined */
+EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule)
+{
+
+#ifdef _STATIC_MEMORY
+ switch (dataModule)
+ {
+
+ /* main instance data for synthesizer */
+ case EAS_CM_EAS_DATA:
+ return &eas_Data;
+
+ /* mix buffer for mix engine */
+ case EAS_CM_MIX_BUFFER:
+ /*lint -e{545} lint doesn't like this because it sees the underlying type */
+ return &eas_MixBuffer;
+
+ /* instance data for synth */
+ case EAS_CM_SYNTH_DATA:
+ return &eas_Synth;
+
+ /* instance data for MIDI parser */
+ case EAS_CM_MIDI_DATA:
+ return &eas_MIDI;
+
+ /* instance data for SMF parser */
+ case EAS_CM_SMF_DATA:
+ return &eas_SMFData;
+
+#ifdef _XMF_PARSER
+ /* instance data for XMF parser */
+ case EAS_CM_XMF_DATA:
+ return &eas_XMFData;
+#endif
+
+#ifdef _SMAF_PARSER
+ /* instance data for SMAF parser */
+ case EAS_CM_SMAF_DATA:
+ return &eas_SMAFData;
+#endif
+
+ /* instance data for the PCM engine */
+ case EAS_CM_PCM_DATA:
+ /*lint -e{545} lint doesn't like this because it sees the underlying type */
+ return &eas_PCMData;
+
+ case EAS_CM_MIDI_STREAM_DATA:
+ return &eas_MIDIData;
+
+#ifdef _OTA_PARSER
+ /* instance data for OTA parser */
+ case EAS_CM_OTA_DATA:
+ return &eas_OTAData;
+#endif
+
+#ifdef _IMELODY_PARSER
+ /* instance data for iMelody parser */
+ case EAS_CM_IMELODY_DATA:
+ return &eas_iMelodyData;
+#endif
+
+#ifdef _RTTTL_PARSER
+ /* instance data for RTTTL parser */
+ case EAS_CM_RTTTL_DATA:
+ return &eas_RTTTLData;
+#endif
+
+#ifdef _WAVE_PARSER
+ /* instance data for WAVE parser */
+ case EAS_CM_WAVE_DATA:
+ return &eas_WaveData;
+#endif
+
+#if defined (_CMX_PARSER) || defined(_MFI_PARSER)
+ /* instance data for CMF parser */
+ case EAS_CM_CMF_DATA:
+ return &eas_CMFData;
+#endif
+
+ default:
+ return NULL;
+ }
+
+#else
+ return NULL;
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional effects modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ * pModule - pointer to module interface
+ *
+ * Outputs:
+ * Returns pointer to function table or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module)
+{
+
+ if (module >= NUM_EFFECTS_MODULES)
+ return NULL;
+ return effectsModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ * pData - pointer to handle variable
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule)
+{
+
+ if (dataModule >= NUM_EFFECTS_MODULES)
+ return NULL;
+ return effectsData[dataModule];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ *
+ * Outputs:
+ * returns pointer to function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module)
+{
+
+ /* sanity check */
+ if (module >= NUM_OPTIONAL_MODULES)
+ return EAS_FALSE;
+ return optionalModules[module];
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule)
+{
+
+ if (dataModule >= NUM_OPTIONAL_MODULES)
+ return NULL;
+ return optionalData[dataModule];
+}
+
+
diff --git a/arm-wt-22k/host_src/eas_config.h b/arm-wt-22k/host_src/eas_config.h
new file mode 100644
index 0000000..d16be4a
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_config.h
@@ -0,0 +1,191 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_config.h
+ *
+ * Contents and purpose:
+ * This header declares the Configuration Module interface (CM). The CM
+ * is a module compiled external to the library that sets the configuration
+ * for this build. It allows the library to find optional components and
+ * links to static memory allocations (when used in a static configuration).
+ *
+ * NOTE: This module is not intended to be modified by the customer. It
+ * needs to be included in the build process with the correct configuration
+ * defines (see the library documentation for information on how to configure
+ * the library).
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// sentinel
+#ifndef _EAS_CONFIG_H
+#define _EAS_CONFIG_H
+
+#include "eas_types.h"
+
+/* list of enumerators for optional modules */
+typedef enum {
+ EAS_CM_FILE_PARSERS = 1
+} E_CM_ENUM_MODULES;
+
+/* list of enumerators for module and memory pointers */
+typedef enum {
+ EAS_CM_EAS_DATA = 1,
+ EAS_CM_MIX_BUFFER,
+ EAS_CM_SYNTH_DATA,
+ EAS_CM_MIDI_DATA,
+ EAS_CM_SMF_DATA,
+ EAS_CM_XMF_DATA,
+ EAS_CM_SMAF_DATA,
+ EAS_CM_PCM_DATA,
+ EAS_CM_MIDI_STREAM_DATA,
+ EAS_CM_METRICS_DATA,
+ EAS_CM_OTA_DATA,
+ EAS_CM_IMELODY_DATA,
+ EAS_CM_RTTTL_DATA,
+ EAS_CM_WAVE_DATA,
+ EAS_CM_CMF_DATA
+} E_CM_DATA_MODULES;
+
+typedef struct
+{
+ int maxSMFStreams;
+ void *pSMFData;
+ void *pSMFStream;
+} S_EAS_SMF_PTRS;
+
+typedef struct
+{
+ int maxSMAFStreams;
+ void *pSMAFData;
+ void *pSMAFStream;
+} S_EAS_SMAF_PTRS;
+
+/*----------------------------------------------------------------------------
+ * EAS_CMStaticMemoryModel()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function returns true if EAS has been configured for
+ * a static memory model. There are some limitations in the
+ * static memory model, see the documentation for more
+ * information.
+ *
+ * Outputs:
+ * returns EAS_TRUE if a module is found
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL EAS_CMStaticMemoryModel (void);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - module number
+ *
+ * Outputs:
+ * returns a pointer to the module function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumData (EAS_INT dataModule);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional effects modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ * pModule - pointer to module interface
+ *
+ * Outputs:
+ * Returns pointer to function table or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumFXData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ * pData - pointer to handle variable
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumFXData (EAS_INT dataModule);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptModules()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to optional modules.
+ *
+ * Inputs:
+ * module - enumerated module number
+ *
+ * Outputs:
+ * returns pointer to function table or NULL if no module
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptModules (EAS_INT module);
+
+/*----------------------------------------------------------------------------
+ * EAS_CMEnumOptData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function is used to find pointers to static memory allocations.
+ *
+ * Inputs:
+ * dataModule - enumerated module number
+ *
+ * Outputs:
+ * Returns handle to data or NULL if not found
+ *----------------------------------------------------------------------------
+*/
+EAS_VOID_PTR EAS_CMEnumOptData (EAS_INT dataModule);
+
+#endif /* end _EAS_CONFIG_H */
diff --git a/arm-wt-22k/host_src/eas_debugmsgs.h b/arm-wt-22k/host_src/eas_debugmsgs.h
new file mode 100644
index 0000000..25913bd
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_debugmsgs.h
@@ -0,0 +1,87 @@
+/* Auto-generated from source file: eas_chorusdata.c */
+/* Auto-generated from source file: eas_xmfdata.c */
+/* Auto-generated from source file: eas_mdls.c */
+{ 0x19299ed4, 0x00000022, "eas_mdls.c[2561]: #Instruments: %u\n" },
+{ 0x19299ed4, 0x00000023, "eas_mdls.c[2562]: #Regions: %u\n" },
+{ 0x19299ed4, 0x00000024, "eas_mdls.c[2563]: #Articulations: %u\n" },
+{ 0x19299ed4, 0x00000025, "eas_mdls.c[2564]: #Waves: %u\n" },
+{ 0x19299ed4, 0x00000026, "eas_mdls.c[2569]: Locale: %lu:%lu:%lu\n" },
+{ 0x19299ed4, 0x00000027, "eas_mdls.c[2576]: \tRegion: %u\n" },
+{ 0x19299ed4, 0x00000028, "eas_mdls.c[2578]: \t\tm_nGain: %d\n" },
+{ 0x19299ed4, 0x00000029, "eas_mdls.c[2579]: \t\trangeLow:rangeHigh %u:%u\n" },
+{ 0x19299ed4, 0x0000002a, "eas_mdls.c[2580]: \t\tm_nKeyGroupAndFlags: %04x\n" },
+{ 0x19299ed4, 0x0000002b, "eas_mdls.c[2581]: \t\tm_nLoopStart: %u\n" },
+{ 0x19299ed4, 0x0000002c, "eas_mdls.c[2582]: \t\tm_nLoopEnd: %u\n" },
+{ 0x19299ed4, 0x0000002d, "eas_mdls.c[2583]: \t\tm_nNetTuningInCents: %d\n" },
+{ 0x19299ed4, 0x0000002e, "eas_mdls.c[2584]: \t\tArt Index: %u\n" },
+{ 0x19299ed4, 0x0000002f, "eas_mdls.c[2585]: \t\tWave Index: %u\n" },
+{ 0x19299ed4, 0x00000030, "eas_mdls.c[2597]: Articulation: %u\n" },
+{ 0x19299ed4, 0x00000031, "eas_mdls.c[2599]: \t\tm_nEG2toFilterDepth: %d\n" },
+{ 0x19299ed4, 0x00000032, "eas_mdls.c[2600]: \t\tm_nEG2toPitchDepth: %d\n" },
+{ 0x19299ed4, 0x00000033, "eas_mdls.c[2601]: \t\tm_nFilterCutoffFrequency: %d\n" },
+{ 0x19299ed4, 0x00000034, "eas_mdls.c[2602]: \t\tm_nFilterResonance: %u\n" },
+{ 0x19299ed4, 0x00000035, "eas_mdls.c[2603]: \t\tm_nLFOAmplitudeDepth: %d\n" },
+{ 0x19299ed4, 0x00000036, "eas_mdls.c[2604]: \t\tm_nLFODelayTime: %d\n" },
+{ 0x19299ed4, 0x00000037, "eas_mdls.c[2605]: \t\tm_nLFOFrequency: %d\n" },
+{ 0x19299ed4, 0x00000038, "eas_mdls.c[2606]: \t\tm_nLFOPitchDepth: %d\n" },
+{ 0x19299ed4, 0x00000039, "eas_mdls.c[2607]: \t\tm_nPan: %d\n" },
+{ 0x19299ed4, 0x0000003a, "eas_mdls.c[2610]: \t\tm_nAttack: %d\n" },
+{ 0x19299ed4, 0x0000003b, "eas_mdls.c[2611]: \t\tm_nDecay: %d\n" },
+{ 0x19299ed4, 0x0000003c, "eas_mdls.c[2612]: \t\tm_nSustain: %d\n" },
+{ 0x19299ed4, 0x0000003d, "eas_mdls.c[2613]: \t\tm_nRelease: %d\n" },
+{ 0x19299ed4, 0x0000003e, "eas_mdls.c[2616]: \t\tm_nAttack: %d\n" },
+{ 0x19299ed4, 0x0000003f, "eas_mdls.c[2617]: \t\tm_nDecay: %d\n" },
+{ 0x19299ed4, 0x00000040, "eas_mdls.c[2618]: \t\tm_nSustain: %d\n" },
+{ 0x19299ed4, 0x00000041, "eas_mdls.c[2619]: \t\tm_nRelease: %d\n" },
+{ 0x19299ed4, 0x00000042, "eas_mdls.c[2626]: Wave Index: %d\n" },
+{ 0x19299ed4, 0x00000043, "eas_mdls.c[2627]: \tSize %u\n" },
+{ 0x19299ed4, 0x00000044, "eas_mdls.c[2628]: \tPointer %08lx\n" },
+/* Auto-generated from source file: eas_mididata.c */
+/* Auto-generated from source file: eas_pan.c */
+/* Auto-generated from source file: eas_wavefiledata.c */
+/* Auto-generated from source file: eas_reverbdata.c */
+/* Auto-generated from source file: eas_imelodydata.c */
+/* Auto-generated from source file: eas_ota.c */
+/* Auto-generated from source file: eas_mixbuf.c */
+/* Auto-generated from source file: eas_tcdata.c */
+/* Auto-generated from source file: jet.c */
+/* Auto-generated from source file: eas_rtttl.c */
+/* Auto-generated from source file: eas_reverb.c */
+/* Auto-generated from source file: eas_pcmdata.c */
+/* Auto-generated from source file: eas_chorus.c */
+/* Auto-generated from source file: eas_math.c */
+/* Auto-generated from source file: eas_xmf.c */
+/* Auto-generated from source file: eas_smfdata.c */
+/* Auto-generated from source file: eas_imelody.c */
+/* Auto-generated from source file: eas_dlssynth.c */
+/* Auto-generated from source file: eas_public.c */
+/* Auto-generated from source file: eas_rtttldata.c */
+/* Auto-generated from source file: eas_voicemgt.c */
+/* Auto-generated from source file: eas_tonecontrol.c */
+/* Auto-generated from source file: eas_wtengine.c */
+/* Auto-generated from source file: eas_imaadpcm.c */
+{ 0x2380b977, 0x00000006, "eas_imaadpcm.c[305]: IMADecoderLocate: Time=%d, samples=%d\n" },
+{ 0x2380b977, 0x00000007, "eas_imaadpcm.c[328]: IMADecoderLocate: Looped sample, numBlocks=%d, samplesPerLoop=%d, samplesInLastBlock=%d, samples=%d\n" },
+{ 0x2380b977, 0x00000008, "eas_imaadpcm.c[335]: IMADecoderLocate: Byte location in audio = %d\n" },
+{ 0x2380b977, 0x00000009, "eas_imaadpcm.c[345]: IMADecoderLocate: bytesLeft = %d\n" },
+/* Auto-generated from source file: eas_flog.c */
+/* Auto-generated from source file: eas_midi.c */
+/* Auto-generated from source file: eas_otadata.c */
+/* Auto-generated from source file: eas_ima_tables.c */
+/* Auto-generated from source file: eas_data.c */
+/* Auto-generated from source file: eas_pcm.c */
+/* Auto-generated from source file: eas_mixer.c */
+/* Auto-generated from source file: eas_wavefile.c */
+/* Auto-generated from source file: eas_wtsynth.c */
+/* Auto-generated from source file: eas_smf.c */
+/* Auto-generated from source file: eas_wave.c */
+/* Auto-generated from source file: eas_hostmm.c */
+{ 0x1a54b6e8, 0x00000001, "eas_hostmm.c[586]: Vibrate state: %d\n" },
+{ 0x1a54b6e8, 0x00000002, "eas_hostmm.c[601]: LED state: %d\n" },
+{ 0x1a54b6e8, 0x00000003, "eas_hostmm.c[616]: Backlight state: %d\n" },
+{ 0x1a54b6e8, 0x00000004, "eas_hostmm.c[162]: HWMemCpy: bad amount: %d\n" },
+{ 0x1a54b6e8, 0x00000005, "eas_hostmm.c[179]: HWMemSet: bad amount: %d\n" },
+{ 0x1a54b6e8, 0x00000006, "eas_hostmm.c[196]: HWMemCmp: bad amount: %d\n" },
+/* Auto-generated from source file: eas_config.c */
+/* Auto-generated from source file: eas_main.c */
+{ 0xe624f4d9, 0x00000005, "eas_main.c[106]: Play length: %d.%03d (secs)\n" },
diff --git a/arm-wt-22k/host_src/eas_host.h b/arm-wt-22k/host_src/eas_host.h
new file mode 100644
index 0000000..270e68c
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_host.h
@@ -0,0 +1,87 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_host.h
+ *
+ * Contents and purpose:
+ * This header defines the host wrapper functions for stdio, stdlib, etc.
+ * The host application must provide an abstraction layer for these functions
+ * to support certain features, such as SMAF and SMF-1 conversion.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// sentinel
+#ifndef _EAS_HOST_H
+#define _EAS_HOST_H
+
+#include "eas_types.h"
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* initialization and shutdown routines */
+extern EAS_RESULT EAS_HWInit(EAS_HW_DATA_HANDLE *hwInstData);
+extern EAS_RESULT EAS_HWShutdown(EAS_HW_DATA_HANDLE hwInstData);
+
+/* threading */
+extern void* EAS_HWRegisterSignalHandler();
+extern EAS_RESULT EAS_HWUnRegisterSignalHandler(void *cookie);
+
+/* memory functions */
+extern void *EAS_HWMemSet(void *s, int c, EAS_I32 n);
+extern void *EAS_HWMemCpy(void *s1, const void *s2, EAS_I32 n);
+extern EAS_I32 EAS_HWMemCmp(const void *s1, const void *s2, EAS_I32 n);
+
+/* memory allocation */
+extern void *EAS_HWMalloc(EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size);
+extern void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p);
+
+/* file I/O */
+extern EAS_RESULT EAS_HWOpenFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode);
+extern EAS_RESULT EAS_HWReadFile(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead);
+extern EAS_RESULT EAS_HWGetByte(EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p);
+extern EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
+extern EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst);
+extern EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition);
+extern EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
+extern EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position);
+extern EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength);
+extern EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pFile);
+extern EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file);
+
+/* vibrate, LED, and backlight functions */
+extern EAS_RESULT EAS_HWVibrate(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+extern EAS_RESULT EAS_HWLED(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+extern EAS_RESULT EAS_HWBackLight(EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+
+/* host yield function */
+extern EAS_BOOL EAS_HWYield(EAS_HW_DATA_HANDLE hwInstData);
+#endif /* end _EAS_HOST_H */
diff --git a/arm-wt-22k/host_src/eas_hostmm.c b/arm-wt-22k/host_src/eas_hostmm.c
new file mode 100644
index 0000000..132239b
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_hostmm.c
@@ -0,0 +1,687 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_hostmm.c
+ *
+ * Contents and purpose:
+ * This file contains the host wrapper functions for stdio, stdlib, etc.
+ * This is a sample version that reads from a filedescriptor.
+ * The file locator (EAS_FILE_LOCATOR) handle passed to
+ * HWOpenFile is the same one that is passed to EAS_OpenFile.
+ *
+ * Modify this file to suit the needs of your particular system.
+ *
+ * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within
+ * a MIDI type 1 file that can be played.
+ *
+ * EAS_HW_FILE is a structure to support the file I/O functions. It
+ * comprises the file descriptor, the file read pointer, and
+ * the dup flag, which when set, indicates that the file handle has
+ * been duplicated, and offset and length within the file.
+ *
+ * Copyright 2005 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <signal.h>
+#define LOG_TAG "Sonivox"
+#include <utils/Log.h>
+#include <media/MediaPlayerInterface.h>
+#endif
+
+#include "eas_host.h"
+
+/* Only for debugging LED, vibrate, and backlight functions */
+#include "eas_report.h"
+
+/* this module requires dynamic memory support */
+#ifdef _STATIC_MEMORY
+#error "eas_hostmm.c requires the dynamic memory model!\n"
+#endif
+
+#ifndef EAS_MAX_FILE_HANDLES
+#define EAS_MAX_FILE_HANDLES 32
+#endif
+
+/*
+ * this structure and the related function are here
+ * to support the ability to create duplicate handles
+ * and buffering it in memory. If your system uses
+ * in-memory resources, you can eliminate the calls
+ * to malloc and free, the dup flag, and simply track
+ * the file size and read position.
+ */
+typedef struct eas_hw_file_tag
+{
+ EAS_I32 fileSize;
+ EAS_I32 filePos;
+ EAS_BOOL dup;
+ int fd;
+ EAS_I32 offset;
+} EAS_HW_FILE;
+
+typedef struct eas_hw_inst_data_tag
+{
+ EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
+} EAS_HW_INST_DATA;
+
+pthread_key_t EAS_sigbuskey;
+
+/*----------------------------------------------------------------------------
+ * EAS_HWInit
+ *
+ * Initialize host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
+{
+ EAS_HW_FILE *file;
+ int i;
+
+ /* need to track file opens for duplicate handles */
+ *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
+ if (!(*pHWInstData))
+ return EAS_ERROR_MALLOC_FAILED;
+
+ EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
+
+ file = (*pHWInstData)->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ file->fd = -1;
+ file++;
+ }
+
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_HWShutdown
+ *
+ * Shut down host wrapper interface
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
+{
+
+ free(hwInstData);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMalloc
+ *
+ * Allocates dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
+{
+ /* Since this whole library loves signed sizes, let's not let
+ * negative or 0 values through */
+ if (size <= 0)
+ return NULL;
+ return malloc((size_t) size);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFree
+ *
+ * Frees dynamic memory
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
+{
+ free(p);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCpy
+ *
+ * Copy memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
+{
+ if (amount < 0) {
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000004 , amount);
+ exit(255);
+ }
+ return memcpy(dest, src, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemSet
+ *
+ * Set memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
+{
+ if (amount < 0) {
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000005 , amount);
+ exit(255);
+ }
+ return memset(dest, val, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWMemCmp
+ *
+ * Compare memory wrapper
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
+{
+ if (amount < 0) {
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000006 , amount);
+ exit(255);
+ }
+ return (EAS_I32) memcmp(s1, s2, (size_t) amount);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWOpenFile
+ *
+ * Open a file for read or write
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
+{
+ EAS_HW_FILE *file;
+ int fd;
+ int i, temp;
+
+ /* set return value to NULL */
+ *pFile = NULL;
+
+ /* only support read mode at this time */
+ if (mode != EAS_FILE_READ)
+ return EAS_ERROR_INVALID_FILE_MODE;
+
+ /* find an empty entry in the file table */
+ file = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (file->fd < 0)
+ {
+ if (locator->path) {
+ /* open the file */
+ if ((fd = open(locator->path, O_RDONLY)) < 0) {
+ return EAS_ERROR_FILE_OPEN_FAILED;
+ }
+ } else {
+ /* else file is already open */
+ fd = dup(locator->fd);
+ }
+
+ /* determine the file size */
+ if (locator->length == 0) {
+ if (lseek(fd, 0, SEEK_END) < 0) {
+ close(fd);
+ return EAS_ERROR_FILE_LENGTH;
+ }
+ if ((file->fileSize = lseek(fd, 0, SEEK_CUR)) == -1L) {
+ close(fd);
+ return EAS_ERROR_FILE_LENGTH;
+ }
+ }
+
+ // file size was passed in
+ else {
+ file->fileSize = (EAS_I32) locator->length;
+ }
+
+ file->fd = fd;
+ file->offset = locator->offset;
+
+ /* initialize some values */
+ file->filePos = 0;
+ file->dup = EAS_FALSE;
+
+ *pFile = file;
+ return EAS_SUCCESS;
+ }
+ file++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWReadFile
+ *
+ * Read data from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
+{
+ EAS_I32 count;
+
+ /* make sure we have a valid handle */
+ if (file->fd < 0)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ if (n < 0)
+ return EAS_EOF;
+
+ /* calculate the bytes to read */
+ count = file->fileSize - file->filePos;
+ if (n < count)
+ count = n;
+ if (count < 0)
+ return EAS_EOF;
+
+ /* copy the data to the requested location, and advance the pointer */
+ if (count) {
+ lseek(file->fd, file->filePos + file->offset, SEEK_SET);
+ count = read(file->fd, pBuffer, count);
+ }
+ file->filePos += count;
+ *pBytesRead = count;
+
+ /* were n bytes read? */
+ if (count!= n)
+ return EAS_EOF;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetByte
+ *
+ * Read a byte from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
+{
+ EAS_I32 numread;
+ return EAS_HWReadFile(hwInstData, file, p, 1, &numread);
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetWord
+ *
+ * Read a 16 bit word from a file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_U8 c1, c2;
+
+ /* read 2 bytes from the file */
+ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
+ else
+ *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWGetDWord
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
+{
+ EAS_RESULT result;
+ EAS_U8 c1, c2,c3,c4;
+
+ /* read 4 bytes from the file */
+ if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
+ return result;
+
+ /* order them as requested */
+ if (msbFirst)
+ *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
+ else
+ *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFilePos
+ *
+ * Returns the current location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
+{
+
+ /* make sure we have a valid handle */
+ if (file->fd < 0)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pPosition = file->filePos;
+ return EAS_SUCCESS;
+} /* end EAS_HWFilePos */
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeek
+ *
+ * Seek to a specific location in the file
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+
+ /* make sure we have a valid handle */
+ if (file->fd < 0)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* validate new position */
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* save new position */
+ file->filePos = position;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileSeekOfs
+ *
+ * Seek forward or back relative to the current position
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
+{
+
+ /* make sure we have a valid handle */
+ if (file->fd < 0)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* determine the file position */
+ position += file->filePos;
+ if ((position < 0) || (position > file->fileSize))
+ return EAS_ERROR_FILE_SEEK;
+
+ /* save new position */
+ file->filePos = position;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWFileLength
+ *
+ * Return the file length
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
+{
+
+ /* make sure we have a valid handle */
+ if (file->fd < 0)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ *pLength = file->fileSize;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWDupHandle
+ *
+ * Duplicate a file handle
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
+{
+ EAS_HW_FILE *dupFile;
+ int i;
+
+ /* make sure we have a valid handle */
+ if (file->fd < 0)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* find an empty entry in the file table */
+ dupFile = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* is this slot being used? */
+ if (dupFile->fd < 0)
+ {
+ /* copy info from the handle to be duplicated */
+ dupFile->filePos = file->filePos;
+ dupFile->fileSize = file->fileSize;
+ dupFile->fd = file->fd;
+ dupFile->offset = file->offset;
+
+ /* set the duplicate handle flag */
+ dupFile->dup = file->dup = EAS_TRUE;
+
+ *pDupFile = dupFile;
+ return EAS_SUCCESS;
+ }
+ dupFile++;
+ }
+
+ /* too many open files */
+ return EAS_ERROR_MAX_FILES_OPEN;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWClose
+ *
+ * Wrapper for fclose function
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
+{
+ EAS_HW_FILE *file2,*dupFile;
+ int i;
+
+
+ /* make sure we have a valid handle */
+ if (file1->fd < 0)
+ return EAS_ERROR_INVALID_HANDLE;
+
+ /* check for duplicate handle */
+ if (file1->dup)
+ {
+ dupFile = NULL;
+ file2 = hwInstData->files;
+ for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
+ {
+ /* check for duplicate */
+ if ((file1 != file2) && (file2->fd == file1->fd))
+ {
+ /* is there more than one duplicate? */
+ if (dupFile != NULL)
+ {
+ /* clear this entry and return */
+ file1->fd = -1;
+ return EAS_SUCCESS;
+ }
+
+ /* this is the first duplicate found */
+ else
+ dupFile = file2;
+ }
+ file2++;
+ }
+
+ /* there is only one duplicate, clear the dup flag */
+ if (dupFile)
+ dupFile->dup = EAS_FALSE;
+ else
+ /* if we get here, there's a serious problem */
+ return EAS_ERROR_HANDLE_INTEGRITY;
+
+ /* clear this entry and return */
+ file1->fd = -1;
+ return EAS_SUCCESS;
+ }
+
+ /* no duplicates - close the file */
+ close(file1->fd);
+ /* clear this entry and return */
+ file1->fd = -1;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWVibrate
+ *
+ * Turn on/off vibrate function
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000001 , state);
+ return EAS_SUCCESS;
+} /* end EAS_HWVibrate */
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWLED
+ *
+ * Turn on/off LED
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000002 , state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWBackLight
+ *
+ * Turn on/off backlight
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
+{
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000003 , state);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_HWYield
+ *
+ * This function is called periodically by the EAS library to give the
+ * host an opportunity to allow other tasks to run. There are two ways to
+ * use this call:
+ *
+ * If you have a multi-tasking OS, you can call the yield function in the
+ * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
+ * the EAS library to continue processing when control returns from this
+ * function.
+ *
+ * If tasks run in a single thread by sequential function calls (sometimes
+ * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
+ * return to the caller. Be sure to check the number of bytes rendered
+ * before passing the audio buffer to the codec - it may not be filled.
+ * The next call to EAS_Render will continue processing until the buffer
+ * has been filled.
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, hwInstData) hwInstData available for customer use */
+EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
+{
+ /* put your code here */
+ return EAS_FALSE;
+}
+
diff --git a/arm-wt-22k/host_src/eas_main.c b/arm-wt-22k/host_src/eas_main.c
new file mode 100644
index 0000000..fed600e
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_main.c
@@ -0,0 +1,464 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_main.c
+ *
+ * Contents and purpose:
+ * The entry point and high-level functions for the EAS Synthesizer test
+ * harness.
+ *
+ * Copyright Sonic Network Inc. 2004
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 775 $
+ * $Date: 2007-07-20 10:11:11 -0700 (Fri, 20 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#endif
+
+#include "eas.h"
+#include "eas_wave.h"
+#include "eas_report.h"
+
+/* determines how many EAS buffers to fill a host buffer */
+#define NUM_BUFFERS 8
+
+/* default file to play if no filename is specified on the command line */
+static const char defaultTestFile[] = "test.mid";
+
+EAS_I32 polyphony;
+
+/* prototypes for helper functions */
+static void StrCopy(char *dest, const char *src, EAS_I32 size);
+static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size);
+static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize);
+static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig);
+
+/* main is defined after playfile to avoid the need for two passes through lint */
+
+/*----------------------------------------------------------------------------
+ * PlayFile()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function plays the file requested by filename
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_RESULT PlayFile (EAS_DATA_HANDLE easData, const char* filename, const char* outputFile, const S_EAS_LIB_CONFIG *pLibConfig, void *buffer, EAS_I32 bufferSize)
+{
+ EAS_HANDLE handle;
+ EAS_RESULT result, reportResult;
+ EAS_I32 count;
+ EAS_STATE state;
+ EAS_I32 playTime;
+ char waveFilename[256];
+ WAVE_FILE *wFile;
+ EAS_INT i;
+ EAS_PCM *p;
+ EAS_FILE file;
+
+ /* determine the name of the output file */
+ wFile = NULL;
+ if (outputFile == NULL)
+ {
+ StrCopy(waveFilename, filename, sizeof(waveFilename));
+ if (!ChangeFileExt(waveFilename, "wav", sizeof(waveFilename)))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error in output filename %s\n", waveFilename); */ }
+ return EAS_FAILURE;
+ }
+ outputFile = waveFilename;
+ }
+
+ /* call EAS library to open file */
+ file.path = filename;
+ file.fd = 0;
+ if ((reportResult = EAS_OpenFile(easData, &file, &handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_OpenFile returned %ld\n", reportResult); */ }
+ return reportResult;
+ }
+
+ /* prepare to play the file */
+ if ((result = EAS_Prepare(easData, handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Prepare returned %ld\n", result); */ }
+ reportResult = result;
+ }
+
+ /* get play length */
+ if ((result = EAS_ParseMetaData(easData, handle, &playTime)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_ParseMetaData returned %ld\n", result); */ }
+ return result;
+ }
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0xe624f4d9, 0x00000005 , playTime / 1000, playTime % 1000);
+
+ if (reportResult == EAS_SUCCESS)
+ {
+ /* create the output file */
+ wFile = WaveFileCreate(outputFile, pLibConfig->numChannels, pLibConfig->sampleRate, sizeof(EAS_PCM) * 8);
+ if (!wFile)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to create output file %s\n", waveFilename); */ }
+ reportResult = EAS_FAILURE;
+ }
+ }
+
+ /* rendering loop */
+ while (reportResult == EAS_SUCCESS)
+ {
+
+ /* we may render several buffers here to fill one host buffer */
+ for (i = 0, p = buffer; i < NUM_BUFFERS; i++, p+= pLibConfig->mixBufferSize * pLibConfig->numChannels)
+ {
+
+ /* get the current time */
+ if ((result = EAS_GetLocation(easData, handle, &playTime)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_GetLocation returned %d\n",result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ break;
+ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Parser time: %d.%03d\n", playTime / 1000, playTime % 1000); */ }
+
+ /* render a buffer of audio */
+ if ((result = EAS_Render(easData, p, pLibConfig->mixBufferSize, &count)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Render returned %d\n",result); */ }
+ if (reportResult == EAS_SUCCESS)
+ reportResult = result;
+ }
+ }
+
+ if (result == EAS_SUCCESS)
+ {
+ /* write it to the wave file */
+ if (WaveFileWrite(wFile, buffer, bufferSize) != bufferSize)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "WaveFileWrite failed\n"); */ }
+ reportResult = EAS_FAILURE;
+ }
+ }
+
+ if (reportResult == EAS_SUCCESS)
+ {
+ /* check stream state */
+ if ((result = EAS_State(easData, handle, &state)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_State returned %d\n", result); */ }
+ reportResult = result;
+ }
+
+ /* is playback complete */
+ if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR))
+ break;
+ }
+ }
+
+ /* close the output file */
+ if (wFile)
+ {
+ if (!WaveFileClose(wFile))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error closing wave file %s\n", waveFilename); */ }
+ if (reportResult == EAS_SUCCESS)
+ result = EAS_FAILURE;
+ }
+ }
+
+ /* close the input file */
+ if ((result = EAS_CloseFile(easData,handle)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_Close returned %ld\n", result); */ }
+ if (reportResult == EAS_SUCCESS)
+ result = EAS_FAILURE;
+ }
+
+ return reportResult;
+} /* end PlayFile */
+
+/*----------------------------------------------------------------------------
+ * main()
+ *----------------------------------------------------------------------------
+ * Purpose: The entry point for the EAS sample application
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+int main( int argc, char **argv )
+{
+ EAS_DATA_HANDLE easData;
+ const S_EAS_LIB_CONFIG *pLibConfig;
+ void *buffer;
+ EAS_RESULT result, playResult;
+ EAS_I32 bufferSize;
+ int i;
+ int temp;
+ FILE *debugFile;
+ char *outputFile = NULL;
+
+ /* set the error reporting level */
+ EAS_SetDebugLevel(_EAS_SEVERITY_INFO);
+ debugFile = NULL;
+
+ /* process command-line arguments */
+ for (i = 1; i < argc; i++)
+ {
+ /* check for switch */
+ if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'd':
+ temp = argv[i][2];
+ if ((temp >= '0') || (temp <= '9'))
+ EAS_SetDebugLevel(temp);
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid debug level %d\n", temp); */ }
+ break;
+ case 'f':
+ if ((debugFile = fopen(&argv[i][2],"w")) == NULL)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unable to create debug file %s\n", &argv[i][2]); */ }
+ else
+ EAS_SetDebugFile(debugFile, EAS_TRUE);
+ break;
+ case 'o':
+ outputFile = &argv[i][2];
+ break;
+ case 'p':
+ polyphony = atoi(&argv[i][2]);
+ if (polyphony < 1)
+ polyphony = 1;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Polyphony set to %d\n", polyphony); */ }
+ break;
+ default:
+ break;
+ }
+ continue;
+ }
+ }
+
+ /* assume success */
+ playResult = EAS_SUCCESS;
+
+ /* get the library configuration */
+ pLibConfig = EAS_Config();
+ if (!EASLibraryCheck(pLibConfig))
+ return -1;
+ if (polyphony > pLibConfig->maxVoices)
+ polyphony = pLibConfig->maxVoices;
+
+ /* calculate buffer size */
+ bufferSize = pLibConfig->mixBufferSize * pLibConfig->numChannels * (EAS_I32)sizeof(EAS_PCM) * NUM_BUFFERS;
+
+ /* allocate output buffer memory */
+ buffer = malloc((EAS_U32)bufferSize);
+ if (!buffer)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Error allocating memory for audio buffer\n"); */ }
+ return EAS_FAILURE;
+ }
+
+ /* initialize the EAS library */
+ polyphony = pLibConfig->maxVoices;
+ if ((result = EAS_Init(&easData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Init returned %ld - aborting!\n", result); */ }
+ free(buffer);
+ return result;
+ }
+
+ /*
+ * Some debugging environments don't allow for passed parameters.
+ * In this case, just play the default MIDI file "test.mid"
+ */
+ if (argc < 2)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", defaultTestFile); */ }
+ if ((playResult = PlayFile(easData, defaultTestFile, NULL, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, defaultTestFile); */ }
+ }
+ }
+ /* iterate through the list of files to be played */
+ else
+ {
+ for (i = 1; i < argc; i++)
+ {
+ /* check for switch */
+ if (argv[i][0] != '-')
+ {
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "Playing '%s'\n", argv[i]); */ }
+ if ((playResult = PlayFile(easData, argv[i], outputFile, pLibConfig, buffer, bufferSize)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d playing file %s\n", playResult, argv[i]); */ }
+ break;
+ }
+ }
+ }
+ }
+
+ /* shutdown the EAS library */
+ if ((result = EAS_Shutdown(easData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "EAS_Shutdown returned %ld\n", result); */ }
+ }
+
+ /* free the output buffer */
+ free(buffer);
+
+ /* close the debug file */
+ if (debugFile)
+ fclose(debugFile);
+
+ /* play errors take precedence over shutdown errors */
+ if (playResult != EAS_SUCCESS)
+ return playResult;
+ return result;
+} /* end main */
+
+/*----------------------------------------------------------------------------
+ * StrCopy()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Safe string copy
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void StrCopy(char *dest, const char *src, EAS_I32 size)
+{
+ int len;
+
+ strncpy(dest, src, (size_t) size-1);
+ len = (int) strlen(src);
+ if (len < size)
+ dest[len] = 0;
+} /* end StrCopy */
+
+/*----------------------------------------------------------------------------
+ * ChangeFileExt()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Changes the file extension of a filename
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL ChangeFileExt(char *str, const char *ext, EAS_I32 size)
+{
+ char *p;
+
+ /* find the extension, if any */
+ p = strrchr(str,'.');
+ if (!p)
+ {
+ if ((EAS_I32)(strlen(str) + 5) > size)
+ return EAS_FALSE;
+ strcat(str,".");
+ strcat(str,ext);
+ return EAS_TRUE;
+ }
+
+ /* make sure there's room for the extension */
+ p++;
+ *p = 0;
+ if ((EAS_I32)(strlen(str) + 4) > size)
+ return EAS_FALSE;
+ strcat(str,ext);
+ return EAS_TRUE;
+} /* end ChangeFileExt */
+
+/*----------------------------------------------------------------------------
+ * EASLibraryCheck()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Displays the library version and checks it against the header
+ * file used to build this code.
+ *
+ * Inputs:
+ * pLibConfig - library configuration retrieved from the library
+ *
+ * Outputs:
+ * returns EAS_TRUE if matched
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig)
+{
+
+ /* display the library version */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "EAS Library Version %d.%d.%d.%d\n",
+ pLibConfig->libVersion >> 24,
+ (pLibConfig->libVersion >> 16) & 0x0f,
+ (pLibConfig->libVersion >> 8) & 0x0f,
+ pLibConfig->libVersion & 0x0f); */ }
+
+ /* display some info about the library build */
+ if (pLibConfig->checkedVersion)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tChecked library\n"); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMaximum polyphony: %d\n", pLibConfig->maxVoices); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tNumber of channels: %d\n", pLibConfig->numChannels); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tSample rate: %d\n", pLibConfig->sampleRate); */ }
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMix buffer size: %d\n", pLibConfig->mixBufferSize); */ }
+ if (pLibConfig->filterEnabled)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tFilter enabled\n"); */ }
+#ifndef _WIN32_WCE
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build Timestamp: %s", ctime((time_t*)&pLibConfig->buildTimeStamp)); */ }
+#endif
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build ID: %s\n", pLibConfig->buildGUID); */ }
+
+ /* check it against the header file used to build this code */
+ /*lint -e{778} constant expression used for display purposes may evaluate to zero */
+ if (LIB_VERSION != pLibConfig->libVersion)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Library version does not match header files. EAS Header Version %d.%d.%d.%d\n",
+ LIB_VERSION >> 24,
+ (LIB_VERSION >> 16) & 0x0f,
+ (LIB_VERSION >> 8) & 0x0f,
+ LIB_VERSION & 0x0f); */ }
+ return EAS_FALSE;
+ }
+ return EAS_TRUE;
+} /* end EASLibraryCheck */
+
diff --git a/arm-wt-22k/host_src/eas_report.c b/arm-wt-22k/host_src/eas_report.c
new file mode 100644
index 0000000..d4dd22c
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_report.c
@@ -0,0 +1,264 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_report.c
+ *
+ * Contents and purpose:
+ * This file contains the debug message handling routines for the EAS library.
+ * These routines should be modified as needed for your system.
+ *
+ * Copyright 2005 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 659 $
+ * $Date: 2007-04-24 13:36:35 -0700 (Tue, 24 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#endif
+
+#include "eas_report.h"
+
+static int severityLevel = 9999;
+
+/* debug file */
+static FILE *debugFile = NULL;
+int flush = 0;
+
+#ifndef _NO_DEBUG_PREPROCESSOR
+
+/* structure should have an #include for each error message header file */
+S_DEBUG_MESSAGES debugMessages[] =
+{
+#ifndef UNIFIED_DEBUG_MESSAGES
+#include "eas_config_msgs.h"
+
+
+#include "eas_host_msgs.h"
+#include "eas_hostmm_msgs.h"
+#include "eas_math_msgs.h"
+#include "eas_midi_msgs.h"
+#include "eas_mixer_msgs.h"
+#include "eas_pcm_msgs.h"
+#include "eas_public_msgs.h"
+#include "eas_smf_msgs.h"
+#include "eas_wave_msgs.h"
+#include "eas_voicemgt_msgs.h"
+
+#ifdef _FM_SYNTH
+#include "eas_fmsynth_msgs.h"
+#include "eas_fmengine_msgs.h"
+#endif
+
+#ifdef _WT_SYNTH
+#include "eas_wtsynth_msgs.h"
+#include "eas_wtengine_msgs.h"
+#endif
+
+#ifdef _ARM_TEST_MAIN
+#include "arm_main_msgs.h"
+#endif
+
+#ifdef _EAS_MAIN
+#include "eas_main_msgs.h"
+#endif
+
+#ifdef _EAS_MAIN_IPC
+#include "eas_main_ipc_msgs.h"
+#endif
+
+#ifdef _METRICS_ENABLED
+#include "eas_perf_msgs.h"
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+#include "eas_compressor_msgs.h"
+#endif
+
+#ifdef _ENHANCER_ENABLED
+#include "eas_enhancer_msgs.h"
+#endif
+
+#ifdef _WOW_ENABLED
+#include "eas_wow_msgs.h"
+#endif
+
+#ifdef _SMAF_PARSER
+#include "eas_smaf_msgs.h"
+#endif
+
+#ifdef _OTA_PARSER
+#include "eas_ota_msgs.h"
+#endif
+
+#ifdef _IMELODY_PARSER
+#include "eas_imelody_msgs.h"
+#endif
+
+#ifdef _WAVE_PARSER
+#include "eas_wavefile_msgs.h"
+#endif
+
+#if defined(_CMX_PARSER) || defined(_MFI_PARSER)
+#include "eas_cmf_msgs.h"
+#endif
+
+#if defined(_CMX_PARSER) || defined(_MFI_PARSER) || defined(_WAVE_PARSER)
+#include "eas_imaadpcm_msgs.h"
+#endif
+
+#else
+#include "eas_debugmsgs.h"
+#endif
+
+/* denotes end of error messages */
+{ 0,0,0 }
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportEx()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
+{
+ va_list vargs;
+ int i;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /* find the error message and output to stdout */
+ /*lint -e{661} we check for NULL pointer - no fence post error here */
+ for (i = 0; debugMessages[i].m_pDebugMsg; i++)
+ {
+ if ((debugMessages[i].m_nHashCode == hashCode) &&
+ (debugMessages[i].m_nSerialNum == serialNum))
+ {
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, serialNum);
+ if (debugFile)
+ {
+ vfprintf(debugFile, debugMessages[i].m_pDebugMsg, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(debugMessages[i].m_pDebugMsg, vargs);
+ }
+ va_end(vargs);
+ return;
+ }
+ }
+ printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
+} /* end EAS_ReportEx */
+
+#else
+/*----------------------------------------------------------------------------
+ * EAS_Report()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_Report (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, fmt);
+ if (debugFile)
+ {
+ vfprintf(debugFile, fmt, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(fmt, vargs);
+ }
+ va_end(vargs);
+} /* end EAS_Report */
+
+/*----------------------------------------------------------------------------
+ * EAS_ReportX()
+ *
+ * This is the error message handler. The default handler outputs error
+ * messages to stdout. Modify this as needed for your system.
+ *----------------------------------------------------------------------------
+*/
+void EAS_ReportX (int severity, const char *fmt, ...)
+{
+ va_list vargs;
+
+ /* check severity level */
+ if (severity > severityLevel)
+ return;
+
+ /*lint -e{826} <allow variable args> */
+ va_start(vargs, fmt);
+ if (debugFile)
+ {
+ vfprintf(debugFile, fmt, vargs);
+ if (flush)
+ fflush(debugFile);
+ }
+ else
+ {
+ vprintf(fmt, vargs);
+ }
+ va_end(vargs);
+} /* end EAS_ReportX */
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_SetDebugLevel()
+ *
+ * Sets the level for debug message output
+ *----------------------------------------------------------------------------
+*/
+
+void EAS_SetDebugLevel (int severity)
+{
+ severityLevel = severity;
+} /* end EAS_SetDebugLevel */
+
+/*----------------------------------------------------------------------------
+ * EAS_SetDebugFile()
+ *
+ * Redirect debugger output to the specified file.
+ *----------------------------------------------------------------------------
+*/
+void EAS_SetDebugFile (void *file, int flushAfterWrite)
+{
+ debugFile = (FILE*) file;
+ flush = flushAfterWrite;
+} /* end EAS_SetDebugFile */
+
diff --git a/arm-wt-22k/host_src/eas_report.h b/arm-wt-22k/host_src/eas_report.h
new file mode 100644
index 0000000..9d7c8e8
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_report.h
@@ -0,0 +1,77 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_report.h
+ *
+ * Contents and purpose:
+ * This file contains the debug message handling routines for the EAS library.
+ * These routines should be modified as needed for your system.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright 2005 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+/* sentinel */
+#ifndef _EAS_REPORT_H
+#define _EAS_REPORT_H
+
+#define _EAS_SEVERITY_NOFILTER 0
+#define _EAS_SEVERITY_FATAL 1
+#define _EAS_SEVERITY_ERROR 2
+#define _EAS_SEVERITY_WARNING 3
+#define _EAS_SEVERITY_INFO 4
+#define _EAS_SEVERITY_DETAIL 5
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _NO_DEBUG_PREPROCESSOR
+
+/* structure for included debug message header files */
+typedef struct
+{
+ unsigned long m_nHashCode;
+ int m_nSerialNum;
+ char *m_pDebugMsg;
+} S_DEBUG_MESSAGES;
+
+/* debug message handling prototypes */
+extern void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...);
+
+#else
+
+/* these prototypes are used if the debug preprocessor is not used */
+extern void EAS_Report (int severity, const char* fmt, ...);
+extern void EAS_ReportX (int severity, const char* fmt, ...);
+
+#endif
+
+extern void EAS_SetDebugLevel (int severity);
+extern void EAS_SetDebugFile (void *file, int flushAfterWrite);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif
diff --git a/arm-wt-22k/host_src/eas_reverb.h b/arm-wt-22k/host_src/eas_reverb.h
new file mode 100644
index 0000000..a2535fb
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_reverb.h
@@ -0,0 +1,54 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_reverb.h
+ *
+ * Contents and purpose:
+ * Contains parameter enumerations for the Reverb effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 300 $
+ * $Date: 2006-09-11 17:37:20 -0700 (Mon, 11 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_REVERB_H
+#define _EAS_REVERB_H
+
+
+/* enumerated parameter settings for Reverb effect */
+typedef enum
+{
+ EAS_PARAM_REVERB_BYPASS,
+ EAS_PARAM_REVERB_PRESET,
+ EAS_PARAM_REVERB_WET,
+ EAS_PARAM_REVERB_DRY
+} E_REVERB_PARAMS;
+
+
+typedef enum
+{
+ EAS_PARAM_REVERB_LARGE_HALL,
+ EAS_PARAM_REVERB_HALL,
+ EAS_PARAM_REVERB_CHAMBER,
+ EAS_PARAM_REVERB_ROOM,
+} E_REVERB_PRESETS;
+
+
+#endif /* _REVERB_H */
diff --git a/arm-wt-22k/host_src/eas_types.h b/arm-wt-22k/host_src/eas_types.h
new file mode 100644
index 0000000..5ba1e4e
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_types.h
@@ -0,0 +1,273 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_types.h
+ *
+ * Contents and purpose:
+ * The public interface header for the EAS synthesizer.
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2004
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 726 $
+ * $Date: 2007-06-14 23:10:46 -0700 (Thu, 14 Jun 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_TYPES_H
+#define _EAS_TYPES_H
+
+/* EAS_RESULT return codes */
+typedef long EAS_RESULT;
+#define EAS_SUCCESS 0
+#define EAS_FAILURE -1
+#define EAS_ERROR_INVALID_MODULE -2
+#define EAS_ERROR_MALLOC_FAILED -3
+#define EAS_ERROR_FILE_POS -4
+#define EAS_ERROR_INVALID_FILE_MODE -5
+#define EAS_ERROR_FILE_SEEK -6
+#define EAS_ERROR_FILE_LENGTH -7
+#define EAS_ERROR_NOT_IMPLEMENTED -8
+#define EAS_ERROR_CLOSE_FAILED -9
+#define EAS_ERROR_FILE_OPEN_FAILED -10
+#define EAS_ERROR_INVALID_HANDLE -11
+#define EAS_ERROR_NO_MIX_BUFFER -12
+#define EAS_ERROR_PARAMETER_RANGE -13
+#define EAS_ERROR_MAX_FILES_OPEN -14
+#define EAS_ERROR_UNRECOGNIZED_FORMAT -15
+#define EAS_BUFFER_SIZE_MISMATCH -16
+#define EAS_ERROR_FILE_FORMAT -17
+#define EAS_ERROR_SMF_NOT_INITIALIZED -18
+#define EAS_ERROR_LOCATE_BEYOND_END -19
+#define EAS_ERROR_INVALID_PCM_TYPE -20
+#define EAS_ERROR_MAX_PCM_STREAMS -21
+#define EAS_ERROR_NO_VOICE_ALLOCATED -22
+#define EAS_ERROR_INVALID_CHANNEL -23
+#define EAS_ERROR_ALREADY_STOPPED -24
+#define EAS_ERROR_FILE_READ_FAILED -25
+#define EAS_ERROR_HANDLE_INTEGRITY -26
+#define EAS_ERROR_MAX_STREAMS_OPEN -27
+#define EAS_ERROR_INVALID_PARAMETER -28
+#define EAS_ERROR_FEATURE_NOT_AVAILABLE -29
+#define EAS_ERROR_SOUND_LIBRARY -30
+#define EAS_ERROR_NOT_VALID_IN_THIS_STATE -31
+#define EAS_ERROR_NO_VIRTUAL_SYNTHESIZER -32
+#define EAS_ERROR_FILE_ALREADY_OPEN -33
+#define EAS_ERROR_FILE_ALREADY_CLOSED -34
+#define EAS_ERROR_INCOMPATIBLE_VERSION -35
+#define EAS_ERROR_QUEUE_IS_FULL -36
+#define EAS_ERROR_QUEUE_IS_EMPTY -37
+#define EAS_ERROR_FEATURE_ALREADY_ACTIVE -38
+
+/* special return codes */
+#define EAS_EOF 3
+#define EAS_STREAM_BUFFERING 4
+#define EAS_BUFFER_FULL 5
+
+/* EAS_STATE return codes */
+typedef long EAS_STATE;
+typedef enum
+{
+ EAS_STATE_READY = 0,
+ EAS_STATE_PLAY,
+ EAS_STATE_STOPPING,
+ EAS_STATE_PAUSING,
+ EAS_STATE_STOPPED,
+ EAS_STATE_PAUSED,
+ EAS_STATE_OPEN,
+ EAS_STATE_ERROR,
+ EAS_STATE_EMPTY
+} E_EAS_STATE;
+
+/* constants */
+#ifndef EAS_CONST
+#define EAS_CONST const
+#endif
+
+/* definition for public interface functions */
+#ifndef EAS_PUBLIC
+#define EAS_PUBLIC
+#endif
+
+/* boolean values */
+typedef unsigned EAS_BOOL;
+typedef unsigned char EAS_BOOL8;
+
+#define EAS_FALSE 0
+#define EAS_TRUE 1
+
+/* scalar variable definitions */
+typedef unsigned char EAS_U8;
+typedef signed char EAS_I8;
+typedef char EAS_CHAR;
+
+typedef unsigned short EAS_U16;
+typedef short EAS_I16;
+
+typedef unsigned long EAS_U32;
+typedef long EAS_I32;
+
+typedef unsigned EAS_UINT;
+typedef int EAS_INT;
+typedef long EAS_LONG;
+
+/* audio output type */
+typedef short EAS_PCM;
+
+/* file open modes */
+typedef EAS_I32 EAS_FILE_MODE;
+#define EAS_FILE_READ 1
+#define EAS_FILE_WRITE 2
+
+/* file locator e.g. filename or memory pointer */
+typedef struct s_eas_file_tag {
+ const char* path;
+ int fd;
+ long long offset;
+ long long length;
+} EAS_FILE, *EAS_FILE_LOCATOR;
+
+/* handle to stream */
+typedef struct s_eas_stream_tag *EAS_HANDLE;
+
+/* handle to file */
+typedef struct eas_hw_file_tag *EAS_FILE_HANDLE;
+
+/* handle for synthesizer data */
+typedef struct s_eas_data_tag *EAS_DATA_HANDLE;
+
+/* handle to persistent data for host wrapper interface */
+typedef struct eas_hw_inst_data_tag *EAS_HW_DATA_HANDLE;
+
+/* handle to sound library */
+typedef struct s_eas_sndlib_tag *EAS_SNDLIB_HANDLE;
+typedef struct s_eas_dls_tag *EAS_DLSLIB_HANDLE;
+
+/* pointer to frame buffer - used in split architecture only */
+typedef struct s_eas_frame_buffer_tag *EAS_FRAME_BUFFER_HANDLE;
+
+/* untyped pointer for instance data */
+typedef void *EAS_VOID_PTR;
+
+/* inline functions */
+#ifndef EAS_INLINE
+#if defined (__XCC__)
+#define EAS_INLINE __inline__
+#elif defined (__GNUC__)
+#define EAS_INLINE inline static
+#else
+#define EAS_INLINE __inline
+#endif
+#endif
+
+/* define NULL value */
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* metadata types for metadata return codes */
+typedef enum
+{
+ EAS_METADATA_UNKNOWN = 0,
+ EAS_METADATA_TITLE,
+ EAS_METADATA_AUTHOR,
+ EAS_METADATA_COPYRIGHT,
+ EAS_METADATA_LYRIC,
+ EAS_METADATA_TEXT
+} E_EAS_METADATA_TYPE;
+
+/* metadata callback function */
+typedef void (*EAS_METADATA_CBFUNC) (E_EAS_METADATA_TYPE metaDataType, char *metaDataBuf, EAS_VOID_PTR pUserData);
+
+/* file types for metadata return codes */
+typedef enum
+{
+ EAS_FILE_UNKNOWN = 0,
+ EAS_FILE_SMF0,
+ EAS_FILE_SMF1,
+ EAS_FILE_SMAF_UNKNOWN,
+ EAS_FILE_SMAF_MA2,
+ EAS_FILE_SMAF_MA3,
+ EAS_FILE_SMAF_MA5,
+ EAS_FILE_CMX,
+ EAS_FILE_MFI,
+ EAS_FILE_OTA,
+ EAS_FILE_IMELODY,
+ EAS_FILE_RTTTL,
+ EAS_FILE_XMF0,
+ EAS_FILE_XMF1,
+ EAS_FILE_WAVE_PCM,
+ EAS_FILE_WAVE_IMA_ADPCM,
+ EAS_FILE_MMAPI_TONE_CONTROL
+} E_EAS_FILE_TYPE;
+
+/* enumeration for synthesizers */
+typedef enum
+{
+ EAS_MCU_SYNTH = 0,
+ EAS_DSP_SYNTH
+} E_SYNTHESIZER;
+
+/* external audio callback program change */
+typedef struct s_ext_audio_prg_chg_tag
+{
+ EAS_U16 bank;
+ EAS_U8 program;
+ EAS_U8 channel;
+} S_EXT_AUDIO_PRG_CHG;
+
+/* external audio callback event */
+typedef struct s_ext_audio_event_tag
+{
+ EAS_U8 channel;
+ EAS_U8 note;
+ EAS_U8 velocity;
+ EAS_BOOL8 noteOn;
+} S_EXT_AUDIO_EVENT;
+
+typedef struct s_midi_controllers_tag
+{
+ EAS_U8 modWheel; /* CC1 */
+ EAS_U8 volume; /* CC7 */
+ EAS_U8 pan; /* CC10 */
+ EAS_U8 expression; /* CC11 */
+ EAS_U8 channelPressure; /* MIDI channel pressure */
+
+#ifdef _REVERB
+ EAS_U8 reverbSend; /* CC91 */
+#endif
+
+#ifdef _CHORUS
+ EAS_U8 chorusSend; /* CC93 */
+#endif
+} S_MIDI_CONTROLLERS;
+
+/* iMode play modes enumeration for EAS_SetPlayMode */
+typedef enum
+{
+ IMODE_PLAY_ALL = 0,
+ IMODE_PLAY_PARTIAL
+} E_I_MODE_PLAY_MODE;
+
+typedef EAS_BOOL (*EAS_EXT_PRG_CHG_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_PRG_CHG *pPrgChg);
+typedef EAS_BOOL (*EAS_EXT_EVENT_FUNC) (EAS_VOID_PTR pInstData, S_EXT_AUDIO_EVENT *pEvent);
+
+#endif /* #ifndef _EAS_TYPES_H */
diff --git a/arm-wt-22k/host_src/eas_wave.c b/arm-wt-22k/host_src/eas_wave.c
new file mode 100644
index 0000000..02fed6e
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_wave.c
@@ -0,0 +1,423 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wave.c
+ *
+ * Contents and purpose:
+ * This module contains .WAV file functions for the EAS synthesizer
+ * test harness.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 658 $
+ * $Date: 2007-04-24 13:35:49 -0700 (Tue, 24 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* lint complaints about most C library headers, so we use our own during lint step */
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include "eas_wave.h"
+
+/* .WAV file format tags */
+const EAS_U32 riffTag = 0x46464952;
+const EAS_U32 waveTag = 0x45564157;
+const EAS_U32 fmtTag = 0x20746d66;
+const EAS_U32 dataTag = 0x61746164;
+
+#ifdef _BIG_ENDIAN
+/*----------------------------------------------------------------------------
+ * FlipDWord()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip a DWORD for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipDWord (EAS_U32 *pValue)
+{
+ EAS_U8 *p;
+ EAS_U32 temp;
+
+ p = (EAS_U8*) pValue;
+ temp = (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
+ *pValue = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FlipWord()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip a WORD for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipWord (EAS_U16 *pValue)
+{
+ EAS_U8 *p;
+ EAS_U16 temp;
+
+ p = (EAS_U8*) pValue;
+ temp = (p[1] << 8) | p[0];
+ *pValue = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FlipWaveHeader()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip the wave header for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipWaveHeader (WAVE_HEADER *p)
+{
+
+ FlipDWord(&p->nRiffTag);
+ FlipDWord(&p->nRiffSize);
+ FlipDWord(&p->nWaveTag);
+ FlipDWord(&p->nFmtTag);
+ FlipDWord(&p->nFmtSize);
+ FlipDWord(&p->nDataTag);
+ FlipDWord(&p->nDataSize);
+ FlipWord(&p->fc.wFormatTag);
+ FlipWord(&p->fc.nChannels);
+ FlipDWord(&p->fc.nSamplesPerSec);
+ FlipDWord(&p->fc.nAvgBytesPerSec);
+ FlipWord(&p->fc.nBlockAlign);
+ FlipWord(&p->fc.wBitsPerSample);
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * WaveFileCreate()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for writing and writes the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample)
+{
+ WAVE_FILE *wFile;
+
+ /* allocate memory */
+ wFile = malloc(sizeof(WAVE_FILE));
+ if (!wFile)
+ return NULL;
+ wFile->write = EAS_TRUE;
+
+ /* create the file */
+ wFile->file = fopen(filename,"wb");
+ if (!wFile->file)
+ {
+ free(wFile);
+ return NULL;
+ }
+
+ /* initialize PCM format .WAV file header */
+ wFile->wh.nRiffTag = riffTag;
+ wFile->wh.nRiffSize = sizeof(WAVE_HEADER) - 8;
+ wFile->wh.nWaveTag = waveTag;
+ wFile->wh.nFmtTag = fmtTag;
+ wFile->wh.nFmtSize = sizeof(FMT_CHUNK);
+
+ /* initalize 'fmt' chunk */
+ wFile->wh.fc.wFormatTag = 1;
+ wFile->wh.fc.nChannels = (EAS_U16) nChannels;
+ wFile->wh.fc.nSamplesPerSec = (EAS_U32) nSamplesPerSec;
+ wFile->wh.fc.wBitsPerSample = (EAS_U16) wBitsPerSample;
+ wFile->wh.fc.nBlockAlign = (EAS_U16) (nChannels * (EAS_U16) (wBitsPerSample / 8));
+ wFile->wh.fc.nAvgBytesPerSec = wFile->wh.fc.nBlockAlign * (EAS_U32) nSamplesPerSec;
+
+ /* initialize 'data' chunk */
+ wFile->wh.nDataTag = dataTag;
+ wFile->wh.nDataSize = 0;
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+
+ /* write the header */
+ if (fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file) != 1)
+ {
+ fclose(wFile->file);
+ free(wFile);
+ return NULL;
+ }
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+
+ /* return the file handle */
+ return wFile;
+} /* end WaveFileCreate */
+
+/*----------------------------------------------------------------------------
+ * WaveFileWrite()
+ *----------------------------------------------------------------------------
+ * Purpose: Writes data to the wave file
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n)
+{
+ EAS_I32 count;
+
+ /* make sure we have an open file */
+ if (wFile == NULL)
+ {
+ return 0;
+ }
+
+#ifdef _BIG_ENDIAN
+ {
+ EAS_I32 i;
+ EAS_U16 *p;
+ p = buffer;
+ i = n >> 1;
+ while (i--)
+ FlipWord(p++);
+ }
+#endif
+
+ /* write the data */
+ count = (EAS_I32) fwrite(buffer, 1, (size_t) n, wFile->file);
+
+ /* add the number of bytes written */
+ wFile->wh.nRiffSize += (EAS_U32) count;
+ wFile->wh.nDataSize += (EAS_U32) count;
+
+ /* return the count of bytes written */
+ return count;
+} /* end WriteWaveHeader */
+
+/*----------------------------------------------------------------------------
+ * WaveFileClose()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for writing and writes the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+EAS_BOOL WaveFileClose (WAVE_FILE *wFile)
+{
+ EAS_I32 count = 1;
+
+ /* return to beginning of file and write the header */
+ if (wFile->write)
+ {
+ if (fseek(wFile->file, 0L, SEEK_SET) == 0)
+ {
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+ count = (EAS_I32) fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file);
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+ }
+ }
+
+ /* close the file */
+ if (fclose(wFile->file) != 0)
+ count = 0;
+
+ /* free the memory */
+ free(wFile);
+
+ /* return the file handle */
+ return (count == 1 ? EAS_TRUE : EAS_FALSE);
+} /* end WaveFileClose */
+
+#ifdef _WAVE_FILE_READ
+#ifdef _BIG_ENDIAN
+#error "WaveFileOpen not currently supported on big-endian processors"
+#endif
+/*----------------------------------------------------------------------------
+ * WaveFileOpen()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for reading and reads the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+WAVE_FILE *WaveFileOpen (const char *filename)
+{
+ WAVE_FILE *wFile;
+ struct
+ {
+ EAS_U32 tag;
+ EAS_U32 size;
+ } chunk;
+ EAS_U32 tag;
+ EAS_I32 startChunkPos;
+ EAS_INT state;
+ EAS_BOOL done;
+
+ /* allocate memory */
+ wFile = malloc(sizeof(WAVE_FILE));
+ if (!wFile)
+ return NULL;
+
+ /* open the file */
+ wFile->write = EAS_FALSE;
+ wFile->file = fopen(filename,"rb");
+ if (!wFile->file)
+ {
+ free(wFile);
+ return NULL;
+ }
+
+ /* make lint happy */
+ chunk.tag = chunk.size = 0;
+ startChunkPos = 0;
+
+ /* read the RIFF tag and file size */
+ state = 0;
+ done = EAS_FALSE;
+ while (!done)
+ {
+
+ switch(state)
+ {
+ /* read the RIFF tag */
+ case 0:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ if (chunk.tag != riffTag)
+ done = EAS_TRUE;
+ else
+ state++;
+ }
+ break;
+
+ /* read the WAVE tag */
+ case 1:
+ if (fread(&tag, sizeof(tag), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ if (tag != waveTag)
+ done = EAS_TRUE;
+ else
+ state++;
+ }
+ break;
+
+ /* looking for fmt chunk */
+ case 2:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ startChunkPos = ftell(wFile->file);
+
+ /* not fmt tag, skip it */
+ if (chunk.tag != fmtTag)
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ else
+ state++;
+ }
+ break;
+
+ /* read fmt chunk */
+ case 3:
+ if (fread(&wFile->wh.fc, sizeof(FMT_CHUNK), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ state++;
+ }
+ break;
+
+ /* looking for data chunk */
+ case 4:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ startChunkPos = ftell(wFile->file);
+
+ /* not data tag, skip it */
+ if (chunk.tag != dataTag)
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ else
+ {
+ wFile->dataSize = chunk.size;
+ state++;
+ done = EAS_TRUE;
+ }
+ }
+ break;
+
+ default:
+ done = EAS_TRUE;
+ break;
+ }
+ }
+
+ /* if not final state, an error occurred */
+ if (state != 5)
+ {
+ fclose(wFile->file);
+ free(wFile);
+ return NULL;
+ }
+
+ /* return the file handle */
+ return wFile;
+} /* end WaveFileOpen */
+#endif
+
+
+
diff --git a/arm-wt-22k/host_src/eas_wave.h b/arm-wt-22k/host_src/eas_wave.h
new file mode 100644
index 0000000..ca388f5
--- /dev/null
+++ b/arm-wt-22k/host_src/eas_wave.h
@@ -0,0 +1,74 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wave.h
+ *
+ * Contents and purpose:
+ * Writes output to a .WAV file
+ *
+ * DO NOT MODIFY THIS FILE!
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+
+/* sentinel */
+#ifndef _EAS_WAVE_H
+#define _EAS_WAVE_H
+
+/* .WAV file format chunk */
+typedef struct {
+ EAS_U16 wFormatTag;
+ EAS_U16 nChannels;
+ EAS_U32 nSamplesPerSec;
+ EAS_U32 nAvgBytesPerSec;
+ EAS_U16 nBlockAlign;
+ EAS_U16 wBitsPerSample;
+} FMT_CHUNK;
+
+/* .WAV file header */
+typedef struct {
+ EAS_U32 nRiffTag;
+ EAS_U32 nRiffSize;
+ EAS_U32 nWaveTag;
+ EAS_U32 nFmtTag;
+ EAS_U32 nFmtSize;
+ FMT_CHUNK fc;
+ EAS_U32 nDataTag;
+ EAS_U32 nDataSize;
+} WAVE_HEADER;
+
+typedef struct {
+ WAVE_HEADER wh;
+ FILE *file;
+ EAS_BOOL write;
+ EAS_U32 dataSize;
+} WAVE_FILE;
+
+WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample);
+EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n);
+EAS_BOOL WaveFileClose (WAVE_FILE *wFile);
+WAVE_FILE *WaveFileOpen (const char *filename);
+
+#endif /* end #ifndef _EAS_WAVE_H */
+
+
+
diff --git a/arm-wt-22k/host_src/jet.h b/arm-wt-22k/host_src/jet.h
new file mode 100644
index 0000000..b5bce00
--- /dev/null
+++ b/arm-wt-22k/host_src/jet.h
@@ -0,0 +1,199 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * jet.h
+ *
+ * Contents and purpose:
+ * Public interface for JET sound engine
+ *
+ * Copyright (c) 2006 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 554 $
+ * $Date: 2007-02-02 11:06:10 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _JET_H
+#define _JET_H
+
+#include "eas_types.h"
+#include "eas.h"
+
+/* for C++ linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* opaque handle types for JET interface */
+typedef struct s_jet_data_tag *JET_DATA_HANDLE;
+
+typedef struct s_jet_config_tag
+{
+ EAS_U8 appEventRangeLow;
+ EAS_U8 appEventRangeHigh;
+} S_JET_CONFIG;
+
+typedef struct s_jet_status_tag
+{
+ EAS_INT currentUserID;
+ EAS_INT segmentRepeatCount;
+ EAS_INT numQueuedSegments;
+ EAS_BOOL paused;
+ EAS_I32 location;
+ EAS_U8 currentPlayingSegment;
+ EAS_U8 currentQueuedSegment;
+} S_JET_STATUS;
+
+typedef struct s_jet_event_tag
+{
+ EAS_U8 segment;
+ EAS_U8 channel;
+ EAS_U8 track;
+ EAS_U8 controller;
+ EAS_U8 value;
+} S_JET_EVENT;
+
+/*----------------------------------------------------------------------------
+ * JET_Init()
+ *----------------------------------------------------------------------------
+ * Initializes the JET library, allocates memory, etc. Call
+ * JET_Shutdown to de-allocate memory. Pass NULL for pConfig
+ * to use defaults. If passing config data, configSize should be
+ * sizeof(S_JET_CONFIG). This allows for future expansion of the
+ * config structure while maintaining compatibility.
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Init (EAS_DATA_HANDLE easHandle, const S_JET_CONFIG *pConfig, EAS_INT configSize);
+
+/*----------------------------------------------------------------------------
+ * JET_Shutdown()
+ *----------------------------------------------------------------------------
+ * Frees any memory used by the JET library
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Shutdown (EAS_DATA_HANDLE easHandle);
+
+/*----------------------------------------------------------------------------
+ * JET_OpenFile()
+ *----------------------------------------------------------------------------
+ * Opens a JET content file for playback
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_OpenFile (EAS_DATA_HANDLE easHandle, EAS_FILE_LOCATOR locator);
+
+/*----------------------------------------------------------------------------
+ * JET_GetAppData()
+ *----------------------------------------------------------------------------
+ * Returns location and size of application data in the JET file
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT JET_GetAppData (EAS_DATA_HANDLE easHandle, EAS_I32 *pAppDataOffset, EAS_I32 *pAppDataSize);
+
+/*----------------------------------------------------------------------------
+ * JET_CloseFile()
+ *----------------------------------------------------------------------------
+ * Closes a JET content file and releases associated resources
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_CloseFile (EAS_DATA_HANDLE easHandle);
+
+/*----------------------------------------------------------------------------
+ * JET_Status()
+ *----------------------------------------------------------------------------
+ * Returns current status
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Status (EAS_DATA_HANDLE easHandle, S_JET_STATUS *pStatus);
+
+/*----------------------------------------------------------------------------
+ * JET_GetEvent()
+ *----------------------------------------------------------------------------
+ * Checks for application events
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL JET_GetEvent (EAS_DATA_HANDLE easHandle, EAS_U32 *pEventRaw, S_JET_EVENT *pEvent);
+
+/*----------------------------------------------------------------------------
+ * JET_ParseEvent()
+ *----------------------------------------------------------------------------
+ * Returns current status
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC void JET_ParseEvent (EAS_U32 event, S_JET_EVENT *pEvent);
+
+/*----------------------------------------------------------------------------
+ * JET_QueueSegment()
+ *----------------------------------------------------------------------------
+ * Queue a segment for playback
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_QueueSegment (EAS_DATA_HANDLE easHandle, EAS_INT segmentNum, EAS_INT libNum, EAS_INT repeatCount, EAS_INT transpose, EAS_U32 muteFlags, EAS_U8 userID);
+
+/*----------------------------------------------------------------------------
+ * JET_Play()
+ *----------------------------------------------------------------------------
+ * Starts playback of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Play (EAS_DATA_HANDLE easHandle);
+
+/*----------------------------------------------------------------------------
+ * JET_Pause()
+ *----------------------------------------------------------------------------
+ * Pauses playback of the file
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Pause (EAS_DATA_HANDLE easHandle);
+
+/*----------------------------------------------------------------------------
+ * JET_SetMuteFlags()
+ *----------------------------------------------------------------------------
+ * Change the state of the mute flags
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_SetMuteFlags (EAS_DATA_HANDLE easHandle, EAS_U32 muteFlags, EAS_BOOL sync);
+
+/*----------------------------------------------------------------------------
+ * JET_SetMuteFlag()
+ *----------------------------------------------------------------------------
+ * Change the state of a single mute flag
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_SetMuteFlag (EAS_DATA_HANDLE easHandle, EAS_INT trackNum, EAS_BOOL muteFlag, EAS_BOOL sync);
+
+/*----------------------------------------------------------------------------
+ * JET_TriggerClip()
+ *----------------------------------------------------------------------------
+ * Unmute a track and then mute it when it is complete
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_TriggerClip (EAS_DATA_HANDLE easHandle, EAS_INT clipID);
+
+/*----------------------------------------------------------------------------
+ * JET_Clear_Queue()
+ *----------------------------------------------------------------------------
+ * Clears all segments in the queue
+ *----------------------------------------------------------------------------
+*/
+EAS_PUBLIC EAS_RESULT JET_Clear_Queue (EAS_DATA_HANDLE easHandle);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+
+#endif
+
diff --git a/arm-wt-22k/lib/libarm-wt-22k.a b/arm-wt-22k/lib/libarm-wt-22k.a
new file mode 100644
index 0000000..b130714
--- /dev/null
+++ b/arm-wt-22k/lib/libarm-wt-22k.a
Binary files differ
diff --git a/arm-wt-22k/lib_src/ARM-E_filter_gnu.s b/arm-wt-22k/lib_src/ARM-E_filter_gnu.s
new file mode 100644
index 0000000..871cd7d
--- /dev/null
+++ b/arm-wt-22k/lib_src/ARM-E_filter_gnu.s
@@ -0,0 +1,134 @@
+@***********************************************************
+@ Function: WT_VoiceFilter
+@ Processor: ARM
+@ Description:
+@ Implements a 2-pole low-pass filter with resonanance
+@
+@ Usage:
+@ void WT_VoiceFilter(
+@ S_FILTER CONTROL *pFilter,
+@ S_WT_FRAME *pWTFrame);
+@
+@ Copyright 2005 Sonic Network, Inc.
+@****************************************************************
+@ Revision Control:
+@ $Revision: 496 $
+@ $Date: 2006-12-11 14:33:26 -0800 (Mon, 11 Dec 2006) $
+@****************************************************************
+@
+@ where:
+@ S_FILTER_CONTROL *pFilter
+@ PASSED IN: r0
+@
+@ S_WT_FRAME *pWTFrame
+@ PASSED IN: r1
+@****************************************************************
+
+ .include "ARM_synth_constants_gnu.inc"
+
+ .arm
+ .text
+
+
+ .global WT_VoiceFilter
+
+
+@ Register usage
+@ --------------
+pFilter .req r0
+pWTFrame .req r1
+pBuffer .req r2
+numSamples .req r3
+
+z1 .req r4
+z2 .req r5
+b1 .req r6
+b2 .req r7
+K .req r8
+
+tmp0 .req r1 @ reuse register
+tmp1 .req r9
+tmp2 .req r10
+
+
+@SaveRegs RLIST {r4-r10, lr}
+@RestoreRegs RLIST {r4-r10, pc}
+
+
+ .func WT_VoiceFilter
+WT_VoiceFilter:
+
+ STMFD sp!, {r4-r10, lr}
+
+@
+@ Setup passed parameters in their destination registers
+@----------------------------------------------------------------
+
+ LDR pBuffer, [pWTFrame, #m_pAudioBuffer]
+ LDR numSamples, [pWTFrame, #m_numSamples]
+
+ @load state variables from pFilter structure
+ LDRSH z1, [pFilter, #m_z1]
+ LDRSH z2, [pFilter, #m_z2]
+
+ @load coefficients from pWTFrame structure
+ LDR K, [pWTFrame, #m_k]
+ LDR b1, [pWTFrame, #m_b1]
+ LDR b2, [pWTFrame, #m_b2]
+
+ RSB b1, b1, #0 @ b1 = -b1
+ RSB b2, b2, #0 @ b2 = -b2
+ MOV b2, b2, ASR #1 @ b2 = b2 >> 1
+ MOV K, K, ASR #1 @ K = K >> 1
+
+@
+@ Start processing
+@----------------------------------------------------------------
+
+ LDRSH tmp0, [pBuffer] @ fetch sample
+
+FilterLoop:
+ SMULBB tmp2, z1, b1 @ tmp2 = z1 * -b1
+ SMLABB tmp2, z2, b2, tmp2 @ tmp2 = (-b1 * z1) + (-b2 * z2)
+
+ MOV z2, z1 @ delay line
+
+ SMLABB tmp0, tmp0, K, tmp2 @ tmp1 = (K * x[n]) + (-b1 * z1) + (-b2 * z2)
+
+ LDRSH tmp1, [pBuffer, #NEXT_OUTPUT_PCM] @ fetch next sample
+
+ MOV z1, tmp0, ASR #14 @ shift result to low word
+ STRH z1, [pBuffer], #NEXT_OUTPUT_PCM @ write back to buffer
+
+ SMULBB tmp2, z1, b1 @ tmp2 = z1 * -b1
+
+ SUBS numSamples, numSamples, #2 @ unroll loop once
+
+ SMLABB tmp2, z2, b2, tmp2 @ tmp2 = (-b1 * z1) + (-b2 * z2)
+
+ SMLABB tmp1, tmp1, K, tmp2 @ tmp1 = (K * x[n]) + (-b1 * z1) + (-b2 * z2)
+
+ MOV z2, z1 @ delay line
+
+ MOV z1, tmp1, ASR #14 @ shift result to low word
+
+ LDRGTSH tmp0, [pBuffer, #NEXT_OUTPUT_PCM] @ fetch next sample
+
+ STRH z1, [pBuffer], #NEXT_OUTPUT_PCM @ write back to buffer
+
+ BGT FilterLoop
+@ save z terms
+@----------------------------------------------------------------
+
+ STRH z1, [pFilter, #m_z1]
+ STRH z2, [pFilter, #m_z2]
+
+@ Return to calling function
+@----------------------------------------------------------------
+
+ LDMFD sp!,{r4-r10, lr}
+ BX lr
+
+ .endfunc
+ .end
+
diff --git a/arm-wt-22k/lib_src/ARM-E_interpolate_loop_gnu.s b/arm-wt-22k/lib_src/ARM-E_interpolate_loop_gnu.s
new file mode 100644
index 0000000..847a7f0
--- /dev/null
+++ b/arm-wt-22k/lib_src/ARM-E_interpolate_loop_gnu.s
@@ -0,0 +1,131 @@
+@***********************************************************
+@ Function: WT_Interpolate
+@ Processor: ARM-E
+@ Description: the main synthesis function when fetching
+@ wavetable samples.
+@ C-callable.
+@
+@ Usage:
+@ void WT_Interpolate(
+@ S_WT_VOICE *pWTVoice,
+@ S_WT_FRAME *pWTFrame);
+@
+@ Copyright Sonic Network Inc. 2004
+@****************************************************************
+@ Revision Control:
+@ $Revision: 496 $
+@ $Date: 2006-12-11 14:33:26 -0800 (Mon, 11 Dec 2006) $
+@****************************************************************
+@
+@ where:
+@ S_WT_VOICE *pWTVoice
+@ PASSED IN: r0
+@
+@ S_WT_FRAME *pWTFrame;
+@ PASSED IN: r1
+@****************************************************************
+
+ .include "ARM_synth_constants_gnu.inc"
+
+ .arm
+ .text
+
+ .global WT_Interpolate
+
+
+@ Register usage
+@ --------------
+pWTVoice .req r0
+pWTFrame .req r1
+
+numSamples .req r2
+phaseIncrement .req r3
+pOutputBuffer .req r4
+
+tmp0 .req r1 @reuse register
+tmp1 .req r5
+tmp2 .req r6
+
+pLoopEnd .req r7
+pLoopStart .req r8
+
+pPhaseAccum .req r9
+phaseFrac .req r10
+phaseFracMask .req r11
+
+@SaveRegs RLIST {r4-r11,lr}
+@RestoreRegs RLIST {r4-r11,pc}
+
+ .func WT_Interpolate
+WT_Interpolate:
+
+ STMFD sp!,{r4-r11,lr}
+
+@
+@ Fetch parameters from structures
+@----------------------------------------------------------------
+
+ LDR pOutputBuffer, [pWTFrame, #m_pAudioBuffer]
+ LDR numSamples, [pWTFrame, #m_numSamples]
+
+ LDR phaseIncrement, [pWTFrame, #m_phaseIncrement]
+ LDR pPhaseAccum, [pWTVoice, #m_pPhaseAccum]
+ LDR phaseFrac, [pWTVoice, #m_phaseFrac]
+ LDR phaseFracMask,=PHASE_FRAC_MASK
+
+ LDR pLoopStart, [pWTVoice, #m_pLoopStart]
+ LDR pLoopEnd, [pWTVoice, #m_pLoopEnd]
+ ADD pLoopEnd, pLoopEnd, #1 @ need loop end to equal last sample + 1
+
+InterpolationLoop:
+ SUBS tmp0, pPhaseAccum, pLoopEnd @ check for loop end
+ ADDGE pPhaseAccum, pLoopStart, tmp0 @ loop back to start
+
+ .ifdef SAMPLES_8_BIT
+ LDRSB tmp0, [pPhaseAccum] @ tmp0 = x0
+ LDRSB tmp1, [pPhaseAccum, #1] @ tmp1 = x1
+ .else
+ LDRSH tmp0, [pPhaseAccum] @ tmp0 = x0
+ LDRSH tmp1, [pPhaseAccum, #2] @ tmp1 = x1
+ .endif
+
+ ADD tmp2, phaseIncrement, phaseFrac @ increment pointer here to avoid pipeline stall
+
+ SUB tmp1, tmp1, tmp0 @ tmp1 = x1 - x0
+ SMULBB tmp1, phaseFrac, tmp1 @ tmp1 = phaseFrac * tmp2
+
+@ This section performs a gain adjustment of -12dB for 16-bit samples
+@ or +36dB for 8-bit samples. For a high quality synthesizer, the output
+@ can be set to full scale, however if the filter is used, it can overflow
+@ with certain coefficients and signal sources. In this case, either a
+@ saturation operation should take in the filter before scaling back to
+@ 16 bits or the signal path should be increased to 18 bits or more.
+
+ .ifdef SAMPLES_8_BIT
+ MOV tmp0, tmp0, LSL #6 @ boost 8-bit signal by 36dB
+ .else
+ MOV tmp0, tmp0, ASR #2 @ reduce 16-bit signal by 12dB
+ .endif
+
+ ADD tmp1, tmp0, tmp1, ASR #(NUM_EG1_FRAC_BITS-6) @ tmp1 = tmp0 + (tmp1 >> (15-6))
+ @ = x0 + f * (x1 - x0) == interpolated result
+
+ STRH tmp1, [pOutputBuffer], #NEXT_OUTPUT_PCM @ *pOutputBuffer++ = interpolated result
+
+@ carry overflow from fraction to integer portion
+ ADD pPhaseAccum, pPhaseAccum, tmp2, LSR #(NUM_PHASE_FRAC_BITS - NEXT_INPUT_PCM_SHIFT)
+ AND phaseFrac, tmp2, phaseFracMask @ nphaseFrac = frac part
+
+ SUBS numSamples, numSamples, #1
+ BGT InterpolationLoop
+
+@ update and store phase
+ STR pPhaseAccum, [pWTVoice, #m_pPhaseAccum]
+ STR phaseFrac, [pWTVoice, #m_phaseFrac]
+
+ LDMFD sp!,{r4-r11,lr}
+ BX lr
+
+ .endfunc
+ .end
+
diff --git a/arm-wt-22k/lib_src/ARM-E_interpolate_noloop_gnu.s b/arm-wt-22k/lib_src/ARM-E_interpolate_noloop_gnu.s
new file mode 100644
index 0000000..6343762
--- /dev/null
+++ b/arm-wt-22k/lib_src/ARM-E_interpolate_noloop_gnu.s
@@ -0,0 +1,130 @@
+@***********************************************************
+@ Function: WT_InterpolateNoLoop
+@ Processor: ARM-E
+@ Description: the main synthesis function when fetching
+@ wavetable samples.
+@ C-callable.
+@
+@ Usage:
+@ void WT_InterpolateNoLoop(
+@ S_WT_VOICE *pWTVoice,
+@ S_WT_FRAME *pWTFrame);
+@
+@ Copyright Sonic Network Inc. 2004
+@****************************************************************
+@ Revision Control:
+@ $Revision: 496 $
+@ $Date: 2006-12-11 14:33:26 -0800 (Mon, 11 Dec 2006) $
+@****************************************************************
+@
+@ where:
+@ S_WT_VOICE *pWTVoice
+@ PASSED IN: r0
+@
+@ S_WT_FRAME *pWTFrame;
+@ PASSED IN: r1
+@****************************************************************
+
+ .include "ARM_synth_constants_gnu.inc"
+
+ .arm
+ .text
+
+
+ .global WT_InterpolateNoLoop
+
+
+@ Register usage
+@ --------------
+pWTVoice .req r0
+pWTFrame .req r1
+pOutputBuffer .req r2
+numSamples .req r3
+
+phaseIncrement .req r4
+pPhaseAccum .req r5
+phaseFrac .req r6
+phaseFracMask .req r7
+
+tmp0 .req r1 @ reuse register
+tmp1 .req r8
+tmp2 .req r9
+
+
+@SaveRegs RLIST {r4-r9,lr}
+@RestoreRegs RLIST {r4-r9,pc}
+
+ .func WT_InterpolateNoLoop
+WT_InterpolateNoLoop:
+
+ STMFD sp!, {r4-r9,lr}
+
+@
+@ Fetch parameters from structures
+@----------------------------------------------------------------
+
+ LDR pOutputBuffer, [pWTFrame, #m_pAudioBuffer]
+ LDR numSamples, [pWTFrame, #m_numSamples]
+
+ LDR phaseIncrement, [pWTFrame, #m_phaseIncrement]
+ LDR pPhaseAccum, [pWTVoice, #m_pPhaseAccum]
+ LDR phaseFrac, [pWTVoice, #m_phaseFrac]
+ LDR phaseFracMask,=PHASE_FRAC_MASK
+
+InterpolationLoop:
+
+ .ifdef SAMPLES_8_BIT
+ LDRSB tmp0, [pPhaseAccum] @ tmp0 = x0
+ LDRSB tmp1, [pPhaseAccum, #1] @ tmp1 = x1
+ .else
+ LDRSH tmp0, [pPhaseAccum] @ tmp0 = x0
+ LDRSH tmp1, [pPhaseAccum, #2] @ tmp1 = x1
+ .endif
+
+ ADD tmp2, phaseIncrement, phaseFrac @ increment pointer here to avoid pipeline stall
+
+ SUB tmp1, tmp1, tmp0 @ tmp1 = x1 - x0
+ SMULBB tmp1, phaseFrac, tmp1 @ tmp1 = phaseFrac * tmp2
+
+@ This section performs a gain adjustment of -12dB for 16-bit samples
+@ or +36dB for 8-bit samples. For a high quality synthesizer, the output
+@ can be set to full scale, however if the filter is used, it can overflow
+@ with certain coefficients and signal sources. In this case, either a
+@ saturation operation should take in the filter before scaling back to
+@ 16 bits or the signal path should be increased to 18 bits or more.
+
+ .ifdef SAMPLES_8_BIT
+ MOV tmp0, tmp0, LSL #6 @ boost 8-bit signal by 36dB
+ .else
+ MOV tmp0, tmp0, ASR #2 @ reduce 16-bit signal by 12dB
+ .endif
+
+ ADD tmp1, tmp0, tmp1, ASR #(NUM_EG1_FRAC_BITS-6) @ tmp1 = tmp0 + (tmp1 >> (15-6))
+ @ = x0 + f * (x1 - x0) == interpolated result
+
+ STRH tmp1, [pOutputBuffer], #NEXT_OUTPUT_PCM @ *pOutputBuffer++ = interpolated result
+
+@ carry overflow from fraction to integer portion
+ ADD pPhaseAccum, pPhaseAccum, tmp2, LSR #(NUM_PHASE_FRAC_BITS - NEXT_INPUT_PCM_SHIFT)
+ AND phaseFrac, tmp2, phaseFracMask @ nphaseFrac = frac part
+
+ SUBS numSamples, numSamples, #1
+ BGT InterpolationLoop
+
+@ Clean up and store any changes that were caused during the loop
+@----------------------------------------------------------------
+
+ @ update and store phase
+ STR pPhaseAccum, [pWTVoice, #m_pPhaseAccum]
+ STR phaseFrac, [pWTVoice, #m_phaseFrac]
+
+@
+@ Return to calling function
+@----------------------------------------------------------------
+
+ LDMFD sp!,{r4-r9,lr}
+ BX lr
+
+ .endfunc
+ .end
+
diff --git a/arm-wt-22k/lib_src/ARM-E_mastergain_gnu.s b/arm-wt-22k/lib_src/ARM-E_mastergain_gnu.s
new file mode 100644
index 0000000..b4e905b
--- /dev/null
+++ b/arm-wt-22k/lib_src/ARM-E_mastergain_gnu.s
@@ -0,0 +1,109 @@
+@***********************************************************
+@ Function: SynthMasterGain
+@ Processor: ARM-E
+@ Description: Copies 32-bit synth output to 16-bit buffer
+@ with saturated gain control
+@ C-callable.
+@
+@ Usage:
+@ SynthMasterGain(
+@ pInputBuffer
+@ pOutputBuffer,
+@ nGain,
+@ nNumLoopSamples
+@ );
+@
+@ Copyright Sonic Network Inc. 2004
+@****************************************************************
+@ Revision Control:
+@ $Revision: 496 $
+@ $Date: 2006-12-11 14:33:26 -0800 (Mon, 11 Dec 2006) $
+@****************************************************************
+@
+@ where:
+@ long *pInputBuffer
+@ PASSED IN: r0
+@
+@ EAS_PCM *pOutputBuffer
+@ PASSED IN: r1
+@
+@ short nGain
+@ PASSED IN: r2
+@
+@ EAS_U16 nNumLoopSamples
+@ PASSED IN: r3
+@
+@****************************************************************
+
+ .include "ARM_synth_constants_gnu.inc"
+
+ .arm
+ .text
+
+ .func SynthMasterGain
+SynthMasterGain:
+
+ .global SynthMasterGain @ allow other files to use this function
+
+
+
+
+
+@ Stack frame
+@ -----------
+ .equ RET_ADDR_SZ, 0 @return address
+ .equ REG_SAVE_SZ, 0 @save-on-entry registers saved
+ .equ FRAME_SZ, (8) @local variables
+ .equ ARG_BLK_SZ, 0 @argument block
+
+ .equ PARAM_OFFSET, (ARG_BLK_SZ + FRAME_SZ + REG_SAVE_SZ + RET_ADDR_SZ)
+
+@ Register usage
+@ --------------
+pnInputBuffer .req r0
+pnOutputBuffer .req r1
+nGain .req r2
+nNumLoopSamples .req r3
+
+ STMFD sp!,{r4-r6,r14} @Save any save-on-entry registers that are used
+
+ LDR r6, =0x7fff @constant for saturation tests
+
+loop:
+ LDR r4, [pnInputBuffer], #4 @fetch 1st output sample
+
+ LDR r5, [pnInputBuffer], #4 @fetch 2nd output sample
+
+ SMULWB r4, r4, nGain @output = gain * input
+
+ CMP r4, r6 @check for positive saturation
+ MOVGT r4, r6 @saturate
+ CMN r4, r6 @check for negative saturation
+ MVNLT r4, r6 @saturate
+
+ SMULWB r5, r5, nGain @output = gain * input
+
+ STRH r4, [pnOutputBuffer], #NEXT_OUTPUT_PCM @save 1st output sample
+
+ CMP r5, r6 @check for positive saturation
+ MOVGT r5, r6 @saturate
+ CMN r5, r6 @check for negative saturation
+ MVNLT r5, r6 @saturate
+ STRH r5, [pnOutputBuffer], #NEXT_OUTPUT_PCM @save 2nd output sample
+
+ SUBS nNumLoopSamples, nNumLoopSamples, #2
+ BGT loop
+
+@
+@ Return to calling function
+@----------------------------------------------------------------
+
+ LDMFD sp!,{r4-r6, lr} @ return to calling function
+ BX lr
+
+@*****************************************************************************
+
+ .endfunc @ end of function/procedure
+
+ .end @ end of assembly code
+
diff --git a/arm-wt-22k/lib_src/ARM-E_voice_gain_gnu.s b/arm-wt-22k/lib_src/ARM-E_voice_gain_gnu.s
new file mode 100644
index 0000000..4517a3d
--- /dev/null
+++ b/arm-wt-22k/lib_src/ARM-E_voice_gain_gnu.s
@@ -0,0 +1,166 @@
+@***********************************************************
+@ Function: WT_VoiceGain
+@ Processor: ARM-E
+@ Description: the main synthesis function when fetching
+@ wavetable samples.
+@ C-callable.
+@
+@ Usage:
+@ Usage:
+@ WT_VoiceGain(
+@ S_WT_VOICE *pWTVoice,
+@ S_WT_FRAME *pWTFrame);
+@
+@ Copyright 2004, 2005 Sonic Network, Inc.
+@****************************************************************
+@ Revision Control:
+@ $Revision: 814 $
+@ $Date: 2007-08-02 10:34:53 -0700 (Thu, 02 Aug 2007) $
+@****************************************************************
+@
+@ where:
+@ S_WT_VOICE *psVoice
+@ PASSED IN: r0
+@
+@ S_WT_FRAME *pWTFrame
+@ PASSED IN: r1
+@****************************************************************
+
+
+
+ .include "ARM_synth_constants_gnu.inc"
+
+ .arm
+ .text
+
+ .global WT_VoiceGain
+
+@ Register usage
+@ --------------
+pWTVoice .req r0
+pWTFrame .req r1
+pInputBuffer .req r2
+pMixBuffer .req r3
+
+tmp0 .req r4
+tmp1 .req r5
+tmp2 .req r1 @ reuse register
+tmp3 .req r6
+
+numSamples .req r9
+
+ .if STEREO_OUTPUT
+gainIncLeft .req r7
+gainIncRight .req r8
+gainLeft .req r10
+gainRight .req r11
+ .else
+gainIncrement .req r7
+gain .req r8
+ .endif
+
+
+@ register context for local variables
+@SaveRegs RLIST {r4-r11,lr}
+@RestoreRegs RLIST {r4-r11,pc}
+
+ .func WT_VoiceGain
+WT_VoiceGain:
+
+ STMFD sp!, {r4-r11,lr}
+
+ LDR pInputBuffer, [pWTFrame, #m_pAudioBuffer]
+ LDR pMixBuffer, [pWTFrame, #m_pMixBuffer]
+ LDR numSamples, [pWTFrame, #m_numSamples]
+
+@----------------------------------------------------------------
+@ Stereo version
+@----------------------------------------------------------------
+@ NOTE: instructions are reordered to reduce the effect of latency
+@ due to storage and computational dependencies.
+@----------------------------------------------------------------
+
+ .if STEREO_OUTPUT
+
+ LDR tmp0, [pWTFrame, #m_prevGain]
+ LDR tmp1, [pWTFrame, #m_gainTarget]
+
+ LDRSH gainLeft, [pWTVoice, #m_gainLeft]
+ LDRSH gainRight, [pWTVoice, #m_gainRight]
+
+ MOV gainIncLeft, gainLeft
+ SMULBB gainLeft, tmp0, gainLeft
+
+ SMULBB gainIncLeft, tmp1, gainIncLeft
+ SUB gainIncLeft, gainIncLeft, gainLeft
+ MOV gainLeft, gainLeft, ASR #(NUM_MIXER_GUARD_BITS - 2)
+ MOV gainIncLeft, gainIncLeft, ASR #(SYNTH_UPDATE_PERIOD_IN_BITS + NUM_MIXER_GUARD_BITS - 2)
+
+ MOV gainIncRight, gainRight
+ SMULBB gainRight, tmp0, gainRight
+
+ SMULBB gainIncRight, tmp1, gainIncRight
+ SUB gainIncRight, gainIncRight, gainRight
+ MOV gainRight, gainRight, ASR #(NUM_MIXER_GUARD_BITS - 2)
+ MOV gainIncRight, gainIncRight, ASR #(SYNTH_UPDATE_PERIOD_IN_BITS + NUM_MIXER_GUARD_BITS - 2)
+
+ LDRSH tmp0, [pInputBuffer], #2
+
+StereoGainLoop:
+ LDR tmp1, [pMixBuffer]
+
+ ADD gainLeft, gainLeft, gainIncLeft
+
+ SMLAWB tmp1, gainLeft, tmp0, tmp1
+
+ LDR tmp2, [pMixBuffer, #4]
+
+ ADD gainRight, gainRight, gainIncRight
+
+ STR tmp1, [pMixBuffer], #4
+
+ SMLAWB tmp2, gainRight, tmp0, tmp2
+
+ SUBS numSamples, numSamples, #1
+
+ LDRGTSH tmp0, [pInputBuffer], #2
+
+ STR tmp2, [pMixBuffer], #4
+
+ BGT StereoGainLoop
+
+@----------------------------------------------------------------
+@ Mono version
+@----------------------------------------------------------------
+ .else
+
+ LDR gain, [pWTFrame, #m_prevGain]
+ MOV gain, gain, LSL #(NUM_MIXER_GUARD_BITS + 4)
+ LDR gainIncrement, [pWTFrame, #m_gainTarget]
+ MOV gainIncrement, gainIncrement, LSL #(NUM_MIXER_GUARD_BITS + 4)
+ SUB gainIncrement, gainIncrement, gain
+ MOV gainIncrement, gainIncrement, ASR #SYNTH_UPDATE_PERIOD_IN_BITS
+
+MonoGainLoop:
+
+ LDRSH tmp0, [pInputBuffer], #NEXT_OUTPUT_PCM @ fetch voice output
+
+ LDR tmp1, [pMixBuffer] @ get left channel output sample
+ ADD gain, gain, gainIncrement @ gain step to eliminate zipper noise
+ SMULWB tmp0, gain, tmp0 @ sample * local gain
+
+ MOV tmp0, tmp0, ASR #1 @ add 6dB headroom
+ ADD tmp1, tmp0, tmp1
+ STR tmp1, [pMixBuffer], #4 @ save and bump pointer
+
+ SUBS numSamples, numSamples, #1
+ BGT MonoGainLoop
+
+ .endif @end Mono version
+
+ LDMFD sp!,{r4-r11,lr}
+ BX lr
+
+ .endfunc
+ .end
+
diff --git a/arm-wt-22k/lib_src/ARM_synth_constants_gnu.inc b/arm-wt-22k/lib_src/ARM_synth_constants_gnu.inc
new file mode 100644
index 0000000..b4cd29a
--- /dev/null
+++ b/arm-wt-22k/lib_src/ARM_synth_constants_gnu.inc
@@ -0,0 +1,153 @@
+@***********************************************************
+@ File: ARM_synth_constants.inc
+@ Processor: ARM
+@ Description: Contains constants and defines, most of which
+@ are mirrored in synth.h
+@
+@ Copyright Sonic Network Inc. 2004
+@****************************************************************
+@ Revision Control:
+@ $Revision: 741 $
+@ $Date: 2007-06-22 16:39:21 -0700 (Fri, 22 Jun 2007) $
+@****************************************************************
+
+
+ .ifdef SAMPLE_RATE_8000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 5
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 32
+ .endif
+
+ .ifdef SAMPLE_RATE_16000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 6
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 64
+ .endif
+
+ .ifdef SAMPLE_RATE_20000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_22050
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_24000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_32000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
+ .endif
+
+ .ifdef SAMPLE_RATE_44100
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
+ .endif
+
+ .ifdef SAMPLE_RATE_48000
+ .equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
+ .equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
+ .endif
+
+
+@ if the OUTPUT PCM sample is 16-bits, then when using indexed addressing,
+@ the next sample is this many bytes away
+ .equ NEXT_OUTPUT_PCM, 2
+
+@****************************************************************************
+@/* macros for fractional phase accumulator */
+ .equ NUM_PHASE_FRAC_BITS, 15
+
+ .equ PHASE_FRAC_MASK, 0x7FFF
+
+@ shift for phase accumulator when fraction carries over
+ .ifdef SAMPLES_8_BIT
+ .equ NEXT_INPUT_PCM_SHIFT, 0
+ .endif
+
+ .ifdef SAMPLES_16_BIT
+ .equ NEXT_INPUT_PCM_SHIFT, 1
+ .endif
+
+@****************************************************************************
+ .equ NUM_MIXER_GUARD_BITS, 4
+
+@****************************************************************************
+@/* Envelope 1 (EG1) calculation macros */
+ .equ NUM_EG1_FRAC_BITS, 15
+
+@****************************************************************************
+
+ .equ NUM_ENHANCER_FILTER_COEF_FRAC_BITS, 5
+
+@****************************************************************************
+
+@
+@ I've temporarily given up on the idea of getting ADS/RV and gcc to
+@ handle a struct in a compatible fashion. Switching to old fashion EQU
+@
+
+ .if FILTER_ENABLED
+@**************************************
+@ typedef struct s_filter_tag
+ .equ m_z1, 0
+ .equ m_z2, 2
+ .endif
+
+@**************************************
+@ typedef struct s_wt_frame_tag
+ .equ m_gainTarget, 0
+ .equ m_phaseIncrement, 4
+
+ .if FILTER_ENABLED
+ .equ m_k, 8
+ .equ m_b1, 12
+ .equ m_b2, 16
+ .equ m_pAudioBuffer, 20
+ .equ m_pMixBuffer, 24
+ .equ m_numSamples, 28
+ .equ m_prevGain, 32
+ .else
+ .equ m_pAudioBuffer, 8
+ .equ m_pMixBuffer, 12
+ .equ m_numSamples, 16
+ .equ m_prevGain, 20
+ .endif
+
+
+@**************************************
+@ typedef struct s_wt_voice_tag
+ .equ m_pLoopEnd, 0 @ /* points to last PCM sample (not 1 beyond last) */
+ .equ m_pLoopStart, 4 @ /* points to first sample at start of loop */
+ .equ m_pPhaseAccum, 8 @ /* points to first sample at start of loop */
+ .equ m_phaseFrac, 12 @ /* points to first sample at start of loop */
+
+ .if STEREO_OUTPUT
+ .equ m_gainLeft, 16 @ /* current gain, left ch */
+ .equ m_gainRight, 18 @ /* current gain, right ch */
+ .endif
+
+
+@****************************************************************************
+@ enhancer
+ .equ m_nEnhancerFeedForward1, 0
+ .equ m_nEnhancerFeedback1, 1
+ .equ m_nDriveCoef, 2
+ .equ m_nEnhancerFeedback2, 3
+ .equ m_nWet, 4
+ .equ m_nDry, 5
+
+ .equ m_zF0L, 6 @ filter 1 zero state var, left
+ .equ m_zF1L, 8 @ filter 1 pole state var, left
+ .equ m_zF2L, 10 @ filter 2 zero state var, left
+ .equ m_zF0R, 12 @ filter 1 zero state var, right
+ .equ m_zF1R, 14 @ filter 1 pole state var, right
+ .equ m_zF2R, 16 @ filter 2 zero state var, right
+
+@****************************************************************************
+
+
+
diff --git a/arm-wt-22k/lib_src/arm-wt-22k_lib.mak b/arm-wt-22k/lib_src/arm-wt-22k_lib.mak
new file mode 100644
index 0000000..8e9824f
--- /dev/null
+++ b/arm-wt-22k/lib_src/arm-wt-22k_lib.mak
@@ -0,0 +1,25 @@
+#
+# Auto-generated sample makefile
+#
+# This makefile is intended for use with GNU make.
+# Set the paths to the tools (CC, AR, LD, etc.)
+#
+
+vpath %.c lib_src
+
+CC = C:\Program Files\GNUARM\bin\arm-elf-gcc.exe
+AS = C:\Program Files\GNUARM\bin\arm-elf-as.exe
+LD = C:\Program Files\GNUARM\bin\arm-elf-gcc.exe
+AR = C:\Program Files\GNUARM\bin\arm-elf-ar.exe
+
+%.o: %.c
+ $(CC) -c -O2 -o $@ -I lib_src -I host_src -D NUM_OUTPUT_CHANNELS=2 -D _SAMPLE_RATE_22050 -D MAX_SYNTH_VOICES=64 -D EAS_WT_SYNTH -D _8_BIT_SAMPLES -D _FILTER_ENABLED -D _IMELODY_PARSER -D _RTTTL_PARSER -D _OTA_PARSER -D _XMF_PARSER -D _WAVE_PARSER -D _REVERB_ENABLED -D _CHORUS_ENABLED -D DLS_SYNTHESIZER -D _IMA_DECODER -D MMAPI_SUPPORT -D NATIVE_EAS_KERNEL -D JET_INTERFACE $<
+
+%.o: %.s
+ $(AS) -o $@ -EL -mcpu=arm946e-s -mfpu=softfpa -I lib_src --defsym CHECK_STACK=0 --defsym REVERB=0 --defsym CHORUS=0 --defsym STEREO_OUTPUT=1 --defsym SAMPLE_RATE_22050=1 --defsym SAMPLES_8_BIT=1 --defsym FILTER_ENABLED=1 $<
+
+OBJS = eas_mididata.o eas_pan.o eas_wavefiledata.o eas_imelody.o eas_xmfdata.o ARM-E_interpolate_noloop_gnu.o eas_chorusdata.o ARM-E_voice_gain_gnu.o eas_ota.o eas_reverbdata.o eas_rtttl.o eas_reverb.o jet.o eas_mdls.o eas_mixbuf.o eas_smf.o eas_tcdata.o eas_chorus.o eas_pcmdata.o eas_xmf.o eas_smfdata.o eas_math.o eas_tonecontrol.o eas_rtttldata.o eas_voicemgt.o eas_public.o eas_dlssynth.o ARM-E_interpolate_loop_gnu.o ARM-E_filter_gnu.o eas_midi.o eas_otadata.o eas_flog.o eas_wtengine.o eas_imaadpcm.o eas_wtsynth.o wt_22khz.o eas_pcm.o eas_mixer.o eas_wavefile.o eas_ima_tables.o eas_data.o ARM-E_mastergain_gnu.o eas_imelodydata.o
+
+arm-wt-22k.a: $(OBJS)
+ $(AR) rc lib$@ $(OBJS)
+
diff --git a/arm-wt-22k/lib_src/dls.h b/arm-wt-22k/lib_src/dls.h
new file mode 100644
index 0000000..ca1d4c7
--- /dev/null
+++ b/arm-wt-22k/lib_src/dls.h
@@ -0,0 +1,268 @@
+ /*
+
+ dls.h
+
+ Description:
+
+ Interface defines and structures for the Instrument Collection Form
+ RIFF DLS.
+
+ Written by Sonic Foundry 1996. Released for public use.
+
+ */
+
+ #ifndef _INC_DLS
+ #define _INC_DLS
+
+ /*
+
+ Layout of an instrument collection:
+
+
+ RIFF [] 'DLS ' [colh,INSTLIST,WAVEPOOL,INFOLIST]
+
+ INSTLIST
+ LIST [] 'lins'
+ LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST]
+ LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST]
+ LIST [] 'ins ' [insh,RGNLIST,ARTLIST,INFOLIST]
+
+ RGNLIST
+ LIST [] 'lrgn'
+ LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST]
+ LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST]
+ LIST [] 'rgn ' [rgnh,wsmp,wlnk,ARTLIST]
+
+ ARTLIST
+ LIST [] 'lart'
+ 'art1' level 1 Articulation connection graph
+ 'art2' level 2 Articulation connection graph
+ '3rd1' Possible 3rd party articulation structure 1
+ '3rd2' Possible 3rd party articulation structure 2 .... and so on
+
+ WAVEPOOL
+ ptbl [] [pool table]
+ LIST [] 'wvpl'
+ [path],
+ [path],
+ LIST [] 'wave',RIFFWAVE
+ LIST [] 'wave',RIFFWAVE
+ LIST [] 'wave',RIFFWAVE
+ LIST [] 'wave',RIFFWAVE
+ LIST [] 'wave',RIFFWAVE
+
+ INFOLIST
+ LIST [] 'INFO'
+ 'icmt' 'One of those crazy comments.'
+ 'icop' 'Copyright (C) 1996 Sonic Foundry'
+
+ */
+
+
+ /*
+ FOURCC's used in the DLS file
+ */
+/* shree */
+//#define FAR
+
+/* shree
+
+ #define FOURCC_DLS mmioFOURCC('D','L','S',' ')
+ #define FOURCC_COLH mmioFOURCC('c','o','l','h')
+ #define FOURCC_WVPL mmioFOURCC('w','v','p','l')
+ #define FOURCC_PTBL mmioFOURCC('p','t','b','l')
+ #define FOURCC_PATH mmioFOURCC('p','a','t','h')
+ #define FOURCC_wave mmioFOURCC('w','a','v','e')
+ #define FOURCC_LINS mmioFOURCC('l','i','n','s')
+ #define FOURCC_INS mmioFOURCC('i','n','s',' ')
+ #define FOURCC_INSH mmioFOURCC('i','n','s','h')
+ #define FOURCC_LRGN mmioFOURCC('l','r','g','n')
+ #define FOURCC_RGN mmioFOURCC('r','g','n',' ')
+ #define FOURCC_RGNH mmioFOURCC('r','g','n','h')
+ #define FOURCC_LART mmioFOURCC('l','a','r','t')
+ #define FOURCC_ART1 mmioFOURCC('a','r','t','1')
+ #define FOURCC_WLNK mmioFOURCC('w','l','n','k')
+ #define FOURCC_WSMP mmioFOURCC('w','s','m','p')
+ #define FOURCC_VERS mmioFOURCC('v','e','r','s')
+*/
+ /*
+ Articulation connection graph definitions
+ */
+
+ /* Generic Sources */
+ #define CONN_SRC_NONE 0x0000
+ #define CONN_SRC_LFO 0x0001
+ #define CONN_SRC_KEYONVELOCITY 0x0002
+ #define CONN_SRC_KEYNUMBER 0x0003
+ #define CONN_SRC_EG1 0x0004
+ #define CONN_SRC_EG2 0x0005
+ #define CONN_SRC_PITCHWHEEL 0x0006
+
+ /* Midi Controllers 0-127 */
+ #define CONN_SRC_CC1 0x0081
+ #define CONN_SRC_CC7 0x0087
+ #define CONN_SRC_CC10 0x008a
+ #define CONN_SRC_CC11 0x008b
+
+ /* Registered Parameter Numbers */
+ #define CONN_SRC_RPN0 0x0100
+ #define CONN_SRC_RPN1 0x0101
+ #define CONN_SRC_RPN2 0x0102
+
+ /* Generic Destinations */
+ #define CONN_DST_NONE 0x0000
+ #define CONN_DST_ATTENUATION 0x0001
+ #define CONN_DST_RESERVED 0x0002
+ #define CONN_DST_PITCH 0x0003
+ #define CONN_DST_PAN 0x0004
+
+ /* LFO Destinations */
+ #define CONN_DST_LFO_FREQUENCY 0x0104
+ #define CONN_DST_LFO_STARTDELAY 0x0105
+
+ /* EG1 Destinations */
+ #define CONN_DST_EG1_ATTACKTIME 0x0206
+ #define CONN_DST_EG1_DECAYTIME 0x0207
+ #define CONN_DST_EG1_RESERVED 0x0208
+ #define CONN_DST_EG1_RELEASETIME 0x0209
+ #define CONN_DST_EG1_SUSTAINLEVEL 0x020a
+
+ /* EG2 Destinations */
+ #define CONN_DST_EG2_ATTACKTIME 0x030a
+ #define CONN_DST_EG2_DECAYTIME 0x030b
+ #define CONN_DST_EG2_RESERVED 0x030c
+ #define CONN_DST_EG2_RELEASETIME 0x030d
+ #define CONN_DST_EG2_SUSTAINLEVEL 0x030e
+
+ #define CONN_TRN_NONE 0x0000
+ #define CONN_TRN_CONCAVE 0x0001
+
+ typedef struct _DLSVERSION {
+ DWORD dwVersionMS;
+ DWORD dwVersionLS;
+ }DLSVERSION, FAR *LPDLSVERSION;
+
+
+ typedef struct _CONNECTION {
+ USHORT usSource;
+ USHORT usControl;
+ USHORT usDestination;
+ USHORT usTransform;
+ LONG lScale;
+ }CONNECTION, FAR *LPCONNECTION;
+
+
+ /* Level 1 Articulation Data */
+
+ typedef struct _CONNECTIONLIST {
+ ULONG cbSize; /* size of the connection list structure */
+ ULONG cConnections; /* count of connections in the list */
+ } CONNECTIONLIST, FAR *LPCONNECTIONLIST;
+
+
+
+ /*
+ Generic type defines for regions and instruments
+ */
+
+ typedef struct _RGNRANGE {
+ USHORT usLow;
+ USHORT usHigh;
+ }RGNRANGE, FAR * LPRGNRANGE;
+
+ #define F_INSTRUMENT_DRUMS 0x80000000
+
+ typedef struct _MIDILOCALE {
+ ULONG ulBank;
+ ULONG ulInstrument;
+ }MIDILOCALE, FAR *LPMIDILOCALE;
+
+ /*
+ Header structures found in an DLS file for collection, instruments, and
+ regions.
+ */
+
+ #define F_RGN_OPTION_SELFNONEXCLUSIVE 0x0001
+
+ typedef struct _RGNHEADER {
+ RGNRANGE RangeKey; /* Key range */
+ RGNRANGE RangeVelocity; /* Velocity Range */
+ USHORT fusOptions; /* Synthesis options for this range */
+ USHORT usKeyGroup; /* Key grouping for non simultaneous play
+ 0 = no group, 1 up is group
+ for Level 1 only groups 1-15 are allowed */
+ }RGNHEADER, FAR *LPRGNHEADER;
+
+ typedef struct _INSTHEADER {
+ ULONG cRegions; /* Count of regions in this instrument */
+ MIDILOCALE Locale; /* Intended MIDI locale of this instrument */
+ }INSTHEADER, FAR *LPINSTHEADER;
+
+ typedef struct _DLSHEADER {
+ ULONG cInstruments; /* Count of instruments in the collection */
+ }DLSHEADER, FAR *LPDLSHEADER;
+
+ /*
+ definitions for the Wave link structure
+ */
+
+ /***** For level 1 only WAVELINK_CHANNEL_MONO is valid ****
+ ulChannel allows for up to 32 channels of audio with each bit position
+ specifiying a channel of playback */
+
+ #define WAVELINK_CHANNEL_LEFT 0x0001
+ #define WAVELINK_CHANNEL_RIGHT 0x0002
+
+ #define F_WAVELINK_PHASE_MASTER 0x0001
+
+ typedef struct _WAVELINK { /* any paths or links are stored right after struct */
+ USHORT fusOptions; /* options flags for this wave */
+ USHORT usPhaseGroup; /* Phase grouping for locking channels */
+ ULONG ulChannel; /* channel placement */
+ ULONG ulTableIndex; /* index into the wave pool table, 0 based */
+ }WAVELINK, FAR *LPWAVELINK;
+
+ #define POOL_CUE_NULL 0xffffffff
+
+ typedef struct _POOLCUE {
+ // ULONG ulEntryIndex; /* Index entry in the list */
+ ULONG ulOffset; /* Offset to the entry in the list */
+ }POOLCUE, FAR *LPPOOLCUE;
+
+ typedef struct _POOLTABLE {
+ ULONG cbSize; /* size of the pool table structure */
+ ULONG cCues; /* count of cues in the list */
+ } POOLTABLE, FAR *LPPOOLTABLE;
+
+ /*
+ Structures for the "wsmp" chunk
+ */
+
+ #define F_WSMP_NO_TRUNCATION 0x0001
+ #define F_WSMP_NO_COMPRESSION 0x0002
+
+
+ typedef struct _rwsmp {
+ ULONG cbSize;
+ USHORT usUnityNote; /* MIDI Unity Playback Note */
+ SHORT sFineTune; /* Fine Tune in log tuning */
+ LONG lAttenuation; /* Overall Attenuation to be applied to data */
+ ULONG fulOptions; /* Flag options */
+ ULONG cSampleLoops; /* Count of Sample loops, 0 loops is one shot */
+ } WSMPL, FAR *LPWSMPL;
+
+
+ /* This loop type is a normal forward playing loop which is continually
+ played until the envelope reaches an off threshold in the release
+ portion of the volume envelope */
+
+ #define WLOOP_TYPE_FORWARD 0
+
+ typedef struct _rloop {
+ ULONG cbSize;
+ ULONG ulType; /* Loop Type */
+ ULONG ulStart; /* Start of loop in samples */
+ ULONG ulLength; /* Length of loop in samples */
+ } WLOOP, FAR *LPWLOOP;
+
+ #endif /* _INC_DLS */
diff --git a/arm-wt-22k/lib_src/dls2.h b/arm-wt-22k/lib_src/dls2.h
new file mode 100644
index 0000000..17d6efd
--- /dev/null
+++ b/arm-wt-22k/lib_src/dls2.h
@@ -0,0 +1,122 @@
+/*
+
+ dls2.h
+
+ Description:
+
+ Interface defines and structures for the DLS2 extensions of DLS.
+
+
+ Written by Microsoft 1998. Released for public use.
+
+*/
+
+#ifndef _INC_DLS2
+#define _INC_DLS2
+
+/*
+ FOURCC's used in the DLS2 file, in addition to DLS1 chunks
+*/
+
+#define FOURCC_RGN2 mmioFOURCC('r','g','n','2')
+#define FOURCC_LAR2 mmioFOURCC('l','a','r','2')
+#define FOURCC_ART2 mmioFOURCC('a','r','t','2')
+#define FOURCC_CDL mmioFOURCC('c','d','l',' ')
+#define FOURCC_DLID mmioFOURCC('d','l','i','d')
+
+/*
+ Articulation connection graph definitions. These are in addition to
+ the definitions in the DLS1 header.
+*/
+
+/* Generic Sources (in addition to DLS1 sources. */
+#define CONN_SRC_POLYPRESSURE 0x0007 /* Polyphonic Pressure */
+#define CONN_SRC_CHANNELPRESSURE 0x0008 /* Channel Pressure */
+#define CONN_SRC_VIBRATO 0x0009 /* Vibrato LFO */
+#define CONN_SRC_MONOPRESSURE 0x000a /* MIDI Mono pressure */
+
+
+/* Midi Controllers */
+#define CONN_SRC_CC91 0x00db /* Reverb Send */
+#define CONN_SRC_CC93 0x00dd /* Chorus Send */
+
+
+/* Generic Destinations */
+#define CONN_DST_GAIN 0x0001 /* Same as CONN_DST_ ATTENUATION, but more appropriate terminology. */
+#define CONN_DST_KEYNUMBER 0x0005 /* Key Number Generator */
+
+/* Audio Channel Output Destinations */
+#define CONN_DST_LEFT 0x0010 /* Left Channel Send */
+#define CONN_DST_RIGHT 0x0011 /* Right Channel Send */
+#define CONN_DST_CENTER 0x0012 /* Center Channel Send */
+#define CONN_DST_LEFTREAR 0x0013 /* Left Rear Channel Send */
+#define CONN_DST_RIGHTREAR 0x0014 /* Right Rear Channel Send */
+#define CONN_DST_LFE_CHANNEL 0x0015 /* LFE Channel Send */
+#define CONN_DST_CHORUS 0x0080 /* Chorus Send */
+#define CONN_DST_REVERB 0x0081 /* Reverb Send */
+
+/* Vibrato LFO Destinations */
+#define CONN_DST_VIB_FREQUENCY 0x0114 /* Vibrato Frequency */
+#define CONN_DST_VIB_STARTDELAY 0x0115 /* Vibrato Start Delay */
+
+/* EG1 Destinations */
+#define CONN_DST_EG1_DELAYTIME 0x020B /* EG1 Delay Time */
+#define CONN_DST_EG1_HOLDTIME 0x020C /* EG1 Hold Time */
+#define CONN_DST_EG1_SHUTDOWNTIME 0x020D /* EG1 Shutdown Time */
+
+
+/* EG2 Destinations */
+#define CONN_DST_EG2_DELAYTIME 0x030F /* EG2 Delay Time */
+#define CONN_DST_EG2_HOLDTIME 0x0310 /* EG2 Hold Time */
+
+
+/* Filter Destinations */
+#define CONN_DST_FILTER_CUTOFF 0x0500 /* Filter Cutoff Frequency */
+#define CONN_DST_FILTER_Q 0x0501 /* Filter Resonance */
+
+
+/* Transforms */
+#define CONN_TRN_CONVEX 0x0002 /* Convex Transform */
+#define CONN_TRN_SWITCH 0x0003 /* Switch Transform */
+
+
+/* Conditional chunk operators */
+ #define DLS_CDL_AND 0x0001 /* X = X & Y */
+ #define DLS_CDL_OR 0x0002 /* X = X | Y */
+ #define DLS_CDL_XOR 0x0003 /* X = X ^ Y */
+ #define DLS_CDL_ADD 0x0004 /* X = X + Y */
+ #define DLS_CDL_SUBTRACT 0x0005 /* X = X - Y */
+ #define DLS_CDL_MULTIPLY 0x0006 /* X = X * Y */
+ #define DLS_CDL_DIVIDE 0x0007 /* X = X / Y */
+ #define DLS_CDL_LOGICAL_AND 0x0008 /* X = X && Y */
+ #define DLS_CDL_LOGICAL_OR 0x0009 /* X = X || Y */
+ #define DLS_CDL_LT 0x000A /* X = (X < Y) */
+ #define DLS_CDL_LE 0x000B /* X = (X <= Y) */
+ #define DLS_CDL_GT 0x000C /* X = (X > Y) */
+ #define DLS_CDL_GE 0x000D /* X = (X >= Y) */
+ #define DLS_CDL_EQ 0x000E /* X = (X == Y) */
+ #define DLS_CDL_NOT 0x000F /* X = !X */
+ #define DLS_CDL_CONST 0x0010 /* 32-bit constant */
+ #define DLS_CDL_QUERY 0x0011 /* 32-bit value returned from query */
+ #define DLS_CDL_QUERYSUPPORTED 0x0012 /* 32-bit value returned from query */
+
+/*
+ Loop and release
+*/
+
+#define WLOOP_TYPE_RELEASE 1
+
+/*
+ DLSID queries for <cdl-ck>
+*/
+DEFINE_DLSID(DLSID_GMInHardware, 0x178f2f24, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+DEFINE_DLSID(DLSID_GSInHardware, 0x178f2f25, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+DEFINE_DLSID(DLSID_XGInHardware, 0x178f2f26, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+DEFINE_DLSID(DLSID_SupportsDLS1, 0x178f2f27, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+DEFINE_DLSID(DLSID_SupportsDLS2, 0xf14599e5, 0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);
+DEFINE_DLSID(DLSID_SampleMemorySize, 0x178f2f28, 0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+DEFINE_DLSID(DLSID_ManufacturersID, 0xb03e1181, 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+DEFINE_DLSID(DLSID_ProductID, 0xb03e1182, 0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+DEFINE_DLSID(DLSID_SamplePlaybackRate, 0x2a91f713, 0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+#endif /* _INC_DLS2 */
+
diff --git a/arm-wt-22k/lib_src/eas_audioconst.h b/arm-wt-22k/lib_src/eas_audioconst.h
new file mode 100644
index 0000000..1cfa404
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_audioconst.h
@@ -0,0 +1,97 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_audioconst.h
+ *
+ * Contents and purpose:
+ * Defines audio constants related to the sample rate, bit size, etc.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_AUDIOCONST_H
+#define _EAS_AUDIOCONST_H
+
+/*----------------------------------------------------------------------------
+ * These macros define the various characteristics of the defined sample rates
+ *----------------------------------------------------------------------------
+ * BUFFER_SIZE_IN_MONO_SAMPLES size of buffer in samples
+ * _OUTPUT_SAMPLE_RATE compiled output sample rate
+ * AUDIO_FRAME_LENGTH length of an audio frame in 256ths of a millisecond
+ * SYNTH_UPDATE_PERIOD_IN_BITS length of an audio frame (2^x samples)
+ *----------------------------------------------------------------------------
+*/
+
+#if defined (_SAMPLE_RATE_8000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 32
+#define _OUTPUT_SAMPLE_RATE 8000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 5
+
+#elif defined (_SAMPLE_RATE_16000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 64
+#define _OUTPUT_SAMPLE_RATE 16000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 6
+
+#elif defined (_SAMPLE_RATE_20000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 20000
+#define AUDIO_FRAME_LENGTH 1638
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_22050)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 22050
+#define AUDIO_FRAME_LENGTH 1486
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_24000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 24000
+#define AUDIO_FRAME_LENGTH 1365
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_32000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 128
+#define _OUTPUT_SAMPLE_RATE 32000
+#define AUDIO_FRAME_LENGTH 1024
+#define SYNTH_UPDATE_PERIOD_IN_BITS 7
+
+#elif defined (_SAMPLE_RATE_44100)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 256
+#define _OUTPUT_SAMPLE_RATE 44100
+#define AUDIO_FRAME_LENGTH 1486
+#define SYNTH_UPDATE_PERIOD_IN_BITS 8
+
+#elif defined (_SAMPLE_RATE_48000)
+#define BUFFER_SIZE_IN_MONO_SAMPLES 256
+#define _OUTPUT_SAMPLE_RATE 48000
+#define AUDIO_FRAME_LENGTH 1365
+#define SYNTH_UPDATE_PERIOD_IN_BITS 8
+
+#else
+#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
+#endif
+
+#endif /* #ifndef _EAS_AUDIOCONST_H */
+
diff --git a/arm-wt-22k/lib_src/eas_chorus.c b/arm-wt-22k/lib_src/eas_chorus.c
new file mode 100644
index 0000000..bc42237
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_chorus.c
@@ -0,0 +1,604 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorus.c
+ *
+ * Contents and purpose:
+ * Contains the implementation of the Chorus effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 499 $
+ * $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_effects.h"
+#include "eas_math.h"
+#include "eas_chorusdata.h"
+#include "eas_chorus.h"
+#include "eas_config.h"
+#include "eas_host.h"
+#include "eas_report.h"
+
+/* prototypes for effects interface */
+static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples);
+static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+
+/* common effects interface for configuration module */
+const S_EFFECTS_INTERFACE EAS_Chorus =
+{
+ ChorusInit,
+ ChorusProcess,
+ ChorusShutdown,
+ ChorusGetParam,
+ ChorusSetParam
+};
+
+
+
+//LFO shape table used by the chorus, larger table would sound better
+//this is a sine wave, where 32767 = 1.0
+static const EAS_I16 EAS_chorusShape[CHORUS_SHAPE_SIZE] = {
+ 0, 1608, 3212, 4808, 6393, 7962, 9512, 11309, 12539, 14010, 15446, 16846, 18204, 19519, 20787, 22005, 23170,
+ 24279, 25329, 26319, 27245, 28105, 28898, 29621, 30273, 30852, 31356, 31785, 32137, 32412, 32609, 32728,
+ 32767, 32728, 32609, 32412, 32137, 31785, 31356, 30852, 30273, 29621, 28898, 28105, 27245, 26319, 25329,
+ 24279, 23170, 22005, 20787, 19519, 18204, 16846, 15446, 14010, 12539, 11039, 9512, 7962, 6393, 4808, 3212,
+ 1608, 0, -1608, -3212, -4808, -6393, -7962, -9512, -11309, -12539, -14010, -15446, -16846, -18204, -19519,
+ -20787, -22005, -23170, -24279, -25329, -26319, -27245, -28105, -28898, -29621, -30273, -30852, -31356, -31785,
+ -32137, -32412, -32609, -32728, -32767, -32728, -32609, -32412, -32137, -31785, -31356, -30852, -30273, -29621,
+ -28898, -28105, -27245, -26319, -25329, -24279, -23170, -22005, -20787, -19519, -18204, -16846, -15446, -14010,
+ -12539, -11039, -9512, -7962, -6393, -4808, -3212, -1608
+};
+
+/*----------------------------------------------------------------------------
+ * InitializeChorus()
+ *----------------------------------------------------------------------------
+ * Purpose: Initializes chorus parameters
+ *
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusInit (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData)
+{
+ S_CHORUS_OBJECT *pChorusData;
+ S_CHORUS_PRESET *pPreset;
+ EAS_I32 index;
+
+ /* check Configuration Module for data allocation */
+ if (pEASData->staticMemoryModel)
+ pChorusData = EAS_CMEnumFXData(EAS_MODULE_CHORUS);
+
+ /* allocate dynamic memory */
+ else
+ pChorusData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_CHORUS_OBJECT));
+
+ if (pChorusData == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate Chorus memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ /* clear the structure */
+ EAS_HWMemSet(pChorusData, 0, sizeof(S_CHORUS_OBJECT));
+
+ ChorusReadInPresets(pChorusData);
+
+ /* set some default values */
+ pChorusData->bypass = EAS_CHORUS_BYPASS_DEFAULT;
+ pChorusData->preset = EAS_CHORUS_PRESET_DEFAULT;
+ pChorusData->m_nLevel = EAS_CHORUS_LEVEL_DEFAULT;
+ pChorusData->m_nRate = EAS_CHORUS_RATE_DEFAULT;
+ pChorusData->m_nDepth = EAS_CHORUS_DEPTH_DEFAULT;
+
+ //chorus rate and depth need some massaging from preset value (which is sample rate independent)
+
+ //convert rate from steps of .05 Hz to value which can be used as phase increment,
+ //with current CHORUS_SHAPE_SIZE and rate limits, this fits into 16 bits
+ //want to compute ((shapeSize * 65536) * (storedRate/20))/sampleRate;
+ //computing it as below allows rate steps to be evenly spaced
+ //uses 32 bit divide, but only once when new value is selected
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ //convert depth from steps of .05 ms, to samples, with 16 bit whole part, discard fraction
+ //want to compute ((depth * sampleRate)/20000)
+ //use the following approximation since 105/32 is roughly 65536/20000
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ pChorusData->m_nLevel = pChorusData->m_nLevel;
+
+ //zero delay memory for chorus
+ for (index = CHORUS_L_SIZE - 1; index >= 0; index--)
+ {
+ pChorusData->chorusDelayL[index] = 0;
+ }
+ for (index = CHORUS_R_SIZE - 1; index >= 0; index--)
+ {
+ pChorusData->chorusDelayR[index] = 0;
+ }
+
+ //init delay line index, these are used to implement circular delay buffer
+ pChorusData->chorusIndexL = 0;
+ pChorusData->chorusIndexR = 0;
+
+ //init LFO phase
+ //16 bit whole part, 16 bit fraction
+ pChorusData->lfoLPhase = 0;
+ pChorusData->lfoRPhase = (CHORUS_SHAPE_SIZE << 16) >> 2; // 1/4 of total, i.e. 90 degrees out of phase;
+
+ //init chorus delay position
+ //right now chorus delay is a compile-time value, as is sample rate
+ pChorusData->chorusTapPosition = (EAS_I16)((CHORUS_DELAY_MS * _OUTPUT_SAMPLE_RATE)/1000);
+
+ //now copy from the new preset into Chorus
+ pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
+
+ pChorusData->m_nLevel = pPreset->m_nLevel;
+ pChorusData->m_nRate = pPreset->m_nRate;
+ pChorusData->m_nDepth = pPreset->m_nDepth;
+
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ *pInstData = pChorusData;
+
+ return EAS_SUCCESS;
+} /* end ChorusInit */
+
+/*----------------------------------------------------------------------------
+ * WeightedTap()
+ *----------------------------------------------------------------------------
+ * Purpose: Does fractional array look-up using linear interpolation
+ *
+ * first convert indexDesired to actual desired index by taking into account indexReference
+ * then do linear interpolation between two actual samples using fractional part
+ *
+ * Inputs:
+ * array: pointer to array of signed 16 bit values, typically either PCM data or control data
+ * indexReference: the circular buffer relative offset
+ * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
+ * indexLimit: the total size of the array, used to compute buffer wrap
+ *
+ * Outputs:
+ * Value from the input array, linearly interpolated between two actual data values
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit)
+{
+ EAS_I16 index;
+ EAS_I16 fraction;
+ EAS_I16 val1;
+ EAS_I16 val2;
+
+ //separate indexDesired into whole and fractional parts
+ /*lint -e{704} use shift for performance */
+ index = (EAS_I16)(indexDesired >> 16);
+ /*lint -e{704} use shift for performance */
+ fraction = (EAS_I16)((indexDesired>>1) & 0x07FFF); //just use 15 bits of fractional part
+
+ //adjust whole part by indexReference
+ index = indexReference - index;
+ //make sure we stay within array bounds, this implements circular buffer
+ while (index < 0)
+ {
+ index += indexLimit;
+ }
+
+ //get two adjacent values from the array
+ val1 = array[index];
+
+ //handle special case when index == 0, else typical case
+ if (index == 0)
+ {
+ val2 = array[indexLimit-1]; //get last value from array
+ }
+ else
+ {
+ val2 = array[index-1]; //get previous value from array
+ }
+
+ //compute linear interpolation as (val1 + ((val2-val1)*fraction))
+ return(val1 + (EAS_I16)MULT_EG1_EG1(val2-val1,fraction));
+}
+
+/*----------------------------------------------------------------------------
+ * ChorusProcess()
+ *----------------------------------------------------------------------------
+ * Purpose: compute the chorus on the input buffer, and mix into output buffer
+ *
+ *
+ * Inputs:
+ * src: pointer to input buffer of PCM values to be processed
+ * dst: pointer to output buffer of PCM values we are to sume the result with
+ * bufSize: the number of sample frames (i.e. stereo samples) in the buffer
+ *
+ * Outputs:
+ * None
+ *
+ *----------------------------------------------------------------------------
+*/
+//compute the chorus, and mix into output buffer
+static void ChorusProcess (EAS_VOID_PTR pInstData, EAS_PCM *pSrc, EAS_PCM *pDst, EAS_I32 numSamples)
+{
+ EAS_I32 ix;
+ EAS_I32 nChannelNumber;
+ EAS_I16 lfoValueLeft;
+ EAS_I16 lfoValueRight;
+ EAS_I32 positionOffsetL;
+ EAS_I32 positionOffsetR;
+ EAS_PCM tapL;
+ EAS_PCM tapR;
+ EAS_I32 tempValue;
+ EAS_PCM nInputSample;
+ EAS_I32 nOutputSample;
+ EAS_PCM *pIn;
+ EAS_PCM *pOut;
+
+ S_CHORUS_OBJECT *pChorusData;
+
+ pChorusData = (S_CHORUS_OBJECT*) pInstData;
+
+ //if the chorus is disabled or turned all the way down
+ if (pChorusData->bypass == EAS_TRUE || pChorusData->m_nLevel == 0)
+ {
+ if (pSrc != pDst)
+ EAS_HWMemCpy(pSrc, pDst, numSamples * NUM_OUTPUT_CHANNELS * (EAS_I32) sizeof(EAS_PCM));
+ return;
+ }
+
+ if (pChorusData->m_nNextChorus != pChorusData->m_nCurrentChorus)
+ {
+ ChorusUpdate(pChorusData);
+ }
+
+ for (nChannelNumber = 0; nChannelNumber < NUM_OUTPUT_CHANNELS; nChannelNumber++)
+ {
+
+ pIn = pSrc + nChannelNumber;
+ pOut = pDst + nChannelNumber;
+
+ if(nChannelNumber==0)
+ {
+ for (ix = 0; ix < numSamples; ix++)
+ {
+ nInputSample = *pIn;
+ pIn += NUM_OUTPUT_CHANNELS;
+
+ //feed input into chorus delay line
+ pChorusData->chorusDelayL[pChorusData->chorusIndexL] = nInputSample;
+
+ //compute chorus lfo value using phase as fractional index into chorus shape table
+ //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
+ lfoValueLeft = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoLPhase, CHORUS_SHAPE_SIZE);
+
+ //scale chorus depth by lfo value to get relative fractional sample index
+ //index is expressed as 32 bit number with 16 bit fractional part
+ /*lint -e{703} use shift for performance */
+ positionOffsetL = pChorusData->m_nDepth * (((EAS_I32)lfoValueLeft) << 1);
+
+ //add fixed chorus delay to get actual fractional sample index
+ positionOffsetL += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
+
+ //get tap value from chorus delay using fractional sample index
+ tapL = WeightedTap(pChorusData->chorusDelayL, pChorusData->chorusIndexL, positionOffsetL, CHORUS_L_SIZE);
+
+ //scale by chorus level, then sum with input buffer contents and saturate
+ tempValue = MULT_EG1_EG1(tapL, pChorusData->m_nLevel);
+ nOutputSample = SATURATE(tempValue + nInputSample);
+
+ *pOut = (EAS_I16)SATURATE(nOutputSample);
+ pOut += NUM_OUTPUT_CHANNELS;
+
+
+ //increment chorus delay index and make it wrap as needed
+ //this implements circular buffer
+ if ((pChorusData->chorusIndexL+=1) >= CHORUS_L_SIZE)
+ pChorusData->chorusIndexL = 0;
+
+ //increment fractional lfo phase, and make it wrap as needed
+ pChorusData->lfoLPhase += pChorusData->m_nRate;
+ while (pChorusData->lfoLPhase >= (CHORUS_SHAPE_SIZE<<16))
+ {
+ pChorusData->lfoLPhase -= (CHORUS_SHAPE_SIZE<<16);
+ }
+ }
+ }
+ else
+ {
+ for (ix = 0; ix < numSamples; ix++)
+ {
+ nInputSample = *pIn;
+ pIn += NUM_OUTPUT_CHANNELS;
+
+ //feed input into chorus delay line
+ pChorusData->chorusDelayR[pChorusData->chorusIndexR] = nInputSample;
+
+ //compute chorus lfo value using phase as fractional index into chorus shape table
+ //resulting value is between -1.0 and 1.0, expressed as signed 16 bit number
+ lfoValueRight = WeightedTap(EAS_chorusShape, 0, pChorusData->lfoRPhase, CHORUS_SHAPE_SIZE);
+
+ //scale chorus depth by lfo value to get relative fractional sample index
+ //index is expressed as 32 bit number with 16 bit fractional part
+ /*lint -e{703} use shift for performance */
+ positionOffsetR = pChorusData->m_nDepth * (((EAS_I32)lfoValueRight) << 1);
+
+ //add fixed chorus delay to get actual fractional sample index
+ positionOffsetR += ((EAS_I32)pChorusData->chorusTapPosition) << 16;
+
+ //get tap value from chorus delay using fractional sample index
+ tapR = WeightedTap(pChorusData->chorusDelayR, pChorusData->chorusIndexR, positionOffsetR, CHORUS_R_SIZE);
+
+ //scale by chorus level, then sum with output buffer contents and saturate
+ tempValue = MULT_EG1_EG1(tapR, pChorusData->m_nLevel);
+ nOutputSample = SATURATE(tempValue + nInputSample);
+
+ *pOut = (EAS_I16)SATURATE(nOutputSample);
+ pOut += NUM_OUTPUT_CHANNELS;
+
+ //increment chorus delay index and make it wrap as needed
+ //this implements circular buffer
+ if ((pChorusData->chorusIndexR+=1) >= CHORUS_R_SIZE)
+ pChorusData->chorusIndexR = 0;
+
+ //increment fractional lfo phase, and make it wrap as needed
+ pChorusData->lfoRPhase += pChorusData->m_nRate;
+ while (pChorusData->lfoRPhase >= (CHORUS_SHAPE_SIZE<<16))
+ {
+ pChorusData->lfoRPhase -= (CHORUS_SHAPE_SIZE<<16);
+ }
+ }
+ }
+
+ }
+} /* end ChorusProcess */
+
+
+
+/*----------------------------------------------------------------------------
+ * ChorusShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the Chorus effect.
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusShutdown (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData)
+{
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pInstData);
+ return EAS_SUCCESS;
+} /* end ChorusShutdown */
+
+/*----------------------------------------------------------------------------
+ * ChorusGetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get a Chorus parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - pointer to variable to hold retrieved value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusGetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_CHORUS_OBJECT *p;
+
+ p = (S_CHORUS_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_CHORUS_BYPASS:
+ *pValue = (EAS_I32) p->bypass;
+ break;
+ case EAS_PARAM_CHORUS_PRESET:
+ *pValue = (EAS_I8) p->m_nCurrentChorus;
+ break;
+ case EAS_PARAM_CHORUS_RATE:
+ *pValue = (EAS_I32) p->m_nRate;
+ break;
+ case EAS_PARAM_CHORUS_DEPTH:
+ *pValue = (EAS_I32) p->m_nDepth;
+ break;
+ case EAS_PARAM_CHORUS_LEVEL:
+ *pValue = (EAS_I32) p->m_nLevel;
+ break;
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ChorusGetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ChorusSetParam()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set a Chorus parameter
+ *
+ * Inputs:
+ * pInstData - handle to instance data
+ * param - parameter index
+ * *pValue - new paramter value
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusSetParam (EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_CHORUS_OBJECT *p;
+
+ p = (S_CHORUS_OBJECT*) pInstData;
+
+ switch (param)
+ {
+ case EAS_PARAM_CHORUS_BYPASS:
+ p->bypass = (EAS_BOOL) value;
+ break;
+ case EAS_PARAM_CHORUS_PRESET:
+ if(value!=EAS_PARAM_CHORUS_PRESET1 && value!=EAS_PARAM_CHORUS_PRESET2 &&
+ value!=EAS_PARAM_CHORUS_PRESET3 && value!=EAS_PARAM_CHORUS_PRESET4)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nNextChorus = (EAS_I8)value;
+ break;
+ case EAS_PARAM_CHORUS_RATE:
+ if(value<EAS_CHORUS_RATE_MIN || value>EAS_CHORUS_RATE_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nRate = (EAS_I16) value;
+ break;
+ case EAS_PARAM_CHORUS_DEPTH:
+ if(value<EAS_CHORUS_DEPTH_MIN || value>EAS_CHORUS_DEPTH_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nDepth = (EAS_I16) value;
+ break;
+ case EAS_PARAM_CHORUS_LEVEL:
+ if(value<EAS_CHORUS_LEVEL_MIN || value>EAS_CHORUS_LEVEL_MAX)
+ return EAS_ERROR_INVALID_PARAMETER;
+ p->m_nLevel = (EAS_I16) value;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+} /* end ChorusSetParam */
+
+
+/*----------------------------------------------------------------------------
+ * ChorusReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global Chorus preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData)
+{
+
+ int preset = 0;
+ int defaultPreset = 0;
+
+ //now init any remaining presets to defaults
+ for (defaultPreset = preset; defaultPreset < CHORUS_MAX_TYPE; defaultPreset++)
+ {
+ S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[defaultPreset];
+ if (defaultPreset == 0 || defaultPreset > CHORUS_MAX_TYPE-1)
+ {
+ pPreset->m_nDepth = 39;
+ pPreset->m_nRate = 30;
+ pPreset->m_nLevel = 32767;
+ }
+ else if (defaultPreset == 1)
+ {
+ pPreset->m_nDepth = 21;
+ pPreset->m_nRate = 45;
+ pPreset->m_nLevel = 25000;
+ }
+ else if (defaultPreset == 2)
+ {
+ pPreset->m_nDepth = 53;
+ pPreset->m_nRate = 25;
+ pPreset->m_nLevel = 32000;
+ }
+ else if (defaultPreset == 3)
+ {
+ pPreset->m_nDepth = 32;
+ pPreset->m_nRate = 37;
+ pPreset->m_nLevel = 29000;
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * ChorusUpdate
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the Chorus preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - chorus paramters will be changed
+ * - m_nCurrentRoom := m_nNextRoom
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT *pChorusData)
+{
+ S_CHORUS_PRESET *pPreset = &pChorusData->m_sPreset.m_sPreset[pChorusData->m_nNextChorus];
+
+ pChorusData->m_nLevel = pPreset->m_nLevel;
+ pChorusData->m_nRate = pPreset->m_nRate;
+ pChorusData->m_nDepth = pPreset->m_nDepth;
+
+ pChorusData->m_nRate = (EAS_I16)
+ ((((EAS_I32)CHORUS_SHAPE_SIZE<<16)/(20*(EAS_I32)_OUTPUT_SAMPLE_RATE)) * pChorusData->m_nRate);
+
+ /*lint -e{704} use shift for performance */
+ pChorusData->m_nDepth = (EAS_I16)
+ (((((EAS_I32)pChorusData->m_nDepth * _OUTPUT_SAMPLE_RATE)>>5) * 105) >> 16);
+
+ pChorusData->m_nCurrentChorus = pChorusData->m_nNextChorus;
+
+ return EAS_SUCCESS;
+
+} /* end ChorusUpdate */
diff --git a/arm-wt-22k/lib_src/eas_chorusdata.c b/arm-wt-22k/lib_src/eas_chorusdata.c
new file mode 100644
index 0000000..caee1ed
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_chorusdata.c
@@ -0,0 +1,34 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorusdata.c
+ *
+ * Contents and purpose:
+ * Contains the static data allocation for the Chorus effect
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 550 $
+ * $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_chorusdata.h"
+
+S_CHORUS_OBJECT eas_ChorusData;
+
diff --git a/arm-wt-22k/lib_src/eas_chorusdata.h b/arm-wt-22k/lib_src/eas_chorusdata.h
new file mode 100644
index 0000000..4420ddd
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_chorusdata.h
@@ -0,0 +1,160 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_chorusdata.h
+ *
+ * Contents and purpose:
+ * Contains the prototypes for the Chorus effect.
+ *
+ *
+ * Copyright Sonic Network Inc. 2006
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 309 $
+ * $Date: 2006-09-12 18:52:45 -0700 (Tue, 12 Sep 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_CHORUS_H
+#define _EAS_CHORUS_H
+
+#include "eas_types.h"
+#include "eas_audioconst.h"
+
+//defines for chorus
+
+#define EAS_CHORUS_BYPASS_DEFAULT 1
+#define EAS_CHORUS_PRESET_DEFAULT 0
+#define EAS_CHORUS_RATE_DEFAULT 30
+#define EAS_CHORUS_DEPTH_DEFAULT 39
+#define EAS_CHORUS_LEVEL_DEFAULT 32767
+
+#define EAS_CHORUS_LEVEL_MIN 0
+#define EAS_CHORUS_LEVEL_MAX 32767
+
+#define EAS_CHORUS_RATE_MIN 10
+#define EAS_CHORUS_RATE_MAX 50
+
+#define EAS_CHORUS_DEPTH_MIN 15
+#define EAS_CHORUS_DEPTH_MAX 60
+
+#define CHORUS_SIZE_MS 20
+#define CHORUS_L_SIZE ((CHORUS_SIZE_MS*_OUTPUT_SAMPLE_RATE)/1000)
+#define CHORUS_R_SIZE CHORUS_L_SIZE
+#define CHORUS_SHAPE_SIZE 128
+#define CHORUS_DELAY_MS 10
+
+#define CHORUS_MAX_TYPE 4 // any Chorus numbers larger than this are invalid
+
+typedef struct
+{
+ EAS_I16 m_nRate;
+ EAS_I16 m_nDepth;
+ EAS_I16 m_nLevel;
+
+} S_CHORUS_PRESET;
+
+typedef struct
+{
+ S_CHORUS_PRESET m_sPreset[CHORUS_MAX_TYPE]; //array of presets
+
+} S_CHORUS_PRESET_BANK;
+
+/* parameters for each Chorus */
+typedef struct
+{
+ EAS_I32 lfoLPhase;
+ EAS_I32 lfoRPhase;
+ EAS_I16 chorusIndexL;
+ EAS_I16 chorusIndexR;
+ EAS_U16 chorusTapPosition;
+
+ EAS_I16 m_nRate;
+ EAS_I16 m_nDepth;
+ EAS_I16 m_nLevel;
+
+ //delay lines used by the chorus, longer would sound better
+ EAS_PCM chorusDelayL[CHORUS_L_SIZE];
+ EAS_PCM chorusDelayR[CHORUS_R_SIZE];
+
+ EAS_BOOL bypass;
+ EAS_I8 preset;
+
+ EAS_I16 m_nCurrentChorus; // preset number for current Chorus
+ EAS_I16 m_nNextChorus; // preset number for next Chorus
+
+ S_CHORUS_PRESET pPreset;
+
+ S_CHORUS_PRESET_BANK m_sPreset;
+
+} S_CHORUS_OBJECT;
+
+
+/*----------------------------------------------------------------------------
+ * WeightedTap()
+ *----------------------------------------------------------------------------
+ * Purpose: Does fractional array look-up using linear interpolation
+ *
+ * first convert indexDesired to actual desired index by taking into account indexReference
+ * then do linear interpolation between two actual samples using fractional part
+ *
+ * Inputs:
+ * array: pointer to array of signed 16 bit values, typically either PCM data or control data
+ * indexReference: the circular buffer relative offset
+ * indexDesired: the fractional index we are looking up (16 bits index + 16 bits fraction)
+ * indexLimit: the total size of the array, used to compute buffer wrap
+ *
+ * Outputs:
+ * Value from the input array, linearly interpolated between two actual data values
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 WeightedTap(const EAS_I16 *array, EAS_I16 indexReference, EAS_I32 indexDesired, EAS_I16 indexLimit);
+
+/*----------------------------------------------------------------------------
+ * ChorusReadInPresets()
+ *----------------------------------------------------------------------------
+ * Purpose: sets global Chorus preset bank to defaults
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusReadInPresets(S_CHORUS_OBJECT *pChorusData);
+
+/*----------------------------------------------------------------------------
+ * ChorusUpdate
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the Chorus preset parameters as required
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ * - chorus paramters will be changed
+ * - m_nCurrentChorus := m_nNextChorus
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ChorusUpdate(S_CHORUS_OBJECT* pChorusData);
+
+#endif /* #ifndef _EAS_CHORUSDATA_H */
+
+
diff --git a/arm-wt-22k/lib_src/eas_ctype.h b/arm-wt-22k/lib_src/eas_ctype.h
new file mode 100644
index 0000000..8503870
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_ctype.h
@@ -0,0 +1,41 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ctype.h
+ *
+ * Contents and purpose:
+ * This is a replacement for the CRT ctype.h functions. These
+ * functions are currently ASCII only, but eventually, we will want
+ * to support wide-characters for localization.
+ *
+ * Copyright (c) 2005 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 429 $
+ * $Date: 2006-10-19 23:50:15 -0700 (Thu, 19 Oct 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_CTYPE_H
+#define _EAS_CTYPE_H
+
+EAS_INLINE EAS_I8 IsDigit (EAS_I8 c) { return ((c >= '0') && (c <= '9')); }
+EAS_INLINE EAS_I8 IsSpace (EAS_I8 c) { return (((c >= 9) && (c <= 13)) || (c == ' ')); }
+EAS_INLINE EAS_I8 ToUpper (EAS_I8 c) { if ((c >= 'a') && (c <= 'z')) return c & ~0x20; else return c; }
+EAS_INLINE EAS_I8 ToLower (EAS_I8 c) { if ((c >= 'A') && (c <= 'Z')) return c |= 0x20; else return c; }
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_data.c b/arm-wt-22k/lib_src/eas_data.c
new file mode 100644
index 0000000..bb60ef2
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_data.c
@@ -0,0 +1,37 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_data.c
+ *
+ * Contents and purpose:
+ * Contains a data allocation for synthesizer
+ *
+ * Copyright Sonic Network Inc. 2004
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_data.h"
+
+// globals
+S_EAS_DATA eas_Data;
+S_VOICE_MGR eas_Synth;
+S_SYNTH eas_MIDI;
+
diff --git a/arm-wt-22k/lib_src/eas_data.h b/arm-wt-22k/lib_src/eas_data.h
new file mode 100644
index 0000000..28957fd
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_data.h
@@ -0,0 +1,133 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_data.h
+ *
+ * Contents and purpose:
+ * This header defines all types, to support dynamic allocation of the
+ * memory resources needed for persistent EAS data.
+ *
+ * Copyright 2004 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 842 $
+ * $Date: 2007-08-23 14:32:31 -0700 (Thu, 23 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_DATA_H
+#define _EAS_DATA_H
+
+#define JET_INTERFACE
+
+#include "eas_types.h"
+#include "eas_synthcfg.h"
+#include "eas.h"
+#include "eas_audioconst.h"
+#include "eas_sndlib.h"
+#include "eas_pcm.h"
+#include "eas_pcmdata.h"
+#include "eas_synth.h"
+#include "eas_miditypes.h"
+#include "eas_effects.h"
+
+#ifdef AUX_MIXER
+#include "eas_auxmixdata.h"
+#endif
+
+#ifdef JET_INTERFACE
+#include "jet.h"
+#endif
+
+#ifdef _METRICS_ENABLED
+#include "eas_perf.h"
+#endif
+
+#ifndef MAX_NUMBER_STREAMS
+#define MAX_NUMBER_STREAMS 4
+#endif
+
+/* flags for S_EAS_STREAM */
+#define STREAM_FLAGS_PARSED 1
+#define STREAM_FLAGS_PAUSE 2
+#define STREAM_FLAGS_LOCATE 4
+#define STREAM_FLAGS_RESUME 8
+
+/* structure for parsing a stream */
+typedef struct s_eas_stream_tag
+{
+ void *pParserModule;
+ EAS_U32 time;
+ EAS_U32 frameLength;
+ EAS_I32 repeatCount;
+ EAS_VOID_PTR handle;
+ EAS_U8 volume;
+ EAS_BOOL8 streamFlags;
+} S_EAS_STREAM;
+
+/* default master volume is -10dB */
+#define DEFAULT_VOLUME 90
+#define DEFAULT_STREAM_VOLUME 100
+#define DEFAULT_STREAM_GAIN 14622
+
+/* 10 dB of boost available for individual parsers */
+#define STREAM_VOLUME_HEADROOM 10
+
+/* amalgamated persistent data type */
+typedef struct s_eas_data_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck;
+#endif
+ EAS_HW_DATA_HANDLE hwInstData;
+
+ S_EFFECTS_MODULE effectsModules[NUM_EFFECTS_MODULES];
+
+#ifdef _METRICS_ENABLED
+ S_METRICS_INTERFACE *pMetricsModule;
+ EAS_VOID_PTR pMetricsData;
+#endif
+
+ EAS_I32 *pMixBuffer;
+ EAS_PCM *pOutputAudioBuffer;
+
+#ifdef AUX_MIXER
+ S_EAS_AUX_MIXER auxMixer;
+#endif
+
+#ifdef _MAXIMIZER_ENABLED
+ EAS_VOID_PTR pMaximizerData;
+#endif
+
+ S_EAS_STREAM streams[MAX_NUMBER_STREAMS];
+
+ S_PCM_STATE *pPCMStreams;
+
+ S_VOICE_MGR *pVoiceMgr;
+
+#ifdef JET_INTERFACE
+ JET_DATA_HANDLE jetHandle;
+#endif
+
+ EAS_U32 renderTime;
+ EAS_I16 masterGain;
+ EAS_U8 masterVolume;
+ EAS_BOOL8 staticMemoryModel;
+ EAS_BOOL8 searchHeaderFlag;
+} S_EAS_DATA;
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_dlssynth.c b/arm-wt-22k/lib_src/eas_dlssynth.c
new file mode 100644
index 0000000..c1fa1ef
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_dlssynth.c
@@ -0,0 +1,578 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_dlssynth.c
+ *
+ * Contents and purpose:
+ * Implements the Mobile DLS synthesizer.
+ *
+ * Copyright Sonic Network Inc. 2006
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_math.h"
+#include "eas_synth_protos.h"
+#include "eas_wtsynth.h"
+#include "eas_pan.h"
+#include "eas_mdls.h"
+#include "eas_dlssynth.h"
+
+#ifdef _METRICS_ENABLED
+#include "eas_perf.h"
+#endif
+
+static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, const S_DLS_ENVELOPE *pEnvParams, EAS_I16 *pValue, EAS_I16 *pIncrement, EAS_U8 *pState);
+
+/*----------------------------------------------------------------------------
+ * DLS_MuteVoice()
+ *----------------------------------------------------------------------------
+ * Mute the voice using shutdown time from the DLS articulation data
+ *----------------------------------------------------------------------------
+*/
+void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
+{
+ S_WT_VOICE *pWTVoice;
+ const S_DLS_ARTICULATION *pDLSArt;
+
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
+
+ /* clear deferred action flags */
+ pVoice->voiceFlags &=
+ ~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
+ VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
+ VOICE_FLAG_DEFER_MUTE);
+
+ /* set the envelope state */
+ pVoiceMgr->wtVoices[voiceNum].eg1State = eEnvelopeStateRelease;
+ pWTVoice->eg1Increment = pDLSArt->eg1ShutdownTime;
+ pVoiceMgr->wtVoices[voiceNum].eg2State = eEnvelopeStateRelease;
+ pWTVoice->eg2Increment = pDLSArt->eg2.releaseTime;
+}
+
+/*----------------------------------------------------------------------------
+ * DLS_ReleaseVoice()
+ *----------------------------------------------------------------------------
+ * Release the selected voice.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pVoice) standard API, pVoice may be used by other synthesizers */
+void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
+{
+ S_WT_VOICE *pWTVoice;
+ const S_DLS_ARTICULATION *pDLSArt;
+
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
+
+ /* if still in attack phase, convert units to log */
+ /*lint -e{732} eg1Value is never negative */
+ /*lint -e{703} use shift for performance */
+ if (pWTVoice->eg1State == eEnvelopeStateAttack)
+ pWTVoice->eg1Value = (EAS_I16) ((EAS_flog2(pWTVoice->eg1Value) << 1) + 2048);
+
+ /* release EG1 */
+ pWTVoice->eg1State = eEnvelopeStateRelease;
+ pWTVoice->eg1Increment = pDLSArt->eg1.releaseTime;
+
+ /* release EG2 */
+ pWTVoice->eg2State = eEnvelopeStateRelease;
+ pWTVoice->eg2Increment = pDLSArt->eg2.releaseTime;
+}
+
+/*----------------------------------------------------------------------------
+ * DLS_SustainPedal()
+ *----------------------------------------------------------------------------
+ * The sustain pedal was just depressed. If the voice is still
+ * above the sustain level, catch the voice and continue holding.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pChannel) pChannel reserved for future use */
+void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
+{
+ S_WT_VOICE *pWTVoice;
+ const S_DLS_ARTICULATION *pDLSArt;
+
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
+
+ /* don't catch the voice if below the sustain level */
+ if (pWTVoice->eg1Value < pDLSArt->eg1.sustainLevel)
+ return;
+
+ /* defer releasing this note until the damper pedal is off */
+ pWTVoice->eg1State = eEnvelopeStateDecay;
+ pVoice->voiceState = eVoiceStatePlay;
+ pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
+
+#ifdef _DEBUG_SYNTH
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "DLS_SustainPedal: defer note off because sustain pedal is on\n"); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * DLS_UpdatePhaseInc()
+ *----------------------------------------------------------------------------
+ * Calculate the oscillator phase increment for the next frame
+ *----------------------------------------------------------------------------
+*/
+static EAS_I32 DLS_UpdatePhaseInc (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 pitchCents)
+{
+ EAS_I32 temp;
+
+ /* start with base mod LFO modulation */
+ temp = pDLSArt->modLFOToPitch;
+
+ /* add mod wheel effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOCC1ToPitch * pChannel->modWheel) >> 7);
+
+ /* add channel pressure effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOChanPressToPitch * pChannel->channelPressure) >> 7);
+
+ /* add total mod LFO effect */
+ pitchCents += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
+
+ /* start with base vib LFO modulation */
+ temp = pDLSArt->vibLFOToPitch;
+
+ /* add mod wheel effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->vibLFOCC1ToPitch * pChannel->modWheel) >> 7);
+
+ /* add channel pressure effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->vibLFOChanPressToPitch * pChannel->channelPressure) >> 7);
+
+ /* add total vibrato LFO effect */
+ pitchCents += FMUL_15x15(temp, pWTVoice->vibLFO.lfoValue);
+
+ /* add EG2 effect */
+ pitchCents += FMUL_15x15(pDLSArt->eg2ToPitch, pWTVoice->eg2Value);
+
+ /* convert from cents to linear phase increment */
+ return EAS_Calculate2toX(pitchCents);
+}
+
+/*----------------------------------------------------------------------------
+ * DLS_UpdateGain()
+ *----------------------------------------------------------------------------
+ * Calculate the gain for the next frame
+ *----------------------------------------------------------------------------
+*/
+static EAS_I32 DLS_UpdateGain (S_WT_VOICE *pWTVoice, const S_DLS_ARTICULATION *pDLSArt, S_SYNTH_CHANNEL *pChannel, EAS_I32 gain, EAS_U8 velocity)
+{
+ EAS_I32 temp;
+
+ /* start with base mod LFO modulation */
+ temp = pDLSArt->modLFOToGain;
+
+ /* add mod wheel effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOCC1ToGain * pChannel->modWheel) >> 7);
+
+ /* add channel pressure effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOChanPressToGain * pChannel->channelPressure) >> 7);
+
+ /* add total mod LFO effect */
+ gain += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
+ if (gain > 0)
+ gain = 0;
+
+ /* convert to linear gain including EG1 */
+ if (pWTVoice->eg1State != eEnvelopeStateAttack)
+ {
+ gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT;
+ /*lint -e{702} use shift for performance */
+#if 1
+ gain += (pWTVoice->eg1Value - 32767) >> 1;
+ gain = EAS_LogToLinear16(gain);
+#else
+ gain = EAS_LogToLinear16(gain);
+ temp = EAS_LogToLinear16((pWTVoice->eg1Value - 32767) >> 1);
+ gain = FMUL_15x15(gain, temp);
+#endif
+ }
+ else
+ {
+ gain = (DLS_GAIN_FACTOR * gain) >> DLS_GAIN_SHIFT;
+ gain = EAS_LogToLinear16(gain);
+ gain = FMUL_15x15(gain, pWTVoice->eg1Value);
+ }
+
+ /* include MIDI channel gain */
+ gain = FMUL_15x15(gain, pChannel->staticGain);
+
+ /* include velocity */
+ if (pDLSArt->filterQandFlags & FLAG_DLS_VELOCITY_SENSITIVE)
+ {
+ temp = velocity << 8;
+ temp = FMUL_15x15(temp, temp);
+ gain = FMUL_15x15(gain, temp);
+ }
+
+ /* return gain */
+ return gain;
+}
+
+/*----------------------------------------------------------------------------
+ * DLS_UpdateFilter()
+ *----------------------------------------------------------------------------
+ * Update the Filter parameters
+ *----------------------------------------------------------------------------
+*/
+static void DLS_UpdateFilter (S_SYNTH_VOICE *pVoice, S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pIntFrame, S_SYNTH_CHANNEL *pChannel, const S_DLS_ARTICULATION *pDLSArt)
+{
+ EAS_I32 cutoff;
+ EAS_I32 temp;
+
+ /* no need to calculate filter coefficients if it is bypassed */
+ if (pDLSArt->filterCutoff == DEFAULT_DLS_FILTER_CUTOFF_FREQUENCY)
+ {
+ pIntFrame->frame.k = 0;
+ return;
+ }
+
+ /* start with base cutoff frequency */
+ cutoff = pDLSArt->filterCutoff;
+
+ /* get base mod LFO modulation */
+ temp = pDLSArt->modLFOToFc;
+
+ /* add mod wheel effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOCC1ToFc * pChannel->modWheel) >> 7);
+
+ /* add channel pressure effect */
+ /*lint -e{702} use shift for performance */
+ temp += ((pDLSArt->modLFOChanPressToFc* pChannel->channelPressure) >> 7);
+
+ /* add total mod LFO effect */
+ cutoff += FMUL_15x15(temp, pWTVoice->modLFO.lfoValue);
+
+ /* add EG2 effect */
+ cutoff += FMUL_15x15(pWTVoice->eg2Value, pDLSArt->eg2ToFc);
+
+ /* add velocity effect */
+ /*lint -e{702} use shift for performance */
+ cutoff += (pVoice->velocity * pDLSArt->velToFc) >> 7;
+
+ /* add velocity effect */
+ /*lint -e{702} use shift for performance */
+ cutoff += (pVoice->note * pDLSArt->keyNumToFc) >> 7;
+
+ /* subtract the A5 offset and the sampling frequency */
+ cutoff -= FILTER_CUTOFF_FREQ_ADJUST + A5_PITCH_OFFSET_IN_CENTS;
+
+ /* limit the cutoff frequency */
+ if (cutoff > FILTER_CUTOFF_MAX_PITCH_CENTS)
+ cutoff = FILTER_CUTOFF_MAX_PITCH_CENTS;
+ else if (cutoff < FILTER_CUTOFF_MIN_PITCH_CENTS)
+ cutoff = FILTER_CUTOFF_MIN_PITCH_CENTS;
+
+ WT_SetFilterCoeffs(pIntFrame, cutoff, pDLSArt->filterQandFlags & FILTER_Q_MASK);
+}
+
+/*----------------------------------------------------------------------------
+ * DLS_StartVoice()
+ *----------------------------------------------------------------------------
+ * Start up a DLS voice
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
+{
+ S_WT_VOICE *pWTVoice;
+ const S_DLS_REGION *pDLSRegion;
+ const S_DLS_ARTICULATION *pDLSArt;
+ S_SYNTH_CHANNEL *pChannel;
+
+#ifdef _DEBUG_SYNTH
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "DLS_StartVoice: Voice %ld; Region %d\n", (EAS_I32) (pVoice - pVoiceMgr->voices), regionIndex); */ }
+#endif
+
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pChannel = &pSynth->channels[pVoice->channel & 15];
+ pDLSRegion = &pSynth->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK];
+ pWTVoice->artIndex = pDLSRegion->wtRegion.artIndex;
+ pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
+
+ /* initialize the envelopes */
+ pWTVoice->eg1State = eEnvelopeStateInit;
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
+ pWTVoice->eg2State = eEnvelopeStateInit;
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
+
+ /* initialize the LFOs */
+ pWTVoice->modLFO.lfoValue = 0;
+ pWTVoice->modLFO.lfoPhase = pDLSArt->modLFO.lfoDelay;
+ pWTVoice->vibLFO.lfoValue = 0;
+ pWTVoice->vibLFO.lfoPhase = pDLSArt->vibLFO.lfoDelay;
+
+ /* initalize the envelopes and calculate initial gain */
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
+ pVoice->gain = (EAS_I16) DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity);
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_CalcPanControl((EAS_INT) pChannel->pan - 64 + (EAS_INT) pDLSArt->pan, &pWTVoice->gainLeft, &pWTVoice->gainRight);
+#endif
+
+ /* initialize the filter states */
+ pWTVoice->filter.z1 = 0;
+ pWTVoice->filter.z2 = 0;
+
+ /* initialize the oscillator */
+ pWTVoice->phaseAccum = (EAS_U32) pSynth->pDLS->pDLSSamples + pSynth->pDLS->pDLSSampleOffsets[pDLSRegion->wtRegion.waveIndex];
+ if (pDLSRegion->wtRegion.region.keyGroupAndFlags & REGION_FLAG_IS_LOOPED)
+ {
+ pWTVoice->loopStart = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopStart;
+ pWTVoice->loopEnd = pWTVoice->phaseAccum + pDLSRegion->wtRegion.loopEnd - 1;
+ }
+ else
+ pWTVoice->loopStart = pWTVoice->loopEnd = pWTVoice->phaseAccum + pSynth->pDLS->pDLSSampleLen[pDLSRegion->wtRegion.waveIndex] - 1;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * DLS_UpdateVoice()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize a block of samples for the given voice.
+ * Use linear interpolation.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
+{
+ S_WT_VOICE *pWTVoice;
+ S_SYNTH_CHANNEL *pChannel;
+ const S_DLS_REGION *pDLSRegion;
+ const S_DLS_ARTICULATION *pDLSArt;
+ S_WT_INT_FRAME intFrame;
+ EAS_I32 temp;
+ EAS_BOOL done = EAS_FALSE;
+
+ /* establish pointers to critical data */
+ pWTVoice = &pVoiceMgr->wtVoices[voiceNum];
+ pDLSRegion = &pSynth->pDLS->pDLSRegions[pVoice->regionIndex & REGION_INDEX_MASK];
+ pChannel = &pSynth->channels[pVoice->channel & 15];
+ pDLSArt = &pSynth->pDLS->pDLSArticulations[pWTVoice->artIndex];
+
+ /* update the envelopes */
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg1, &pWTVoice->eg1Value, &pWTVoice->eg1Increment, &pWTVoice->eg1State);
+ DLS_UpdateEnvelope(pVoice, pChannel, &pDLSArt->eg2, &pWTVoice->eg2Value, &pWTVoice->eg2Increment, &pWTVoice->eg2State);
+
+ /* update the LFOs using the EAS synth function */
+ WT_UpdateLFO(&pWTVoice->modLFO, pDLSArt->modLFO.lfoFreq);
+ WT_UpdateLFO(&pWTVoice->vibLFO, pDLSArt->vibLFO.lfoFreq);
+
+ /* calculate base frequency */
+ temp = pDLSArt->tuning + pChannel->staticPitch + pDLSRegion->wtRegion.tuning +
+ (((EAS_I32) pVoice->note * (EAS_I32) pDLSArt->keyNumToPitch) >> 7);
+
+ /* don't transpose rhythm channel */
+ if ((pChannel ->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL) == 0)
+ temp += pSynth->globalTranspose * 100;
+
+ /* calculate phase increment including modulation effects */
+ intFrame.frame.phaseIncrement = DLS_UpdatePhaseInc(pWTVoice, pDLSArt, pChannel, temp);
+
+ /* calculate gain including modulation effects */
+ intFrame.frame.gainTarget = DLS_UpdateGain(pWTVoice, pDLSArt, pChannel, pDLSRegion->wtRegion.gain, pVoice->velocity);
+ intFrame.prevGain = pVoice->gain;
+
+ DLS_UpdateFilter(pVoice, pWTVoice, &intFrame, pChannel, pDLSArt);
+
+ /* call into engine to generate samples */
+ intFrame.pAudioBuffer = pVoiceMgr->voiceBuffer;
+ intFrame.pMixBuffer = pMixBuffer;
+ intFrame.numSamples = numSamples;
+ if (numSamples < 0)
+ return EAS_FALSE;
+
+ /* check for end of sample */
+ if ((pWTVoice->loopStart != WT_NOISE_GENERATOR) && (pWTVoice->loopStart == pWTVoice->loopEnd))
+ done = WT_CheckSampleEnd(pWTVoice, &intFrame, EAS_FALSE);
+
+ WT_ProcessVoice(pWTVoice, &intFrame);
+
+ /* clear flag */
+ pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
+
+ /* if the update interval has elapsed, then force the current gain to the next
+ * gain since we never actually reach the next gain when ramping -- we just get
+ * very close to the target gain.
+ */
+ pVoice->gain = (EAS_I16) intFrame.frame.gainTarget;
+
+ /* if voice has finished, set flag for voice manager */
+ if ((pVoice->voiceState != eVoiceStateStolen) && (pWTVoice->eg1State == eEnvelopeStateMuted))
+ done = EAS_TRUE;
+
+ return done;
+}
+
+/*----------------------------------------------------------------------------
+ * DLS_UpdateEnvelope()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Synthesize a block of samples for the given voice.
+ * Use linear interpolation.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * number of samples actually written to buffer
+ *
+ * Side Effects:
+ * - samples are added to the presently free buffer
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pChannel) pChannel not used in this instance */
+static void DLS_UpdateEnvelope (S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, const S_DLS_ENVELOPE *pEnvParams, EAS_I16 *pValue, EAS_I16 *pIncrement, EAS_U8 *pState)
+{
+ EAS_I32 temp;
+
+ switch (*pState)
+ {
+ /* initial state */
+ case eEnvelopeStateInit:
+ *pState = eEnvelopeStateDelay;
+ *pValue = 0;
+ *pIncrement = pEnvParams->delayTime;
+ if (*pIncrement != 0)
+ return;
+ /*lint -e{825} falls through to next case */
+
+ case eEnvelopeStateDelay:
+ if (*pIncrement)
+ {
+ *pIncrement = *pIncrement - 1;
+ return;
+ }
+
+ /* calculate attack rate */
+ *pState = eEnvelopeStateAttack;
+ if (pEnvParams->attackTime != ZERO_TIME_IN_CENTS)
+ {
+ /*lint -e{702} use shift for performance */
+ temp = pEnvParams->attackTime + ((pEnvParams->velToAttack * pVoice->velocity) >> 7);
+ *pIncrement = ConvertRate(temp);
+ return;
+ }
+
+ *pValue = SYNTH_FULL_SCALE_EG1_GAIN;
+ /*lint -e{825} falls through to next case */
+
+ case eEnvelopeStateAttack:
+ if (*pValue < SYNTH_FULL_SCALE_EG1_GAIN)
+ {
+ temp = *pValue + *pIncrement;
+ *pValue = (EAS_I16) (temp < SYNTH_FULL_SCALE_EG1_GAIN ? temp : SYNTH_FULL_SCALE_EG1_GAIN);
+ return;
+ }
+
+ /* calculate hold time */
+ *pState = eEnvelopeStateHold;
+ if (pEnvParams->holdTime != ZERO_TIME_IN_CENTS)
+ {
+ /*lint -e{702} use shift for performance */
+ temp = pEnvParams->holdTime + ((pEnvParams->keyNumToHold * pVoice->note) >> 7);
+ *pIncrement = ConvertDelay(temp);
+ return;
+ }
+ else
+ *pIncrement = 0;
+ /*lint -e{825} falls through to next case */
+
+ case eEnvelopeStateHold:
+ if (*pIncrement)
+ {
+ *pIncrement = *pIncrement - 1;
+ return;
+ }
+
+ /* calculate decay rate */
+ *pState = eEnvelopeStateDecay;
+ if (pEnvParams->decayTime != ZERO_TIME_IN_CENTS)
+ {
+ /*lint -e{702} use shift for performance */
+ temp = pEnvParams->decayTime + ((pEnvParams->keyNumToDecay * pVoice->note) >> 7);
+ *pIncrement = ConvertRate(temp);
+ return;
+ }
+
+// *pValue = pEnvParams->sustainLevel;
+ /*lint -e{825} falls through to next case */
+
+ case eEnvelopeStateDecay:
+ if (*pValue > pEnvParams->sustainLevel)
+ {
+ temp = *pValue - *pIncrement;
+ *pValue = (EAS_I16) (temp > pEnvParams->sustainLevel ? temp : pEnvParams->sustainLevel);
+ return;
+ }
+
+ *pState = eEnvelopeStateSustain;
+ *pValue = pEnvParams->sustainLevel;
+ /*lint -e{825} falls through to next case */
+
+ case eEnvelopeStateSustain:
+ return;
+
+ case eEnvelopeStateRelease:
+ temp = *pValue - *pIncrement;
+ if (temp <= 0)
+ {
+ *pState = eEnvelopeStateMuted;
+ *pValue = 0;
+ }
+ else
+ *pValue = (EAS_I16) temp;
+ break;
+
+ case eEnvelopeStateMuted:
+ *pValue = 0;
+ return;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Envelope in invalid state %d\n", *pState); */ }
+ break;
+ }
+}
+
diff --git a/arm-wt-22k/lib_src/eas_dlssynth.h b/arm-wt-22k/lib_src/eas_dlssynth.h
new file mode 100644
index 0000000..0dab41e
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_dlssynth.h
@@ -0,0 +1,41 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_dlssynth.h
+ *
+ * Contents and purpose:
+ * Implements the Mobile DLS synthesizer.
+ *
+ * Copyright Sonic Network Inc. 2006
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 143 $
+ * $Date: 2006-07-17 14:09:35 -0700 (Mon, 17 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_DLSSYNTH_H
+#define _EAS_DLSSYNTH_H
+
+/* prototypes */
+void DLS_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+void DLS_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
+void DLS_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
+EAS_RESULT DLS_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
+EAS_BOOL DLS_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_effects.h b/arm-wt-22k/lib_src/eas_effects.h
new file mode 100644
index 0000000..01e64c0
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_effects.h
@@ -0,0 +1,61 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_effects.h
+ *
+ * Contents and purpose:
+ * Defines a generic effects interface.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_EFFECTS_H
+#define _EAS_EFFECTS_H
+
+#include "eas_types.h"
+
+typedef struct
+{
+ EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+ void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_PCM *in, EAS_PCM *out, EAS_I32 numSamples);
+ EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+} S_EFFECTS_INTERFACE;
+
+typedef struct
+{
+ EAS_RESULT (*pfInit)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR *pInstData);
+ void (*pfProcess)(EAS_VOID_PTR pInstData, EAS_I32 *in, EAS_I32 *out, EAS_I32 numSamples);
+ EAS_RESULT (*pfShutdown)(EAS_DATA_HANDLE pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (*pFGetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (*pFSetParam)(EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+} S_EFFECTS32_INTERFACE;
+
+/* mixer instance data */
+typedef struct
+{
+ S_EFFECTS_INTERFACE *effect;
+ EAS_VOID_PTR effectData;
+} S_EFFECTS_MODULE;
+
+#endif /* end _EAS_EFFECTS_H */
+
diff --git a/arm-wt-22k/lib_src/eas_flog.c b/arm-wt-22k/lib_src/eas_flog.c
new file mode 100644
index 0000000..647da2f
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_flog.c
@@ -0,0 +1,96 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_flog2.c
+ *
+ * Contents and purpose:
+ * Fixed point square root
+ *
+ *
+ * Copyright (c) 2006 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision$
+ * $Date$
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_math.h"
+
+#define MANTISSA_SHIFT 27
+#define MANTISSA_MASK 0x0000000f
+#define MANTISSA_LSB_SHIFT 7
+#define MANTISSA_LSB_MASK 0x000fffff
+#define LOG_EXPONENT_SHIFT 10
+#define INTERPOLATION_SHIFT 20
+#define MAX_NEGATIVE (-2147483647-1)
+
+/* log lookup table */
+static const EAS_U16 eas_log2_table[] =
+{
+ 0, 90, 174, 254, 330, 402, 470, 536,
+ 599, 659, 717, 773, 827, 879, 929, 977,
+ 1024
+};
+
+/*----------------------------------------------------------------------------
+ * EAS_flog2()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the log2 of a 32-bit fixed point value
+ *
+ * Inputs:
+ * n = value of interest
+ *
+ * Outputs:
+ * returns the log2 of n
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_flog2 (EAS_U32 n)
+{
+ EAS_U32 exp;
+ EAS_U32 interp;
+
+ /* check for error condition */
+ if (n == 0)
+ return MAX_NEGATIVE;
+
+ /* find exponent */
+ for (exp = 31; exp > 0; exp--)
+ {
+ /* shift until we get a 1 bit in bit 31 */
+ if ((n & (EAS_U32) MAX_NEGATIVE) != 0)
+ break;
+ n <<= 1;
+ }
+ /*lint -e{701} use shift for performance */
+ exp <<= LOG_EXPONENT_SHIFT;
+
+ /* get the least significant bits for interpolation */
+ interp = (n >> MANTISSA_LSB_SHIFT) & MANTISSA_LSB_MASK;
+
+ /* get the most significant bits for mantissa lookup */
+ n = (n >> MANTISSA_SHIFT) & MANTISSA_MASK;
+
+ /* interpolate mantissa */
+ interp = ((eas_log2_table[n+1] - eas_log2_table[n]) * interp) >> INTERPOLATION_SHIFT;
+ exp += eas_log2_table[n] + interp;
+
+ return (EAS_I32) exp;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_ima_tables.c b/arm-wt-22k/lib_src/eas_ima_tables.c
new file mode 100644
index 0000000..56bd1eb
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_ima_tables.c
@@ -0,0 +1,54 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ima_tables.c
+ *
+ * Contents and purpose:
+ * Contains the constant tables for IMA encode/decode
+ *
+ * Copyright (c) 2005 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 760 $
+ * $Date: 2007-07-17 23:09:36 -0700 (Tue, 17 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+
+/*----------------------------------------------------------------------------
+ * ADPCM decode tables
+ *----------------------------------------------------------------------------
+*/
+const EAS_I16 imaIndexTable[16] =
+{
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+};
+
+const EAS_I16 imaStepSizeTable[89] =
+{
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
diff --git a/arm-wt-22k/lib_src/eas_imaadpcm.c b/arm-wt-22k/lib_src/eas_imaadpcm.c
new file mode 100644
index 0000000..68bf257
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_imaadpcm.c
@@ -0,0 +1,368 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imaadpcm.c
+ *
+ * Contents and purpose:
+ * Implements the IMA ADPCM decoder
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 847 $
+ * $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_host.h"
+#include "eas_pcm.h"
+#include "eas_math.h"
+#include "eas_report.h"
+
+// #define _DEBUG_IMA_ADPCM_LOCATE
+
+/*----------------------------------------------------------------------------
+ * externs
+ *----------------------------------------------------------------------------
+*/
+extern const EAS_I16 imaIndexTable[];
+extern const EAS_I16 imaStepSizeTable[];
+
+/*----------------------------------------------------------------------------
+ * prototypes
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble);
+static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+
+/*----------------------------------------------------------------------------
+ * IMA ADPCM Decoder interface
+ *----------------------------------------------------------------------------
+*/
+const S_DECODER_INTERFACE IMADecoder =
+{
+ IMADecoderInit,
+ IMADecoderSample,
+ IMADecoderLocate
+};
+
+/*----------------------------------------------------------------------------
+ * IMADecoderInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the IMA ADPCM decoder
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ pState->decoderL.step = 0;
+ pState->decoderR.step = 0;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderSample()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes an IMA ADPCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
+{
+ EAS_RESULT result;
+ EAS_I16 sTemp;
+
+ /* if high nibble, decode */
+ if (pState->hiNibble)
+ {
+ IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte >> 4));
+ pState->hiNibble = EAS_FALSE;
+ }
+
+ /* low nibble, need to fetch another byte */
+ else
+ {
+ /* check for loop */
+ if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
+ {
+ /* seek to start of loop */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
+ return result;
+ pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
+ pState->blockCount = 0;
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMADecoderSample: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
+ }
+
+ /* if start of block, fetch new predictor and step index */
+ if ((pState->blockSize != 0) && (pState->blockCount == 0) && (pState->bytesLeft != 0))
+ {
+
+ /* get predicted sample for left channel */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Predictor: Was %d, now %d\n", pState->decoderL.acc, sTemp); */ }
+#endif
+ pState->decoderL.acc = pState->decoderL.x1 = sTemp;
+
+ /* get step index for left channel - upper 8 bits are reserved */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderL.step, sTemp); */ }
+#endif
+ pState->decoderL.step = sTemp & 0xff;
+
+ if (pState->flags & PCM_FLAGS_STEREO)
+ {
+ /* get predicted sample for right channel */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pState->decoderR.acc = pState->decoderR.x1 = sTemp;
+
+ /* get step index for right channel - upper 8 bits are reserved */
+ if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderR.step, sTemp); */ }
+#endif
+ pState->decoderR.step = sTemp & 0xff;
+
+ pState->blockCount = pState->blockSize - 8;
+ pState->bytesLeft -= 8;
+ }
+ else
+ {
+ pState->blockCount = pState->blockSize - 4;
+ pState->bytesLeft -= 4;
+ }
+ }
+ else
+ {
+
+ /* get another ADPCM data pair */
+ if (pState->bytesLeft)
+ {
+
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
+ return result;
+
+ /* decode the low nibble */
+ pState->bytesLeft--;
+ pState->blockCount--;
+ IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte & 0x0f));
+
+ if (pState->flags & PCM_FLAGS_STEREO)
+ IMADecoderADPCM(&pState->decoderR, (EAS_U8)(pState->srcByte >> 4));
+ else
+ pState->hiNibble = EAS_TRUE;
+ }
+
+ /* out of ADPCM data, generate enough samples to fill buffer */
+ else
+ {
+ pState->decoderL.x1 = pState->decoderL.x0;
+ pState->decoderR.x1 = pState->decoderR.x0;
+ }
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderADPCM()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes an IMA ADPCM sample
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble)
+{
+ EAS_INT delta;
+ EAS_INT stepSize;
+
+ /* get stepsize from table */
+ stepSize = imaStepSizeTable[pState->step];
+
+ /* delta = (abs(delta) + 0.5) * step / 4 */
+ delta = 0;
+ if (nibble & 4)
+ delta += stepSize;
+
+ if (nibble & 2)
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 1;
+
+ if (nibble & 1)
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 2;
+
+ /*lint -e{702} use shift for performance */
+ delta += stepSize >> 3;
+
+ /* integrate the delta */
+ if (nibble & 8)
+ pState->acc -= delta;
+ else
+ pState->acc += delta;
+
+ /* saturate */
+ if (pState->acc > 32767)
+ pState->acc = 32767;
+ if (pState->acc < -32768)
+ pState->acc = -32768;
+ pState->x1 = (EAS_PCM) pState->acc;
+
+ /* compute new step size */
+ pState->step += imaIndexTable[nibble];
+ if (pState->step < 0)
+ pState->step = 0;
+ if (pState->step > 88)
+ pState->step = 88;
+
+#ifdef _DEBUG_IMA_ADPCM
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "In=%u, Pred=%d, Step=%d\n", nibble, pState->acc, imaStepSizeTable[pState->step]); */ }
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * IMADecoderLocate()
+ *----------------------------------------------------------------------------
+ * Locate in an IMA ADPCM stream
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
+{
+ EAS_RESULT result;
+ EAS_I32 temp;
+ EAS_I32 samplesPerBlock;
+ EAS_I32 secs, msecs;
+
+ /* no need to calculate if time is zero */
+ if (time == 0)
+ temp = 0;
+
+ /* not zero */
+ else
+ {
+
+ /* can't seek if not a blocked file */
+ if (pState->blockSize == 0)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ /* calculate number of samples per block */
+ if (pState->flags & PCM_FLAGS_STEREO)
+ samplesPerBlock = pState->blockSize - 7;
+ else
+ samplesPerBlock = (pState->blockSize << 1) - 7;
+
+ /* break down into secs and msecs */
+ secs = time / 1000;
+ msecs = time - (secs * 1000);
+
+ /* calculate sample number fraction from msecs */
+ temp = (msecs * pState->sampleRate);
+ temp = (temp >> 10) + ((temp * 49) >> 21);
+
+ /* add integer sample count */
+ temp += secs * pState->sampleRate;
+
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000006 , time, temp);
+#endif
+
+ /* for looped samples, calculate position in the loop */
+ if ((temp > pState->byteCount) && (pState->loopSamples != 0))
+ {
+ EAS_I32 numBlocks;
+ EAS_I32 samplesPerLoop;
+ EAS_I32 samplesInLastBlock;
+
+ numBlocks = (EAS_I32) (pState->loopStart / pState->blockSize);
+ samplesInLastBlock = (EAS_I32) pState->loopStart - (numBlocks * pState->blockSize);
+ if (samplesInLastBlock)
+ {
+ if (pState->flags & PCM_FLAGS_STEREO)
+ samplesInLastBlock = samplesInLastBlock - 7;
+ else
+ /*lint -e{703} use shift for performance */
+ samplesInLastBlock = (samplesInLastBlock << 1) - 7;
+ }
+ samplesPerLoop = numBlocks * samplesPerBlock + samplesInLastBlock;
+ temp = temp % samplesPerLoop;
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000007 , numBlocks, samplesPerLoop, samplesInLastBlock, temp);
+#endif
+ }
+
+ /* find start of block for requested sample */
+ temp = (temp / samplesPerBlock) * pState->blockSize;
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000008 , temp);
+#endif
+
+ }
+
+ /* seek to new location */
+ if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMA_ADPCM_LOCATE
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000009 , pState->bytesLeft);
+#endif
+
+ /* reset state */
+ pState->blockCount = 0;
+ pState->hiNibble = EAS_FALSE;
+ if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
+ pState->state = EAS_STATE_READY;
+
+ return EAS_SUCCESS;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_imelody.c b/arm-wt-22k/lib_src/eas_imelody.c
new file mode 100644
index 0000000..5b7e7b8
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_imelody.c
@@ -0,0 +1,1742 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelody.c
+ *
+ * Contents and purpose:
+ * iMelody parser
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 797 $
+ * $Date: 2007-08-01 00:15:56 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* lint doesn't like the way some string.h files look */
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <string.h>
+#endif
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_imelodydata.h"
+#include "eas_ctype.h"
+
+// #define _DEBUG_IMELODY
+
+/* increase gain for mono ringtones */
+#define IMELODY_GAIN_OFFSET 8
+
+/* length of 32nd note in 1/256ths of a msec for 120 BPM tempo */
+#define DEFAULT_TICK_CONV 16000
+#define TICK_CONVERT 1920000
+
+/* default channel and program for iMelody playback */
+#define IMELODY_CHANNEL 0
+#define IMELODY_PROGRAM 80
+#define IMELODY_VEL_MUL 4
+#define IMELODY_VEL_OFS 67
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+static const char* const tokens[] =
+{
+ "BEGIN:IMELODY",
+ "VERSION:",
+ "FORMAT:CLASS",
+ "NAME:",
+ "COMPOSER:",
+ "BEAT:",
+ "STYLE:",
+ "VOLUME:",
+ "MELODY:",
+ "END:IMELODY"
+};
+
+/* ledon or ledoff */
+static const char ledStr[] = "edo";
+
+/* vibeon or vibeoff */
+static const char vibeStr[] = "ibeo";
+
+/* backon or backoff */
+static const char backStr[] = "cko";
+
+typedef enum
+{
+ TOKEN_BEGIN,
+ TOKEN_VERSION,
+ TOKEN_FORMAT,
+ TOKEN_NAME,
+ TOKEN_COMPOSER,
+ TOKEN_BEAT,
+ TOKEN_STYLE,
+ TOKEN_VOLUME,
+ TOKEN_MELODY,
+ TOKEN_END,
+ TOKEN_INVALID
+} ENUM_IMELODY_TOKENS;
+
+/* lookup table for note values */
+static const EAS_I8 noteTable[] = { 9, 11, 0, 2, 4, 5, 7 };
+
+/* inline functions */
+#ifdef _DEBUG_IMELODY
+static void PutBackChar (S_IMELODY_DATA *pData)
+{
+ if (pData->index)
+ pData->index--;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "PutBackChar '%c'\n", pData->buffer[pData->index]); */ }
+}
+#else
+EAS_INLINE void PutBackChar (S_IMELODY_DATA *pData) { if (pData->index) pData->index--; }
+#endif
+
+
+/* local prototypes */
+static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode);
+static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration);
+static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData);
+static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
+static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader);
+static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData);
+static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader);
+static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine);
+static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_iMelody_Parser
+ *
+ * This structure contains the functional interface for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_iMelody_Parser =
+{
+ IMY_CheckFileType,
+ IMY_Prepare,
+ IMY_Time,
+ IMY_Event,
+ IMY_State,
+ IMY_Close,
+ IMY_Reset,
+ IMY_Pause,
+ IMY_Resume,
+ NULL,
+ IMY_SetData,
+ IMY_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * IMY_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_IMELODY_DATA* pData;
+ EAS_I8 buffer[MAX_LINE_SIZE+1];
+ EAS_U8 index;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_CheckFileType\n"); */ }
+#endif
+
+ /* read the first line of the file */
+ *ppHandle = NULL;
+ if (IMY_ReadLine(pEASData->hwInstData, fileHandle, buffer, NULL) != EAS_SUCCESS)
+ return EAS_SUCCESS;
+
+ /* check for header string */
+ if (IMY_ParseLine(buffer, &index) == TOKEN_BEGIN)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_IMELODY_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_IMELODY_DATA));
+ if (!pData)
+ return EAS_ERROR_MALLOC_FAILED;
+ EAS_HWMemSet(pData, 0, sizeof(S_IMELODY_DATA));
+
+ /* initialize */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_ERROR;
+ pData->state = EAS_STATE_OPEN;
+
+ /* return a pointer to the instance data */
+ *ppHandle = pData;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_Prepare\n"); */ }
+#endif
+
+ /* check for valid state */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ /* parse the header */
+ if ((result = IMY_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Prepare: state set to EAS_STATE_READY\n"); */ }
+#endif
+
+ pData ->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+ EAS_I8 c;
+ EAS_BOOL eof;
+ EAS_INT temp;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ if (pData->state == EAS_STATE_READY) {
+ pData->state = EAS_STATE_PLAY;
+ }
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: Reset\n"); */ }
+#endif
+ /* set program to square lead */
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, IMELODY_PROGRAM);
+
+ /* set channel volume to max */
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Stopping note %d\n", pData->note); */ }
+#endif
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* parse the next event */
+ eof = EAS_FALSE;
+ while (!eof)
+ {
+
+ /* get next character */
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+
+ switch (c)
+ {
+ /* start repeat */
+ case '(':
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter repeat section\n", c); */ }
+#endif
+
+ if (pData->repeatOffset < 0)
+ {
+ pData->repeatOffset = pData->startLine + (EAS_I32) pData->index;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat offset = %d\n", pData->repeatOffset); */ }
+#endif
+ }
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring nested repeat section\n"); */ }
+ break;
+
+ /* end repeat */
+ case ')':
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "End repeat section, repeat offset = %d\n", pData->repeatOffset); */ }
+#endif
+ /* ignore invalid repeats */
+ if (pData->repeatCount >= 0)
+ {
+
+ /* decrement repeat count (repeatCount == 0 means infinite loop) */
+ if (pData->repeatCount > 0)
+ {
+ if (--pData->repeatCount == 0)
+ {
+ pData->repeatCount = -1;
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat loop complete\n"); */ }
+#endif
+ }
+ }
+
+//2 TEMPORARY FIX: If locating, don't do infinite loops.
+//3 We need a different mode for metadata parsing where we don't loop at all
+ if ((parserMode == eParserModePlay) || (pData->repeatCount != 0))
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Rewinding file for repeat\n"); */ }
+#endif
+ /* rewind to start of loop */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS)
+ return result;
+ IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine);
+ pData->index = 0;
+
+ /* if last loop, prevent future loops */
+ if (pData->repeatCount == -1)
+ pData->repeatOffset = -1;
+ }
+ }
+ break;
+
+ /* repeat count */
+ case '@':
+ if (!IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_FALSE))
+ eof = EAS_TRUE;
+ else if (pData->repeatOffset > 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat count = %dt", pData->repeatCount); */ }
+#endif
+ if (pData->repeatCount < 0)
+ pData->repeatCount = (EAS_I16) temp;
+ }
+ break;
+
+ /* volume */
+ case 'V':
+ if (!IMY_GetVolume(pEASData->hwInstData, pData, EAS_FALSE))
+ eof = EAS_TRUE;
+ break;
+
+ /* flat */
+ case '&':
+ pData->noteModifier = -1;
+ break;
+
+ /* sharp */
+ case '#':
+ pData->noteModifier = +1;
+ break;
+
+ /* octave */
+ case '*':
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (IsDigit(c))
+ pData->octave = (EAS_U8) ((c - '0' + 1) * 12);
+ else if (!c)
+ eof = EAS_TRUE;
+ break;
+
+ /* ledon or ledoff */
+ case 'l':
+ if (!IMY_GetLEDState(pEASData, pData))
+ eof = EAS_TRUE;
+ break;
+
+ /* vibeon or vibeoff */
+ case 'v':
+ if (!IMY_GetVibeState(pEASData, pData))
+ eof = EAS_TRUE;
+ break;
+
+ /* either a B note or backon or backoff */
+ case 'b':
+ if (IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE) == 'a')
+ {
+ if (!IMY_GetBackState(pEASData, pData))
+ eof = EAS_TRUE;
+ }
+ else
+ {
+ PutBackChar(pData);
+ if (IMY_PlayNote(pEASData, pData, c, parserMode))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ }
+ break;
+
+ /* rest */
+ case 'r':
+ case 'R':
+ if (IMY_PlayRest(pEASData, pData))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ break;
+
+ /* EOF */
+ case 0:
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: end of iMelody file detected\n"); */ }
+#endif
+ eof = EAS_TRUE;
+ break;
+
+ /* must be a note */
+ default:
+ c = ToLower(c);
+ if ((c >= 'a') && (c <= 'g'))
+ {
+ if (IMY_PlayNote(pEASData, pData, c, parserMode))
+ return EAS_SUCCESS;
+ eof = EAS_TRUE;
+ }
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unexpected character '%c' [0x%02x]\n", c, c); */ }
+ break;
+ }
+ }
+
+ /* handle EOF */
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Event: state set to EAS_STATE_STOPPING\n"); */ }
+#endif
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_IMELODY_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ {
+ pData->state = EAS_STATE_STOPPED;
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_STOPPED\n"); */ }
+#endif
+ }
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_State: state set to EAS_STATE_PAUSED\n"); */ }
+#endif
+ pData->state = EAS_STATE_PAUSED;
+ }
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Close: close file\n"); */ }
+#endif
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA* pData;
+ EAS_RESULT result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: reset file\n"); */ }
+#endif
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+
+ /* reset time to zero */
+ pData->time = 0;
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+ if ((result = IMY_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Reset: state set to EAS_STATE_ERROR\n"); */ }
+#endif
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA *pData;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Pause: pause file\n"); */ }
+#endif
+
+ /* can't pause a stopped stream */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_IMELODY_DATA *pData;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_Resume: resume file\n"); */ }
+#endif
+
+ /* can't resume a stopped stream */
+ pData = (S_IMELODY_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Adjust tempo relative to song tempo
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pInstData - pointer to iMelody instance data
+ * rate - rate (28-bit fractional amount)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return the file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pInstData - pointer to iMelody instance data
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT IMY_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_IMELODY_DATA *pData;
+
+ pData = (S_IMELODY_DATA*) pInstData;
+
+ switch (param)
+ {
+ /* return file type as iMelody */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_IMELODY;
+ break;
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = IMELODY_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_PlayNote()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_PlayNote (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData, EAS_I8 note, EAS_INT parserMode)
+{
+ EAS_I32 duration;
+ EAS_U8 velocity;
+
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: start note %d\n", note); */ }
+#endif
+
+ /* get the duration */
+ if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
+ return EAS_FALSE;
+
+ /* save note value */
+ pData->note = (EAS_U8) (pData->octave + noteTable[note - 'a'] + pData->noteModifier);
+ velocity = (EAS_U8) (pData->volume ? pData->volume * IMELODY_VEL_MUL + IMELODY_VEL_OFS : 0);
+
+ /* start note only if in play mode */
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, IMELODY_CHANNEL, pData->note, velocity);
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayNote: Start note %d, duration %d\n", pData->note, duration); */ }
+#endif
+
+ /* determine note length */
+ switch (pData->style)
+ {
+ case 0:
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 4;
+ break;
+ case 1:
+ pData->restTicks = 0;
+ break;
+ case 2:
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 1;
+ break;
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "IMY_PlayNote: Note style out of range: %d\n", pData->style); */ }
+ /*lint -e{704} shift for performance */
+ pData->restTicks = duration >> 4;
+ break;
+ }
+
+ /* next event is at end of this note */
+ pData->time += duration - pData->restTicks;
+
+ /* reset the flat/sharp modifier */
+ pData->noteModifier = 0;
+
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_PlayRest()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_PlayRest (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I32 duration;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_PlayRest]n"); */ }
+#endif
+
+ /* get the duration */
+ if (!IMY_GetDuration(pEASData->hwInstData, pData, &duration))
+ return EAS_FALSE;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_PlayRest: note duration %d\n", duration); */ }
+#endif
+
+ /* next event is at end of this note */
+ pData->time += duration;
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetDuration()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_BOOL IMY_GetDuration (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_I32 *pDuration)
+{
+ EAS_I32 duration;
+ EAS_I8 c;
+
+ /* get the duration */
+ *pDuration = 0;
+ c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ if ((c < '0') || (c > '5'))
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetDuration: error in duration '%c'\n", c); */ }
+#endif
+ return EAS_FALSE;
+ }
+
+ /* calculate total length of note */
+ duration = pData->tick * (1 << ('5' - c));
+
+ /* check for duration modifier */
+ c = IMY_GetNextChar(hwInstData, pData, EAS_FALSE);
+ if (c)
+ {
+ if (c == '.')
+ /*lint -e{704} shift for performance */
+ duration += duration >> 1;
+ else if (c == ':')
+ /*lint -e{704} shift for performance */
+ duration += (duration >> 1) + (duration >> 2);
+ else if (c == ';')
+ /*lint -e{704} shift for performance */
+ duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
+ else
+ PutBackChar(pData);
+ }
+
+ *pDuration = duration;
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetLEDState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetLEDState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetLEDState\n"); */ }
+#endif
+
+ for (i = 0; i < 5; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 3:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED on\n"); */ }
+#endif
+ EAS_HWLED(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 4:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetLEDState: LED off\n"); */ }
+#endif
+ EAS_HWLED(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != ledStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVibeState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVibeState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVibeState\n"); */ }
+#endif
+
+ for (i = 0; i < 6; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 4:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate on\n"); */ }
+#endif
+ EAS_HWVibrate(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 5:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVibeState: vibrate off\n"); */ }
+#endif
+ EAS_HWVibrate(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != vibeStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetBackState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetBackState (S_EAS_DATA *pEASData, S_IMELODY_DATA *pData)
+{
+ EAS_I8 c;
+ EAS_INT i;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetBackState\n"); */ }
+#endif
+
+ for (i = 0; i < 5; i++)
+ {
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_FALSE);
+ if (!c)
+ return EAS_FALSE;
+ switch (i)
+ {
+ case 3:
+ if (c == 'n')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight on\n"); */ }
+#endif
+ EAS_HWBackLight(pEASData->hwInstData, EAS_TRUE);
+ return EAS_TRUE;
+ }
+ else if (c != 'f')
+ return EAS_FALSE;
+ break;
+
+ case 4:
+ if (c == 'f')
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetBackState: backlight off\n"); */ }
+#endif
+ EAS_HWBackLight(pEASData->hwInstData, EAS_FALSE);
+ return EAS_TRUE;
+ }
+ return EAS_FALSE;
+
+ default:
+ if (c != backStr[i])
+ return EAS_FALSE;
+ break;
+ }
+ }
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVolume (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
+{
+ EAS_INT temp;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetVolume\n"); */ }
+#endif
+
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (c == '+')
+ {
+ if (pData->volume < 15)
+ pData->volume++;
+ return EAS_TRUE;
+ }
+ else if (c == '-')
+ {
+ if (pData->volume > 0)
+ pData->volume--;
+ return EAS_TRUE;
+ }
+ else if (IsDigit(c))
+ temp = c - '0';
+ else
+ return EAS_FALSE;
+
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (IsDigit(c))
+ temp = temp * 10 + c - '0';
+ else if (c)
+ PutBackChar(pData);
+ if ((temp >= 0) && (temp <= 15))
+ {
+ if (inHeader && (temp == 0))
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring V0 encountered in header\n"); */ }
+ else
+ pData->volume = (EAS_U8) temp;
+ }
+ return EAS_TRUE;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetNumber()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetNumber (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_INT *temp, EAS_BOOL inHeader)
+{
+ EAS_BOOL ok;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_GetNumber\n"); */ }
+#endif
+
+ *temp = 0;
+ ok = EAS_FALSE;
+ for (;;)
+ {
+ c = IMY_GetNextChar(hwInstData, pData, inHeader);
+ if (IsDigit(c))
+ {
+ *temp = *temp * 10 + c - '0';
+ ok = EAS_TRUE;
+ }
+ else
+ {
+ if (c)
+ PutBackChar(pData);
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNumber: value %d\n", *temp); */ }
+#endif
+
+ return ok;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetVersion()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL IMY_GetVersion (S_IMELODY_DATA *pData, EAS_INT *pVersion)
+{
+ EAS_I8 c;
+ EAS_INT temp;
+ EAS_INT version;
+
+ version = temp = 0;
+ for (;;)
+ {
+ c = pData->buffer[pData->index++];
+ if ((c == 0) || (c == '.'))
+ {
+ /*lint -e{701} use shift for performance */
+ version = (version << 8) + temp;
+ if (c == 0)
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetVersion: version 0x%04x\n", version); */ }
+#endif
+
+ *pVersion = version;
+ return EAS_TRUE;
+ }
+ temp = 0;
+ }
+ else if (IsDigit(c))
+ temp = (temp * 10) + c - '0';
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_MetaData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void IMY_MetaData (S_IMELODY_DATA *pData, E_EAS_METADATA_TYPE metaType, EAS_I8 *buffer)
+{
+ EAS_I32 len;
+
+ /* check for callback */
+ if (!pData->metadata.callback)
+ return;
+
+ /* copy data to host buffer */
+ len = (EAS_I32) strlen((char*) buffer);
+ if (len >pData->metadata.bufferSize)
+ len = pData->metadata.bufferSize;
+ strncpy((char*) pData->metadata.buffer, (char*) buffer, (size_t) len);
+ pData->metadata.buffer[len] = 0;
+
+ /* callback to host */
+ pData->metadata.callback(metaType, pData->metadata.buffer, pData->metadata.pUserData);
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_ParseHeader (S_EAS_DATA *pEASData, S_IMELODY_DATA* pData)
+{
+ EAS_RESULT result;
+ EAS_INT token;
+ EAS_INT temp;
+ EAS_I8 c;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Enter IMY_ParseHeader\n"); */ }
+#endif
+
+ /* initialize some defaults */
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->note = 0;
+ pData->noteModifier = 0;
+ pData ->restTicks = 0;
+ pData->volume = 7;
+ pData->octave = 60;
+ pData->repeatOffset = -1;
+ pData->repeatCount = -1;
+ pData->style = 0;
+
+ /* force the read of the first line */
+ pData->index = 1;
+
+ /* read data until we get to melody */
+ for (;;)
+ {
+ /* read a line from the file and parse the token */
+ if (pData->index != 0)
+ {
+ if ((result = IMY_ReadLine(pEASData->hwInstData, pData->fileHandle, pData->buffer, &pData->startLine)) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: IMY_ReadLine returned %d\n", result); */ }
+#endif
+ return result;
+ }
+ }
+ token = IMY_ParseLine(pData->buffer, &pData->index);
+
+ switch (token)
+ {
+ /* ignore these valid tokens */
+ case TOKEN_BEGIN:
+ break;
+
+ case TOKEN_FORMAT:
+ if (!IMY_GetVersion(pData, &temp))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid FORMAT field '%s'\n", pData->buffer); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ if ((temp != 0x0100) && (temp != 0x0200))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported FORMAT %02x\n", temp); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+ break;
+
+ case TOKEN_VERSION:
+ if (!IMY_GetVersion(pData, &temp))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid VERSION field '%s'\n", pData->buffer); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ if ((temp != 0x0100) && (temp != 0x0102))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported VERSION %02x\n", temp); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+ break;
+
+ case TOKEN_NAME:
+ IMY_MetaData(pData, EAS_METADATA_TITLE, pData->buffer + pData->index);
+ break;
+
+ case TOKEN_COMPOSER:
+ IMY_MetaData(pData, EAS_METADATA_AUTHOR, pData->buffer + pData->index);
+ break;
+
+ /* handle beat */
+ case TOKEN_BEAT:
+ IMY_GetNumber(pEASData->hwInstData, pData, &temp, EAS_TRUE);
+ if ((temp >= 25) && (temp <= 900))
+ pData->tick = TICK_CONVERT / temp;
+ break;
+
+ /* handle style */
+ case TOKEN_STYLE:
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if (c == 'S')
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if ((c >= '0') && (c <= '2'))
+ pData->style = (EAS_U8) (c - '0');
+ else
+ {
+ PutBackChar(pData);
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in style command: %s\n", pData->buffer); */ }
+ }
+ break;
+
+ /* handle volume */
+ case TOKEN_VOLUME:
+ c = IMY_GetNextChar(pEASData->hwInstData, pData, EAS_TRUE);
+ if (c != 'V')
+ {
+ PutBackChar(pData);
+ if (!IsDigit(c))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error in volume command: %s\n", pData->buffer); */ }
+ break;
+ }
+ }
+ IMY_GetVolume(pEASData->hwInstData, pData, EAS_TRUE);
+ break;
+
+ case TOKEN_MELODY:
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Header successfully parsed\n"); */ }
+#endif
+ return EAS_SUCCESS;
+
+ case TOKEN_END:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unexpected END:IMELODY encountered\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+
+ default:
+ /* force a read of the next line */
+ pData->index = 1;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized token in iMelody file: %s\n", pData->buffer); */ }
+ break;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_GetNextChar()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_I8 IMY_GetNextChar (EAS_HW_DATA_HANDLE hwInstData, S_IMELODY_DATA *pData, EAS_BOOL inHeader)
+{
+ EAS_I8 c;
+ EAS_U8 index;
+
+ for (;;)
+ {
+ /* get next character */
+ c = pData->buffer[pData->index++];
+
+ /* buffer empty, read more */
+ if (!c)
+ {
+ /* don't read the next line in the header */
+ if (inHeader)
+ return 0;
+
+ pData->index = 0;
+ pData->buffer[0] = 0;
+ if (IMY_ReadLine(hwInstData, pData->fileHandle, pData->buffer, &pData->startLine) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: EOF\n"); */ }
+#endif
+ return 0;
+ }
+
+ /* check for END:IMELODY token */
+ if (IMY_ParseLine(pData->buffer, &index) == TOKEN_END)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar: found END:IMELODY\n"); */ }
+#endif
+ pData->buffer[0] = 0;
+ return 0;
+ }
+ continue;
+ }
+
+ /* ignore white space */
+ if (!IsSpace(c))
+ {
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_GetNextChar returned '%c'\n", c); */ }
+#endif
+ return c;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ReadLine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a line of input from the file, discarding the CR/LF
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT IMY_ReadLine (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I8 *buffer, EAS_I32 *pStartLine)
+{
+ EAS_RESULT result;
+ EAS_INT i;
+ EAS_I8 c;
+
+ /* fetch current file position and save it */
+ if (pStartLine != NULL)
+ {
+ if ((result = EAS_HWFilePos(hwInstData, fileHandle, pStartLine)) != EAS_SUCCESS)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseHeader: EAS_HWFilePos returned %d\n", result); */ }
+#endif
+ return result;
+ }
+ }
+
+ buffer[0] = 0;
+ for (i = 0; i < MAX_LINE_SIZE; )
+ {
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
+ {
+ if ((result == EAS_EOF) && (i > 0))
+ break;
+ return result;
+ }
+
+ /* return on LF or end of data */
+ if (c == '\n')
+ break;
+
+ /* store characters in buffer */
+ if (c != '\r')
+ buffer[i++] = c;
+ }
+ buffer[i] = 0;
+
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ReadLine read %s\n", buffer); */ }
+#endif
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * IMY_ParseLine()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_INT IMY_ParseLine (EAS_I8 *buffer, EAS_U8 *pIndex)
+{
+ EAS_INT i;
+ EAS_INT j;
+
+ /* there's no strnicmp() in stdlib, so we have to roll our own */
+ for (i = 0; i < TOKEN_INVALID; i++)
+ {
+ for (j = 0; ; j++)
+ {
+ /* end of token, must be a match */
+ if (tokens[i][j] == 0)
+ {
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine found token %d\n", i); */ }
+#endif
+ *pIndex = (EAS_U8) j;
+ return i;
+ }
+ if (tokens[i][j] != ToUpper(buffer[j]))
+ break;
+ }
+ }
+#ifdef _DEBUG_IMELODY
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMY_ParseLine: no token found\n"); */ }
+#endif
+ return TOKEN_INVALID;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_imelodydata.c b/arm-wt-22k/lib_src/eas_imelodydata.c
new file mode 100644
index 0000000..e72dc0b
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_imelodydata.c
@@ -0,0 +1,43 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelodydata.c
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data definitions for the SMF parser.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_imelodydata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_iMelodyData
+ *
+ * Static memory allocation for iMelody parser
+ *----------------------------------------------------------------------------
+*/
+S_IMELODY_DATA eas_iMelodyData;
+
diff --git a/arm-wt-22k/lib_src/eas_imelodydata.h b/arm-wt-22k/lib_src/eas_imelodydata.h
new file mode 100644
index 0000000..303b8f6
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_imelodydata.h
@@ -0,0 +1,73 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_imelodydata.h
+ *
+ * Contents and purpose:
+ * SMF File Parser
+ *
+ * This file contains data declarations for the iMelody parser.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_IMELODYDATA_H
+#define EAS_IMELODYDATA_H
+
+#include "eas_data.h"
+
+/* maximum line size as specified in iMelody V1.2 spec */
+#define MAX_LINE_SIZE 75
+
+/*----------------------------------------------------------------------------
+ *
+ * S_IMELODY_DATA
+ *
+ * This structure contains the state data for the iMelody parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* pointer to synth */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_I32 tickBase; /* basline length of 32nd note in 256th of a msec */
+ EAS_I32 tick; /* actual length of 32nd note in 256th of a msec */
+ EAS_I32 restTicks; /* ticks to rest after current note */
+ EAS_I32 startLine; /* file offset at start of line (for repeats) */
+ EAS_I32 repeatOffset; /* file offset to start of repeat section */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I16 repeatCount; /* repeat counter */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 style; /* from STYLE */
+ EAS_U8 index; /* index into buffer */
+ EAS_U8 octave; /* octave prefix */
+ EAS_U8 volume; /* current volume */
+ EAS_U8 note; /* MIDI note number */
+ EAS_I8 noteModifier; /* sharp or flat */
+ EAS_I8 buffer[MAX_LINE_SIZE+1]; /* buffer for ASCII data */
+} S_IMELODY_DATA;
+
+#endif
+
+
diff --git a/arm-wt-22k/lib_src/eas_math.c b/arm-wt-22k/lib_src/eas_math.c
new file mode 100644
index 0000000..12d788e
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_math.c
@@ -0,0 +1,168 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_math.c
+ *
+ * Contents and purpose:
+ * Contains common math routines for the various audio engines.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 586 $
+ * $Date: 2007-03-08 20:33:04 -0800 (Thu, 08 Mar 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas.h"
+#include "eas_math.h"
+
+/* anything less than this converts to a fraction too small to represent in 32-bits */
+#define MIN_CENTS -18000
+
+/*----------------------------------------------------------------------------
+ * EAS_Calculate2toX()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate 2^x
+ *
+ * Inputs:
+ * nCents - measured in cents
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_Calculate2toX (EAS_I32 nCents)
+{
+ EAS_I32 nDents;
+ EAS_I32 nExponentInt, nExponentFrac;
+ EAS_I32 nTemp1, nTemp2;
+ EAS_I32 nResult;
+
+ /* check for minimum value */
+ if (nCents < MIN_CENTS)
+ return 0;
+
+ /* for the time being, convert cents to dents */
+ nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
+
+ nExponentInt = GET_DENTS_INT_PART(nDents);
+ nExponentFrac = GET_DENTS_FRAC_PART(nDents);
+
+ /*
+ implement 2^(fracPart) as a power series
+ */
+ nTemp1 = GN2_TO_X2 + MULT_DENTS_COEF(nExponentFrac, GN2_TO_X3);
+ nTemp2 = GN2_TO_X1 + MULT_DENTS_COEF(nExponentFrac, nTemp1);
+ nTemp1 = GN2_TO_X0 + MULT_DENTS_COEF(nExponentFrac, nTemp2);
+
+ /*
+ implement 2^(intPart) as
+ a left shift for intPart >= 0 or
+ a left shift for intPart < 0
+ */
+ if (nExponentInt >= 0)
+ {
+ /* left shift for positive exponents */
+ /*lint -e{703} <avoid multiply for performance>*/
+ nResult = nTemp1 << nExponentInt;
+ }
+ else
+ {
+ /* right shift for negative exponents */
+ nExponentInt = -nExponentInt;
+ nResult = nTemp1 >> nExponentInt;
+ }
+
+ return nResult;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_LogToLinear16()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform log value to linear gain multiplier using piece-wise linear
+ * approximation
+ *
+ * Inputs:
+ * nGain - log scale value in 20.10 format. Even though gain is normally
+ * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
+ * the need for saturation checking when combining gain values.
+ *
+ * Outputs:
+ * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain)
+{
+ EAS_INT nExp;
+ EAS_U16 nTemp;
+
+ /* bias to positive */
+ nGain += 32767;
+
+ /* check for infinite attenuation */
+ if (nGain < 0)
+ return 0;
+
+ /* extract the exponent */
+ nExp = 31 - (nGain >> 10);
+
+ /* check for maximum output */
+ if (nExp < 0)
+ return 0x7fff;
+
+ /* extract mantissa and restore implied 1 bit */
+ nTemp = (EAS_U16)((((nGain & 0x3ff) << 4) | 0x4000) >> nExp);
+
+ /* use shift to approximate power-of-2 operation */
+ return nTemp;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_VolumeToGain()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform volume control in 1dB increments to gain multiplier
+ *
+ * Inputs:
+ * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
+ *
+ * Outputs:
+ * Returns a 16-bit linear value
+ *----------------------------------------------------------------------------
+*/
+EAS_I16 EAS_VolumeToGain (EAS_INT volume)
+{
+ /* check for limits */
+ if (volume <= 0)
+ return 0;
+ if (volume >= 100)
+ return 0x7fff;
+
+ /*lint -e{702} use shift instead of division */
+ return (EAS_I16) EAS_Calculate2toX((((volume - EAS_MAX_VOLUME) * 204099) >> 10) - 1);
+}
+
diff --git a/arm-wt-22k/lib_src/eas_math.h b/arm-wt-22k/lib_src/eas_math.h
new file mode 100644
index 0000000..719270b
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_math.h
@@ -0,0 +1,412 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_math.h
+ *
+ * Contents and purpose:
+ * Contains common math routines for the various audio engines.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 584 $
+ * $Date: 2007-03-08 09:49:24 -0800 (Thu, 08 Mar 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MATH_H
+#define _EAS_MATH_H
+
+
+/** coefs for pan, generates sin, cos */
+#define COEFF_PAN_G2 -27146 /* -0.82842712474619 = 2 - 4/sqrt(2) */
+#define COEFF_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
+
+/*
+coefficients for approximating
+2^x = gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3
+where x is a int.frac number representing number of octaves.
+Actually, we approximate only the 2^(frac) using the power series
+and implement the 2^(int) as a shift, so that
+2^x == 2^(int.frac) == 2^(int) * 2^(fract)
+ == (gn2toX0 + gn2toX1*x + gn2toX2*x^2 + gn2toX3*x^3) << (int)
+
+The gn2toX.. were generated using a best fit for a 3rd
+order polynomial, instead of taking the coefficients from
+a truncated Taylor (or Maclaurin?) series.
+*/
+
+#define GN2_TO_X0 32768 /* 1 */
+#define GN2_TO_X1 22833 /* 0.696807861328125 */
+#define GN2_TO_X2 7344 /* 0.22412109375 */
+#define GN2_TO_X3 2588 /* 0.0789794921875 */
+
+/*----------------------------------------------------------------------------
+ * Fixed Point Math
+ *----------------------------------------------------------------------------
+ * These macros are used for fixed point multiplies. If the processor
+ * supports fixed point multiplies, replace these macros with inline
+ * assembly code to improve performance.
+ *----------------------------------------------------------------------------
+*/
+
+/* Fixed point multiply 0.15 x 0.15 = 0.15 returned as 32-bits */
+#define FMUL_15x15(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b)) >> 15)
+
+/* Fixed point multiply 0.7 x 0.7 = 0.15 returned as 32-bits */
+#define FMUL_7x7(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b) ) << 1)
+
+/* Fixed point multiply 0.8 x 0.8 = 0.15 returned as 32-bits */
+#define FMUL_8x8(a,b) \
+ /*lint -e(704) <avoid multiply for performance>*/ \
+ (((EAS_I32)(a) * (EAS_I32)(b) ) >> 1)
+
+/* Fixed point multiply 0.8 x 1.15 = 0.15 returned as 32-bits */
+#define FMUL_8x15(a,b) \
+ /*lint -e(704) <avoid divide for performance>*/ \
+ (((EAS_I32)((a) << 7) * (EAS_I32)(b)) >> 15)
+
+/* macros for fractional phase accumulator */
+/*
+Note: changed the _U32 to _I32 on 03/14/02. This should not
+affect the phase calculations, and should allow us to reuse these
+macros for other audio sample related math.
+*/
+#define HARDWARE_BIT_WIDTH 32
+
+#define NUM_PHASE_INT_BITS 1
+#define NUM_PHASE_FRAC_BITS 15
+
+#define PHASE_FRAC_MASK (EAS_U32) ((0x1L << NUM_PHASE_FRAC_BITS) -1)
+
+#define GET_PHASE_INT_PART(x) (EAS_U32)((EAS_U32)(x) >> NUM_PHASE_FRAC_BITS)
+#define GET_PHASE_FRAC_PART(x) (EAS_U32)((EAS_U32)(x) & PHASE_FRAC_MASK)
+
+#define DEFAULT_PHASE_FRAC 0
+#define DEFAULT_PHASE_INT 0
+
+/*
+Linear interpolation calculates:
+output = (1-frac) * sample[n] + (frac) * sample[n+1]
+
+where conceptually 0 <= frac < 1
+
+For a fixed point implementation, frac is actually an integer value
+with an implied binary point one position to the left. The value of
+one (unity) is given by PHASE_ONE
+one half and one quarter are useful for 4-point linear interp.
+*/
+#define PHASE_ONE (EAS_I32) (0x1L << NUM_PHASE_FRAC_BITS)
+
+/*
+ Multiply the signed audio sample by the unsigned fraction.
+- a is the signed audio sample
+- b is the unsigned fraction (cast to signed int as long as coef
+ uses (n-1) or less bits, where n == hardware bit width)
+*/
+#define MULT_AUDIO_COEF(audio,coef) /*lint -e704 <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_PHASE_FRAC_BITS \
+ ) \
+ /* lint +704 <restore checking>*/
+
+/* wet / dry calculation macros */
+#define NUM_WET_DRY_FRAC_BITS 7 // 15
+#define NUM_WET_DRY_INT_BITS 9 // 1
+
+/* define a 1.0 */
+#define WET_DRY_ONE (EAS_I32) ((0x1L << NUM_WET_DRY_FRAC_BITS))
+#define WET_DRY_MINUS_ONE (EAS_I32) (~WET_DRY_ONE)
+#define WET_DRY_FULL_SCALE (EAS_I32) (WET_DRY_ONE - 1)
+
+#define MULT_AUDIO_WET_DRY_COEF(audio,coef) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_WET_DRY_FRAC_BITS \
+ )
+
+/* Envelope 1 (EG1) calculation macros */
+#define NUM_EG1_INT_BITS 1
+#define NUM_EG1_FRAC_BITS 15
+
+/* the max positive gain used in the synth for EG1 */
+/* SYNTH_FULL_SCALE_EG1_GAIN must match the value in the dls2eas
+converter, otherwise, the values we read from the .eas file are bogus. */
+#define SYNTH_FULL_SCALE_EG1_GAIN (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS) -1)
+
+/* define a 1.0 */
+#define EG1_ONE (EAS_I32) ((0x1L << NUM_EG1_FRAC_BITS))
+#define EG1_MINUS_ONE (EAS_I32) (~SYNTH_FULL_SCALE_EG1_GAIN)
+
+#define EG1_HALF (EAS_I32) (EG1_ONE/2)
+#define EG1_MINUS_HALF (EAS_I32) (EG1_MINUS_ONE/2)
+
+/*
+We implement the EG1 using a linear gain value, which means that the
+attack segment is handled by incrementing (adding) the linear gain.
+However, EG1 treats the Decay, Sustain, and Release differently than
+the Attack portion. For Decay, Sustain, and Release, the gain is
+linear on dB scale, which is equivalent to exponential damping on
+a linear scale. Because we use a linear gain for EG1, we implement
+the Decay and Release as multiplication (instead of incrementing
+as we did for the attack segment).
+Therefore, we need the following macro to implement the multiplication
+(i.e., exponential damping) during the Decay and Release segments of
+the EG1
+*/
+#define MULT_EG1_EG1(gain,damping) /*lint -e(704) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
+ ) \
+ >> NUM_EG1_FRAC_BITS \
+ )
+
+// Use the following macro specifically for the filter, when multiplying
+// the b1 coefficient. The 0 <= |b1| < 2, which therefore might overflow
+// in certain conditions because we store b1 as a 1.15 value.
+// Instead, we could store b1 as b1p (b1' == b1 "prime") where
+// b1p == b1/2, thus ensuring no potential overflow for b1p because
+// 0 <= |b1p| < 1
+// However, during the filter calculation, we must account for the fact
+// that we are using b1p instead of b1, and thereby multiply by
+// an extra factor of 2. Rather than multiply by an extra factor of 2,
+// we can instead shift the result right by one less, hence the
+// modified shift right value of (NUM_EG1_FRAC_BITS -1)
+#define MULT_EG1_EG1_X2(gain,damping) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(gain)) * ((EAS_I32)(damping)) \
+ ) \
+ >> (NUM_EG1_FRAC_BITS -1) \
+ )
+
+#define SATURATE_EG1(x) /*lint -e{734} saturation operation */ \
+ ((EAS_I32)(x) > SYNTH_FULL_SCALE_EG1_GAIN) ? (SYNTH_FULL_SCALE_EG1_GAIN) : \
+ ((EAS_I32)(x) < EG1_MINUS_ONE) ? (EG1_MINUS_ONE) : (x);
+
+
+/* use "digital cents" == "dents" instead of cents */
+/* we coudl re-use the phase frac macros, but if we do,
+we must change the phase macros to cast to _I32 instead of _U32,
+because using a _U32 cast causes problems when shifting the exponent
+for the 2^x calculation, because right shift a negative values MUST
+be sign extended, or else the 2^x calculation is wrong */
+
+/* use "digital cents" == "dents" instead of cents */
+#define NUM_DENTS_FRAC_BITS 12
+#define NUM_DENTS_INT_BITS (HARDWARE_BIT_WIDTH - NUM_DENTS_FRAC_BITS)
+
+#define DENTS_FRAC_MASK (EAS_I32) ((0x1L << NUM_DENTS_FRAC_BITS) -1)
+
+#define GET_DENTS_INT_PART(x) /*lint -e(704) <avoid divide for performance>*/ \
+ (EAS_I32)((EAS_I32)(x) >> NUM_DENTS_FRAC_BITS)
+
+#define GET_DENTS_FRAC_PART(x) (EAS_I32)((EAS_I32)(x) & DENTS_FRAC_MASK)
+
+#define DENTS_ONE (EAS_I32) (0x1L << NUM_DENTS_FRAC_BITS)
+
+/* use CENTS_TO_DENTS to convert a value in cents to dents */
+#define CENTS_TO_DENTS (EAS_I32) (DENTS_ONE * (0x1L << NUM_EG1_FRAC_BITS) / 1200L) \
+
+
+/*
+For gain, the LFO generates a value that modulates in terms
+of dB. However, we use a linear gain value, so we must convert
+the LFO value in dB to a linear gain. Normally, we would use
+linear gain = 10^x, where x = LFO value in dB / 20.
+Instead, we implement 10^x using our 2^x approximation.
+because
+
+ 10^x = 2^(log2(10^x)) = 2^(x * log2(10))
+
+so we need to multiply by log2(10) which is just a constant.
+Ah, but just wait -- our 2^x actually doesn't exactly implement
+2^x, but it actually assumes that the input is in cents, and within
+the 2^x approximation converts its input from cents to octaves
+by dividing its input by 1200.
+
+So, in order to convert the LFO gain value in dB to something
+that our existing 2^x approximation can use, multiply the LFO gain
+by log2(10) * 1200 / 20
+
+The divide by 20 helps convert dB to linear gain, and we might
+as well incorporate that operation into this conversion.
+Of course, we need to keep some fractional bits, so multiply
+the constant by NUM_EG1_FRAC_BITS
+*/
+
+/* use LFO_GAIN_TO_CENTS to convert the LFO gain value to cents */
+#if 0
+#define DOUBLE_LOG2_10 (double) (3.32192809488736) /* log2(10) */
+
+#define DOUBLE_LFO_GAIN_TO_CENTS (double) \
+ ( \
+ (DOUBLE_LOG2_10) * \
+ 1200.0 / \
+ 20.0 \
+ )
+
+#define LFO_GAIN_TO_CENTS (EAS_I32) \
+ ( \
+ DOUBLE_LFO_GAIN_TO_CENTS * \
+ (0x1L << NUM_EG1_FRAC_BITS) \
+ )
+#endif
+
+#define LFO_GAIN_TO_CENTS (EAS_I32) (1671981156L >> (23 - NUM_EG1_FRAC_BITS))
+
+
+#define MULT_DENTS_COEF(dents,coef) /*lint -e704 <avoid divide for performance>*/ \
+ (EAS_I32)( \
+ ( \
+ ((EAS_I32)(dents)) * ((EAS_I32)(coef)) \
+ ) \
+ >> NUM_DENTS_FRAC_BITS \
+ ) \
+ /* lint +e704 <restore checking>*/
+
+/* we use 16-bits in the PC per audio sample */
+#define BITS_PER_AUDIO_SAMPLE 16
+
+/* we define 1 as 1.0 - 1 LSbit */
+#define DISTORTION_ONE (EAS_I32)((0x1L << (BITS_PER_AUDIO_SAMPLE-1)) -1)
+#define DISTORTION_MINUS_ONE (EAS_I32)(~DISTORTION_ONE)
+
+/* drive coef is given as int.frac */
+#define NUM_DRIVE_COEF_INT_BITS 1
+#define NUM_DRIVE_COEF_FRAC_BITS 4
+
+#define MULT_AUDIO_DRIVE(audio,drive) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32) ( \
+ ( \
+ ((EAS_I32)(audio)) * ((EAS_I32)(drive)) \
+ ) \
+ >> NUM_DRIVE_COEF_FRAC_BITS \
+ )
+
+#define MULT_AUDIO_AUDIO(audio1,audio2) /*lint -e(702) <avoid divide for performance>*/ \
+ (EAS_I32) ( \
+ ( \
+ ((EAS_I32)(audio1)) * ((EAS_I32)(audio2)) \
+ ) \
+ >> (BITS_PER_AUDIO_SAMPLE-1) \
+ )
+
+#define SATURATE(x) \
+ ((((EAS_I32)(x)) > DISTORTION_ONE) ? (DISTORTION_ONE) : \
+ (((EAS_I32)(x)) < DISTORTION_MINUS_ONE) ? (DISTORTION_MINUS_ONE) : ((EAS_I32)(x)));
+
+
+
+/*----------------------------------------------------------------------------
+ * EAS_Calculate2toX()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculate 2^x
+ *
+ * Inputs:
+ * nCents - measured in cents
+ *
+ * Outputs:
+ * nResult - int.frac result (where frac has NUM_DENTS_FRAC_BITS)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_Calculate2toX (EAS_I32 nCents);
+
+/*----------------------------------------------------------------------------
+ * EAS_LogToLinear16()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform log value to linear gain multiplier using piece-wise linear
+ * approximation
+ *
+ * Inputs:
+ * nGain - log scale value in 20.10 format. Even though gain is normally
+ * stored in 6.10 (16-bit) format we use 32-bit numbers here to eliminate
+ * the need for saturation checking when combining gain values.
+ *
+ * Outputs:
+ * Returns a 16-bit linear value approximately equal to 2^(nGain/1024)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_LogToLinear16 (EAS_I32 nGain);
+
+/*----------------------------------------------------------------------------
+ * EAS_VolumeToGain()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Transform volume control in 1dB increments to gain multiplier
+ *
+ * Inputs:
+ * volume - 100 = 0dB, 99 = -1dB, 0 = -inf
+ *
+ * Outputs:
+ * Returns a 16-bit linear value
+ *----------------------------------------------------------------------------
+*/
+EAS_I16 EAS_VolumeToGain (EAS_INT volume);
+
+/*----------------------------------------------------------------------------
+ * EAS_fsqrt()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the square root of a 32-bit fixed point value
+ *
+ * Inputs:
+ * n = value of interest
+ *
+ * Outputs:
+ * returns the square root of n
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_U16 EAS_fsqrt (EAS_U32 n);
+
+/*----------------------------------------------------------------------------
+ * EAS_flog2()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the log2 of a 32-bit fixed point value
+ *
+ * Inputs:
+ * n = value of interest
+ *
+ * Outputs:
+ * returns the log2 of n
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 EAS_flog2 (EAS_U32 n);
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_mdls.c b/arm-wt-22k/lib_src/eas_mdls.c
new file mode 100644
index 0000000..3da3b06
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_mdls.c
@@ -0,0 +1,2668 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mdls.c
+ *
+ * Contents and purpose:
+ * This file contains DLS to EAS converter.
+ *
+ * Copyright (c) 2005 Sonic Network Inc.
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 818 $
+ * $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/*
+ * NOTES:
+ *
+ * Processor Endian-ness:
+ *
+ * We use the EAS_HWGetDWord() and EAS_HWGetWord () functions
+ * extensively in this module. It would probably be faster to read
+ * an entire data structure, but this introduces the problem of
+ * sensitivity to processor endian-ness to the parser. By utlilizing
+ * the host wrapper functions, we avoid having to flip bytes around
+ * for big-endian processors. The default host wrapper versions of
+ * these functions are insensitive to processor endian-ness due to
+ * the fact that they read the file as a byte stream.
+ *
+ * Dynamic Memory:
+ *
+ * Dynamic memory allocation is a risky proposition in a mobile
+ * device. The memory can become fragmented, resulting in an
+ * inability to allocate a memory block, or garbage collection
+ * routines can use many CPU cycles. Either can contribute to
+ * failures of critical systems. Therefore, we try to minimize the
+ * number of memory allocations we make.
+ *
+ * We allocate a single large block of memory for the entire
+ * converted DLS collection, including the articulation data and
+ * samples. This block is then sub-allocated for the various
+ * data structures.
+ *
+ * Parser Overview:
+ *
+ * We make two passes through the file, the first pass to count the
+ * number of instruments, regions, etc. and allocate memory for
+ * them. The second pass parses the data into the allocated data
+ * structures.
+ *
+ * Conditional chunks are challenging in that they can occur
+ * anywhere in the list chunk that contains them. To simplify, we
+ * parse the blocks in a list in specific order, no matter which
+ * order they appear in the file. This way we don't allocate memory
+ * and parse a block that we end up throwing away later due to
+ * a conditional chunk.
+ *
+ * Assumptions that may bite us in the future:
+ *
+ * We make some assumptions to simplify things. The most fundamental
+ * assumption is that there will be no more than one of any type of
+ * chunk in a list. While this is consistent with the block diagram
+ * of the file layout in the mDLS spec, there is nothing in the
+ * spec that precludes having mulitple lar2 or rgn2 chunks, with
+ * conditional blocks that dictate their usage.
+ *
+ * DLS -> EAS Conversion Process:
+ *
+ * Another challenge is that the DLS structure does not map well to
+ * the current EAS sound library structure. Not all DLS constructs
+ * are supported, and data from DLS structures must sometimes be
+ * mapped to multiple EAS data structures. To simplify the process,
+ * the EAS region, articulation, and envelopes are treated as a
+ * single combined unit. Thus for each region, there must be one
+ * articulation element and two envelope elements.
+ *
+ * The sample processing is also a multi-step process. First the
+ * ptbl chunk is pre-parsed to determine the number of samples
+ * in the collection. The next step is to parse the instrument data
+ * to determine which samples are actually used by instruments.
+ * Some samples may not be used because they are used only in
+ * conditional blocks that the synthesizer cannot parse, or the
+ * author neglected to remove unused samples from the collection.
+ * In the next step, the active samples are read into memory and
+ * converted to the appropriate playback format. Finally, as the
+ * instruments are processed, the links are made to the samples and
+ * wsmp data is extracted for the region and articulation data
+ * structures.
+*/
+
+#ifndef _FILTER_ENABLED
+#error "Filter must be enabled if DLS_SYNTHESIZER is enabled"
+#endif
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+
+/* this define allows us to use the sndlib.h structures as RW memory */
+#define SCNST
+
+#include "eas_data.h"
+#include "eas_host.h"
+#include "eas_mdls.h"
+#include "eas_math.h"
+#include "dls.h"
+#include "dls2.h"
+#include "eas_report.h"
+
+//2 we should replace log10() function with fixed point routine in ConvertSampleRate()
+/* lint is choking on the ARM math.h file, so we declare the log10 function here */
+extern double log10(double x);
+
+/*------------------------------------
+ * defines
+ *------------------------------------
+*/
+
+// #define _DEBUG_DLS
+
+#define DLS_MAX_WAVE_COUNT 1024
+#define DLS_MAX_ART_COUNT 2048
+#define DLS_MAX_REGION_COUNT 2048
+#define DLS_MAX_INST_COUNT 256
+#define MAX_DLS_WAVE_SIZE (1024*1024)
+
+/*------------------------------------
+ * typedefs
+ *------------------------------------
+*/
+
+/* offsets to articulation data */
+typedef enum
+{
+ PARAM_MODIFIED = 0,
+ PARAM_MOD_LFO_FREQ,
+ PARAM_MOD_LFO_DELAY,
+
+ PARAM_VIB_LFO_FREQ,
+ PARAM_VIB_LFO_DELAY,
+
+ PARAM_VOL_EG_DELAY,
+ PARAM_VOL_EG_ATTACK,
+ PARAM_VOL_EG_HOLD,
+ PARAM_VOL_EG_DECAY,
+ PARAM_VOL_EG_SUSTAIN,
+ PARAM_VOL_EG_RELEASE,
+ PARAM_VOL_EG_SHUTDOWN,
+ PARAM_VOL_EG_VEL_TO_ATTACK,
+ PARAM_VOL_EG_KEY_TO_DECAY,
+ PARAM_VOL_EG_KEY_TO_HOLD,
+
+ PARAM_MOD_EG_DELAY,
+ PARAM_MOD_EG_ATTACK,
+ PARAM_MOD_EG_HOLD,
+ PARAM_MOD_EG_DECAY,
+ PARAM_MOD_EG_SUSTAIN,
+ PARAM_MOD_EG_RELEASE,
+ PARAM_MOD_EG_VEL_TO_ATTACK,
+ PARAM_MOD_EG_KEY_TO_DECAY,
+ PARAM_MOD_EG_KEY_TO_HOLD,
+
+ PARAM_INITIAL_FC,
+ PARAM_INITIAL_Q,
+ PARAM_MOD_LFO_TO_FC,
+ PARAM_MOD_LFO_CC1_TO_FC,
+ PARAM_MOD_LFO_CHAN_PRESS_TO_FC,
+ PARAM_MOD_EG_TO_FC,
+ PARAM_VEL_TO_FC,
+ PARAM_KEYNUM_TO_FC,
+
+ PARAM_MOD_LFO_TO_GAIN,
+ PARAM_MOD_LFO_CC1_TO_GAIN,
+ PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN,
+ PARAM_VEL_TO_GAIN,
+
+ PARAM_TUNING,
+ PARAM_KEYNUM_TO_PITCH,
+ PARAM_VIB_LFO_TO_PITCH,
+ PARAM_VIB_LFO_CC1_TO_PITCH,
+ PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH,
+ PARAM_MOD_LFO_TO_PITCH,
+ PARAM_MOD_LFO_CC1_TO_PITCH,
+ PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH,
+ PARAM_MOD_EG_TO_PITCH,
+
+ PARAM_DEFAULT_PAN,
+ PARAM_MIDI_CC91_TO_REVERB_SEND,
+ PARAM_DEFAULT_REVERB_SEND,
+ PARAM_MIDI_CC93_TO_CHORUS_SEND,
+ PARAM_DEFAULT_CHORUS_SEND,
+ PARAM_TABLE_SIZE
+} E_ART_INDEX;
+
+/* temporary data structure combining region, articulation, and envelope data */
+typedef struct s_art_dls_tag
+{
+ EAS_I16 values[PARAM_TABLE_SIZE];
+} S_DLS_ART_VALUES;
+
+/* temporary data structure for wlnk chunk data */
+typedef struct
+{
+ EAS_I32 gain;
+ EAS_U32 loopStart;
+ EAS_U32 loopLength;
+ EAS_U32 sampleRate;
+ EAS_U16 bitsPerSample;
+ EAS_I16 fineTune;
+ EAS_U8 unityNote;
+} S_WSMP_DATA;
+
+/* temporary data structure used while parsing a DLS file */
+typedef struct
+{
+ S_DLS *pDLS;
+ EAS_HW_DATA_HANDLE hwInstData;
+ EAS_FILE_HANDLE fileHandle;
+ S_WSMP_DATA *wsmpData;
+ EAS_U32 instCount;
+ EAS_U32 regionCount;
+ EAS_U32 artCount;
+ EAS_U32 waveCount;
+ EAS_U32 wavePoolSize;
+ EAS_U32 wavePoolOffset;
+ EAS_BOOL bigEndian;
+ EAS_BOOL filterUsed;
+} SDLS_SYNTHESIZER_DATA;
+
+/* connection lookup table */
+typedef struct s_connection_tag
+{
+ EAS_U16 source;
+ EAS_U16 control;
+ EAS_U16 destination;
+ EAS_U16 connection;
+} S_CONNECTION;
+
+static const S_CONNECTION connTable[] =
+{
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_FREQUENCY, PARAM_MOD_LFO_FREQ },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_STARTDELAY, PARAM_MOD_LFO_DELAY},
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_FREQUENCY, PARAM_VIB_LFO_FREQ },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_STARTDELAY, PARAM_VIB_LFO_DELAY },
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DELAYTIME, PARAM_VOL_EG_DELAY },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_ATTACK },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_HOLD },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_DECAY },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SUSTAINLEVEL, PARAM_VOL_EG_SUSTAIN },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_RELEASETIME, PARAM_VOL_EG_RELEASE },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SHUTDOWNTIME, PARAM_VOL_EG_SHUTDOWN },
+ { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_VEL_TO_ATTACK },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_KEY_TO_DECAY },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_KEY_TO_HOLD },
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DELAYTIME, PARAM_MOD_EG_DELAY },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_ATTACK },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_HOLD },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_DECAY },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_SUSTAINLEVEL, PARAM_MOD_EG_SUSTAIN },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_RELEASETIME, PARAM_MOD_EG_RELEASE },
+ { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_VEL_TO_ATTACK },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_KEY_TO_DECAY },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_KEY_TO_HOLD },
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_INITIAL_FC },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_Q, PARAM_INITIAL_Q },
+ { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_TO_FC },
+ { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CC1_TO_FC },
+ { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CHAN_PRESS_TO_FC },
+ { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_EG_TO_FC },
+ { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_VEL_TO_FC },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_KEYNUM_TO_FC },
+
+ { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_MOD_LFO_TO_GAIN },
+ { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_GAIN, PARAM_MOD_LFO_CC1_TO_GAIN },
+ { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_GAIN, PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN },
+ { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_VEL_TO_GAIN },
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_TUNING },
+ { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_KEYNUM_TO_PITCH },
+ { CONN_SRC_VIBRATO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_VIB_LFO_TO_PITCH },
+ { CONN_SRC_VIBRATO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_VIB_LFO_CC1_TO_PITCH },
+ { CONN_SRC_VIBRATO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH },
+ { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_LFO_TO_PITCH },
+ { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_MOD_LFO_CC1_TO_PITCH },
+ { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH },
+ { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_EG_TO_PITCH },
+
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PAN, PARAM_DEFAULT_PAN },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_DEFAULT_REVERB_SEND },
+ { CONN_SRC_CC91, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC91_TO_REVERB_SEND },
+ { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_CHORUS, PARAM_DEFAULT_CHORUS_SEND },
+ { CONN_SRC_CC93, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC93_TO_CHORUS_SEND }
+};
+#define ENTRIES_IN_CONN_TABLE (sizeof(connTable)/sizeof(S_CONNECTION))
+
+static const S_DLS_ART_VALUES defaultArt =
+{
+ 0, /* not modified */
+ -851, /* Mod LFO frequency: 5 Hz */
+ -7973, /* Mod LFO delay: 10 milliseconds */
+
+ -851, /* Vib LFO frequency: 5 Hz */
+ -7973, /* Vib LFO delay: 10 milliseconds */
+
+ -32768, /* EG1 delay time: 0 secs */
+ -32768, /* EG1 attack time: 0 secs */
+ -32768, /* EG1 hold time: 0 secs */
+ -32768, /* EG1 decay time: 0 secs */
+ 1000, /* EG1 sustain level: 100.0% */
+ -32768, /* EG1 release time: 0 secs */
+ -7271, /* EG1 shutdown time: 15 msecs */
+ 0, /* EG1 velocity to attack: 0 time cents */
+ 0, /* EG1 key number to decay: 0 time cents */
+ 0, /* EG1 key number to hold: 0 time cents */
+
+ -32768, /* EG2 delay time: 0 secs */
+ -32768, /* EG2 attack time: 0 secs */
+ -32768, /* EG2 hold time: 0 secs */
+ -32768, /* EG2 decay time: 0 secs */
+ 1000, /* EG2 sustain level: 100.0% */
+ -32768, /* EG2 release time: 0 secs */
+ 0, /* EG2 velocity to attack: 0 time cents */
+ 0, /* EG2 key number to decay: 0 time cents */
+ 0, /* EG2 key number to hold: 0 time cents */
+
+ 0x7fff, /* Initial Fc: Disabled */
+ 0, /* Initial Q: 0 dB */
+ 0, /* Mod LFO to Fc: 0 cents */
+ 0, /* Mod LFO CC1 to Fc: 0 cents */
+ 0, /* Mod LFO channel pressure to Fc: 0 cents */
+ 0, /* EG2 to Fc: 0 cents */
+ 0, /* Velocity to Fc: 0 cents */
+ 0, /* Key number to Fc: 0 cents */
+
+ 0, /* Mod LFO to gain: 0 dB */
+ 0, /* Mod LFO CC1 to gain: 0 dB */
+ 0, /* Mod LFO channel pressure to gain: 0 dB */
+ 960, /* Velocity to gain: 96 dB */
+
+ 0, /* Tuning: 0 cents */
+ 12800, /* Key number to pitch: 12,800 cents */
+ 0, /* Vibrato to pitch: 0 cents */
+ 0, /* Vibrato CC1 to pitch: 0 cents */
+ 0, /* Vibrato channel pressure to pitch: 0 cents */
+ 0, /* Mod LFO to pitch: 0 cents */
+ 0, /* Mod LFO CC1 to pitch: 0 cents */
+ 0, /* Mod LFO channel pressure to pitch: 0 cents */
+ 0, /* Mod EG to pitch: 0 cents */
+
+ 0, /* Default pan: 0.0% */
+ 0, /* Default reverb send: 0.0% */
+ 1000, /* Default CC91 to reverb send: 100.0% */
+ 0, /* Default chorus send: 0.0% */
+ 1000 /* Default CC93 to chorus send: 100.0% */
+};
+
+/*------------------------------------
+ * local variables
+ *------------------------------------
+*/
+
+#if defined(_8_BIT_SAMPLES)
+static const EAS_INT bitDepth = 8;
+#elif defined(_16_BIT_SAMPLES)
+static const EAS_INT bitDepth = 16;
+#else
+#error "Must define _8_BIT_SAMPLES or _16_BIT_SAMPLES"
+#endif
+
+static const EAS_U32 outputSampleRate = _OUTPUT_SAMPLE_RATE;
+static const EAS_I32 dlsRateConvert = DLS_RATE_CONVERT;
+static const EAS_I32 dlsLFOFrequencyConvert = DLS_LFO_FREQUENCY_CONVERT;
+
+/*------------------------------------
+ * inline functions
+ *------------------------------------
+*/
+EAS_INLINE void *PtrOfs (void *p, EAS_I32 offset)
+{
+ return (void*) (((EAS_U8*) p) + offset);
+}
+
+/*------------------------------------
+ * prototypes
+ *------------------------------------
+*/
+static EAS_RESULT NextChunk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 *pPos, EAS_U32 *pChunkType, EAS_I32 *pSize);
+static EAS_RESULT Parse_ptbl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 wsmpPos, EAS_I32 wsmpSize);
+static EAS_RESULT Parse_wave (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U16 waveIndex);
+static EAS_RESULT Parse_wsmp (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p);
+static EAS_RESULT Parse_fmt (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p);
+static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *p, EAS_SAMPLE *pSample);
+static EAS_RESULT Parse_lins(SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size);
+static EAS_RESULT Parse_ins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size);
+static EAS_RESULT Parse_insh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pRgnCount, EAS_U32 *pLocale);
+static EAS_RESULT Parse_lrgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex, EAS_U32 numRegions);
+static EAS_RESULT Parse_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex);
+static EAS_RESULT Parse_rgnh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_REGION *pRgn);
+static EAS_RESULT Parse_lart (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_DLS_ART_VALUES *pArt);
+static EAS_RESULT Parse_art (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_ART_VALUES *pArt);
+static EAS_RESULT Parse_wlnk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pWaveIndex);
+static EAS_RESULT Parse_cdl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 size, EAS_U32 *pValue);
+static void Convert_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_U16 regionIndex, EAS_U16 artIndex, EAS_U16 waveIndex, S_WSMP_DATA *pWsmp);
+static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES *pDLSArt, EAS_U16 artIndex);
+static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate);
+static EAS_I16 ConvertSustain (EAS_I32 sustain);
+static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents);
+static EAS_I8 ConvertPan (EAS_I32 pan);
+static EAS_U8 ConvertQ (EAS_I32 q);
+
+#ifdef _DEBUG_DLS
+static void DumpDLS (S_EAS *pEAS);
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * DLSParser ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * pEASData - pointer to over EAS data instance
+ * fileHandle - file handle for input file
+ * offset - offset into file where DLS data starts
+ *
+ * Outputs:
+ * EAS_RESULT
+ * ppEAS - address of pointer to alternate EAS wavetable
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_DLSLIB_HANDLE *ppDLS)
+{
+ EAS_RESULT result;
+ SDLS_SYNTHESIZER_DATA dls;
+ EAS_U32 temp;
+ EAS_I32 pos;
+ EAS_I32 chunkPos;
+ EAS_I32 size;
+ EAS_I32 instSize;
+ EAS_I32 rgnPoolSize;
+ EAS_I32 artPoolSize;
+ EAS_I32 waveLenSize;
+ EAS_I32 endDLS;
+ EAS_I32 wvplPos;
+ EAS_I32 wvplSize;
+ EAS_I32 linsPos;
+ EAS_I32 linsSize;
+ EAS_I32 ptblPos;
+ EAS_I32 ptblSize;
+ void *p;
+
+ /* zero counts and pointers */
+ EAS_HWMemSet(&dls, 0, sizeof(dls));
+
+ /* save file handle and hwInstData to save copying pointers around */
+ dls.hwInstData = hwInstData;
+ dls.fileHandle = fileHandle;
+
+ /* NULL return value in case of error */
+ *ppDLS = NULL;
+
+ /* seek to start of DLS and read in RIFF tag and set processor endian flag */
+ if ((result = EAS_HWFileSeek(dls.hwInstData, dls.fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWReadFile(dls.hwInstData, dls.fileHandle, &temp, sizeof(temp), &size)) != EAS_SUCCESS)
+ return result;
+
+ /* check for processor endian-ness */
+ dls.bigEndian = (temp == CHUNK_RIFF);
+
+ /* first chunk should be DLS */
+ pos = offset;
+ if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+ if (temp != CHUNK_DLS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected DLS chunk, got %08lx\n", temp); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* no instrument or wavepool chunks */
+ linsSize = wvplSize = ptblSize = linsPos = wvplPos = ptblPos = 0;
+
+ /* scan the chunks in the DLS list */
+ endDLS = offset + size;
+ pos = offset + 12;
+ while (pos < endDLS)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* parse useful chunks */
+ switch (temp)
+ {
+ case CHUNK_CDL:
+ if ((result = Parse_cdl(&dls, size, &temp)) != EAS_SUCCESS)
+ return result;
+ if (!temp)
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ break;
+
+ case CHUNK_LINS:
+ linsPos = chunkPos + 12;
+ linsSize = size - 4;
+ break;
+
+ case CHUNK_WVPL:
+ wvplPos = chunkPos + 12;
+ wvplSize = size - 4;
+ break;
+
+ case CHUNK_PTBL:
+ ptblPos = chunkPos + 8;
+ ptblSize = size - 4;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* must have a lins chunk */
+ if (linsSize == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No lins chunk found"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* must have a wvpl chunk */
+ if (wvplSize == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No wvpl chunk found"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* must have a ptbl chunk */
+ if ((ptblSize == 0) || (ptblSize > DLS_MAX_WAVE_COUNT * sizeof(POOLCUE) + sizeof(POOLTABLE)))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No ptbl chunk found"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* pre-parse the wave pool chunk */
+ if ((result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize)) != EAS_SUCCESS)
+ return result;
+
+ /* limit check */
+ if ((dls.waveCount == 0) || (dls.waveCount > DLS_MAX_WAVE_COUNT))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #waves [%u]\n", dls.waveCount); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* allocate memory for wsmp data */
+ dls.wsmpData = EAS_HWMalloc(dls.hwInstData, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount));
+ if (dls.wsmpData == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc for wsmp data failed\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(dls.wsmpData, 0, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount));
+
+ /* pre-parse the lins chunk */
+ result = Parse_lins(&dls, linsPos, linsSize);
+ if (result == EAS_SUCCESS)
+ {
+
+ /* limit check */
+ if ((dls.regionCount == 0) || (dls.regionCount > DLS_MAX_REGION_COUNT))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #regions [%u]\n", dls.regionCount); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* limit check */
+ if ((dls.artCount == 0) || (dls.artCount > DLS_MAX_ART_COUNT))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #articulations [%u]\n", dls.regionCount); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* limit check */
+ if ((dls.instCount == 0) || (dls.instCount > DLS_MAX_INST_COUNT))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #instruments [%u]\n", dls.instCount); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* Allocate memory for the converted DLS data */
+ /* calculate size of instrument data */
+ instSize = (EAS_I32) (sizeof(S_PROGRAM) * dls.instCount);
+
+ /* calculate size of region pool */
+ rgnPoolSize = (EAS_I32) (sizeof(S_DLS_REGION) * dls.regionCount);
+
+ /* calculate size of articulation pool, add one for default articulation */
+ dls.artCount++;
+ artPoolSize = (EAS_I32) (sizeof(S_DLS_ARTICULATION) * dls.artCount);
+
+ /* calculate size of wave length and offset arrays */
+ waveLenSize = (EAS_I32) (dls.waveCount * sizeof(EAS_U32));
+
+ /* calculate final memory size */
+ size = (EAS_I32) sizeof(S_EAS) + instSize + rgnPoolSize + artPoolSize + (2 * waveLenSize) + (EAS_I32) dls.wavePoolSize;
+ if (size <= 0) {
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* allocate the main EAS chunk */
+ dls.pDLS = EAS_HWMalloc(dls.hwInstData, size);
+ if (dls.pDLS == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc failed for DLS memory allocation size %ld\n", size); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(dls.pDLS, 0, size);
+ dls.pDLS->refCount = 1;
+ p = PtrOfs(dls.pDLS, sizeof(S_EAS));
+
+ /* setup pointer to programs */
+ dls.pDLS->numDLSPrograms = (EAS_U16) dls.instCount;
+ dls.pDLS->pDLSPrograms = p;
+ p = PtrOfs(p, instSize);
+
+ /* setup pointer to regions */
+ dls.pDLS->pDLSRegions = p;
+ dls.pDLS->numDLSRegions = (EAS_U16) dls.regionCount;
+ p = PtrOfs(p, rgnPoolSize);
+
+ /* setup pointer to articulations */
+ dls.pDLS->numDLSArticulations = (EAS_U16) dls.artCount;
+ dls.pDLS->pDLSArticulations = p;
+ p = PtrOfs(p, artPoolSize);
+
+ /* setup pointer to wave length table */
+ dls.pDLS->numDLSSamples = (EAS_U16) dls.waveCount;
+ dls.pDLS->pDLSSampleLen = p;
+ p = PtrOfs(p, waveLenSize);
+
+ /* setup pointer to wave offsets table */
+ dls.pDLS->pDLSSampleOffsets = p;
+ p = PtrOfs(p, waveLenSize);
+
+ /* setup pointer to wave pool */
+ dls.pDLS->pDLSSamples = p;
+
+ /* clear filter flag */
+ dls.filterUsed = EAS_FALSE;
+
+ /* parse the wave pool and load samples */
+ result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize);
+ }
+
+ /* create the default articulation */
+ Convert_art(&dls, &defaultArt, 0);
+ dls.artCount = 1;
+
+ /* parse the lins chunk and load instruments */
+ dls.regionCount = dls.instCount = 0;
+ if (result == EAS_SUCCESS)
+ result = Parse_lins(&dls, linsPos, linsSize);
+
+ /* clean up any temporary objects that were allocated */
+ if (dls.wsmpData)
+ EAS_HWFree(dls.hwInstData, dls.wsmpData);
+
+ /* if successful, return a pointer to the EAS collection */
+ if (result == EAS_SUCCESS)
+ {
+ *ppDLS = dls.pDLS;
+#ifdef _DEBUG_DLS
+ DumpDLS(dls.pDLS);
+#endif
+ }
+
+ /* something went wrong, deallocate the EAS collection */
+ else
+ DLSCleanup(dls.hwInstData, dls.pDLS);
+
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * DLSCleanup ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ * pEASData - pointer to over EAS data instance
+ * pEAS - pointer to alternate EAS wavetable
+ *
+ * Outputs:
+ * EAS_RESULT
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT DLSCleanup (EAS_HW_DATA_HANDLE hwInstData, S_DLS *pDLS)
+{
+
+ /* free the allocated memory */
+ if (pDLS)
+ {
+ if (pDLS->refCount)
+ {
+ if (--pDLS->refCount == 0)
+ EAS_HWFree(hwInstData, pDLS);
+ }
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * DLSAddRef ()
+ *----------------------------------------------------------------------------
+ * Increment reference count
+ *----------------------------------------------------------------------------
+*/
+void DLSAddRef (S_DLS *pDLS)
+{
+ if (pDLS)
+ pDLS->refCount++;
+}
+
+/*----------------------------------------------------------------------------
+ * NextChunk ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the type and size of the next chunk in the file
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT NextChunk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 *pPos, EAS_U32 *pChunkType, EAS_I32 *pSize)
+{
+ EAS_RESULT result;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, *pPos)) != EAS_SUCCESS)
+ return result;
+
+ /* read the chunk type */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+
+ /* read the chunk size */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pSize, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get form type for RIFF and LIST types */
+ if ((*pChunkType == CHUNK_RIFF) || (*pChunkType == CHUNK_LIST))
+ {
+
+ /* read the form type */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+
+ }
+
+ /* calculate start of next chunk */
+ *pPos += *pSize + 8;
+
+ /* adjust to word boundary */
+ if (*pPos & 1)
+ (*pPos)++;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_ptbl ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_ptbl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 wtblPos, EAS_I32 wtblSize)
+{
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_FILE_HANDLE tempFile;
+ EAS_U16 waveIndex;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get the structure size */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &temp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get the number of waves */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSData->waveCount, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+#if 0
+ /* just need the wave count on the first pass */
+ if (!pDLSData->pDLS)
+ return EAS_SUCCESS;
+#endif
+
+ /* open duplicate file handle */
+ if ((result = EAS_HWDupHandle(pDLSData->hwInstData, pDLSData->fileHandle, &tempFile)) != EAS_SUCCESS)
+ return result;
+
+ /* read to end of chunk */
+ for (waveIndex = 0; waveIndex < pDLSData->waveCount; waveIndex++)
+ {
+
+ /* get the offset to the wave and make sure it is within the wtbl chunk */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, tempFile, &temp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if (temp > (EAS_U32) wtblSize)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Ptbl offset exceeds size of wtbl\n"); */ }
+ EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* parse the wave */
+ if ((result = Parse_wave(pDLSData, wtblPos +(EAS_I32) temp, waveIndex)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* close the temporary handle and return */
+ EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_wave ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_wave (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U16 waveIndex)
+{
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 size;
+ EAS_I32 endChunk;
+ EAS_I32 chunkPos;
+ EAS_I32 wsmpPos = 0;
+ EAS_I32 fmtPos = 0;
+ EAS_I32 dataPos = 0;
+ EAS_I32 dataSize = 0;
+ S_WSMP_DATA *p;
+ void *pSample;
+ S_WSMP_DATA wsmp;
+
+ /* seek to start of chunk */
+ chunkPos = pos + 12;
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get the chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* make sure it is a wave chunk */
+ if (temp != CHUNK_WAVE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Offset in ptbl does not point to wave chunk\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* read to end of chunk */
+ pos = chunkPos;
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* parse useful chunks */
+ switch (temp)
+ {
+ case CHUNK_WSMP:
+ wsmpPos = chunkPos + 8;
+ break;
+
+ case CHUNK_FMT:
+ fmtPos = chunkPos + 8;
+ break;
+
+ case CHUNK_DATA:
+ dataPos = chunkPos + 8;
+ dataSize = size;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // limit to reasonable size
+ if (dataSize > MAX_DLS_WAVE_SIZE)
+ {
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+
+ /* for first pass, use temporary variable */
+ if (pDLSData->pDLS == NULL)
+ p = &wsmp;
+ else
+ p = &pDLSData->wsmpData[waveIndex];
+
+ /* set the defaults */
+ p->fineTune = 0;
+ p->unityNote = 60;
+ p->gain = 0;
+ p->loopStart = 0;
+ p->loopLength = 0;
+
+ /* must have a fmt chunk */
+ if (!fmtPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no fmt chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* must have a data chunk */
+ if (!dataPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no data chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* parse the wsmp chunk */
+ if (wsmpPos)
+ {
+ if ((result = Parse_wsmp(pDLSData, wsmpPos, p)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* parse the fmt chunk */
+ if ((result = Parse_fmt(pDLSData, fmtPos, p)) != EAS_SUCCESS)
+ return result;
+
+ /* calculate the size of the wavetable needed. We need only half
+ * the memory for 16-bit samples when in 8-bit mode, and we need
+ * double the memory for 8-bit samples in 16-bit mode. For
+ * unlooped samples, we may use ADPCM. If so, we need only 1/4
+ * the memory.
+ *
+ * We also need to add one for looped samples to allow for
+ * the first sample to be copied to the end of the loop.
+ */
+
+ /* use ADPCM encode for unlooped 16-bit samples if ADPCM is enabled */
+ /*lint -e{506} -e{774} groundwork for future version to support 8 & 16 bit */
+ if (bitDepth == 8)
+ {
+ if (p->bitsPerSample == 8)
+ size = dataSize;
+ else
+ /*lint -e{704} use shift for performance */
+ size = dataSize >> 1;
+ if (p->loopLength)
+ size++;
+ }
+
+ else
+ {
+ if (p->bitsPerSample == 16)
+ size = dataSize;
+ else
+ /*lint -e{703} use shift for performance */
+ size = dataSize << 1;
+ if (p->loopLength)
+ size += 2;
+ }
+
+ /* for first pass, add size to wave pool size and return */
+ if (pDLSData->pDLS == NULL)
+ {
+ pDLSData->wavePoolSize += (EAS_U32) size;
+ return EAS_SUCCESS;
+ }
+
+ /* allocate memory and read in the sample data */
+ pSample = pDLSData->pDLS->pDLSSamples + pDLSData->wavePoolOffset;
+ pDLSData->pDLS->pDLSSampleOffsets[waveIndex] = pDLSData->wavePoolOffset;
+ pDLSData->pDLS->pDLSSampleLen[waveIndex] = (EAS_U32) size;
+ pDLSData->wavePoolOffset += (EAS_U32) size;
+ if (pDLSData->wavePoolOffset > pDLSData->wavePoolSize)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Wave pool exceeded allocation\n"); */ }
+ return EAS_ERROR_SOUND_LIBRARY;
+ }
+
+ if ((result = Parse_data(pDLSData, dataPos, dataSize, p, pSample)) != EAS_SUCCESS)
+ return result;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_wsmp ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_wsmp (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p)
+{
+ EAS_RESULT result;
+ EAS_U16 wtemp;
+ EAS_U32 ltemp;
+ EAS_U32 cbSize;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get structure size */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &cbSize, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get unity note */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if (wtemp <= 127)
+ p->unityNote = (EAS_U8) wtemp;
+ else
+ {
+ p->unityNote = 60;
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid unity note [%u] in DLS wsmp ignored, set to 60\n", wtemp); */ }
+ }
+
+ /* get fine tune */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->fineTune, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get gain */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->gain, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if (p->gain > 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Positive gain [%ld] in DLS wsmp ignored, set to 0dB\n", p->gain); */ }
+ p->gain = 0;
+ }
+
+ /* option flags */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* sample loops */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* if looped sample, get loop data */
+ if (ltemp)
+ {
+
+ if (ltemp > 1)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS sample with %lu loops, ignoring extra loops\n", ltemp); */ }
+
+ /* skip ahead to loop data */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + (EAS_I32) cbSize)) != EAS_SUCCESS)
+ return result;
+
+ /* get structure size */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get loop type */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get loop start */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopStart, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get loop length */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopLength, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_fmt ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_fmt (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p)
+{
+ EAS_RESULT result;
+ EAS_U16 wtemp;
+ EAS_U32 ltemp;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get format tag */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if (wtemp != WAVE_FORMAT_PCM)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS sample format %04x\n", wtemp); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* get number of channels */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if (wtemp != 1)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No support for DLS multi-channel samples\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* get sample rate */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->sampleRate, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* bytes/sec */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* block align */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* bits/sample */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->bitsPerSample, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ if ((p->bitsPerSample != 8) && (p->bitsPerSample != 16))
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS bits-per-sample %d\n", p->bitsPerSample); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ return EAS_SUCCESS;
+}
+
+#if defined( _8_BIT_SAMPLES)
+/*----------------------------------------------------------------------------
+ * Parse_data ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * NOTE: The optimized assembly versions of the interpolator require
+ * an extra sample at the end of the loop - a copy of the first
+ * sample. This routine must allocate an extra sample of data and
+ * copy the first sample of the loop to the end.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *pWsmp, EAS_SAMPLE *pSample)
+{
+ EAS_RESULT result;
+ EAS_U8 convBuf[SAMPLE_CONVERT_CHUNK_SIZE];
+ EAS_I32 count;
+ EAS_I32 i;
+ EAS_I8 *p;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* 8-bit samples in an 8-bit synth, just copy the data, and flip bit 7 */
+ p = pSample;
+ if (pWsmp->bitsPerSample == 8)
+ {
+ if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pSample, size, &count)) != EAS_SUCCESS)
+ return result;
+ for (i = 0; i < size; i++)
+ /*lint -e{734} convert from unsigned to signed audio */
+ *p++ ^= 0x80;
+ }
+
+ /* 16-bit samples, need to convert to 8-bit or ADPCM */
+ else
+ {
+
+ while (size)
+ {
+ EAS_I8 *pInput;
+
+ /* for undithered conversion, we're just copying the 8-bit data */
+ if (pDLSData->bigEndian)
+ pInput = (EAS_I8*) convBuf;
+ else
+ pInput = (EAS_I8*) convBuf + 1;
+
+ /* read a small chunk of data and convert it */
+ count = (size < SAMPLE_CONVERT_CHUNK_SIZE ? size : SAMPLE_CONVERT_CHUNK_SIZE);
+ if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, convBuf, count, &count)) != EAS_SUCCESS)
+ return result;
+ size -= count;
+ /*lint -e{704} use shift for performance */
+ count = count >> 1;
+
+ while (count--)
+ {
+ *p++ = *pInput;
+ pInput += 2;
+ }
+ }
+ }
+
+ /* for looped samples, copy the last sample to the end */
+ if (pWsmp->loopLength)
+ pSample[pWsmp->loopStart + pWsmp->loopLength] = pSample[pWsmp->loopStart];
+
+ return EAS_SUCCESS;
+}
+#elif defined(_16_BIT_SAMPLES)
+#error "16-bit DLS conversion not implemented yet"
+#else
+#error "Must specifiy _8_BIT_SAMPLES or _16_BIT_SAMPLES"
+#endif
+
+/*----------------------------------------------------------------------------
+ * Parse_lins ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_lins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size)
+{
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 endChunk;
+ EAS_I32 chunkPos;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* read to end of chunk */
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* only instrument chunks are useful */
+ if (temp != CHUNK_INS)
+ continue;
+
+ if ((result = Parse_ins(pDLSData, chunkPos + 12, size)) != EAS_SUCCESS)
+ return result;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_ins ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_ins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size)
+{
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 chunkPos;
+ EAS_I32 endChunk;
+ EAS_I32 lrgnPos;
+ EAS_I32 lrgnSize;
+ EAS_I32 lartPos;
+ EAS_I32 lartSize;
+ EAS_I32 lar2Pos;
+ EAS_I32 lar2Size;
+ EAS_I32 inshPos;
+ EAS_U32 regionCount;
+ EAS_U32 locale;
+ S_DLS_ART_VALUES art;
+ S_PROGRAM *pProgram;
+ EAS_U16 artIndex;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* no chunks yet */
+ lrgnPos = lrgnSize = lartPos = lartSize = lar2Pos = lar2Size = inshPos = artIndex = 0;
+
+ /* read to end of chunk */
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* parse useful chunks */
+ switch (temp)
+ {
+ case CHUNK_INSH:
+ inshPos = chunkPos + 8;
+ break;
+
+ case CHUNK_LART:
+ lartPos = chunkPos + 12;
+ lartSize = size;
+ break;
+
+ case CHUNK_LAR2:
+ lar2Pos = chunkPos + 12;
+ lar2Size = size;
+ break;
+
+ case CHUNK_LRGN:
+ lrgnPos = chunkPos + 12;
+ lrgnSize = size;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* must have an lrgn to be useful */
+ if (!lrgnPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no lrgn chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* must have an insh to be useful */
+ if (!inshPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no insh chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* parse the instrument header */
+ if ((result = Parse_insh(pDLSData, inshPos, &regionCount, &locale)) != EAS_SUCCESS)
+ return result;
+
+ /* initialize and parse the global data first */
+ EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
+ if (lartPos)
+ if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
+ return result;
+ if (lar2Pos)
+ if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
+ return result;
+
+ if (art.values[PARAM_MODIFIED])
+ {
+ artIndex = (EAS_U16) pDLSData->artCount;
+ pDLSData->artCount++;
+ }
+
+ /* convert data on second pass */
+ if (pDLSData->pDLS)
+ {
+
+ if (art.values[PARAM_MODIFIED])
+ Convert_art(pDLSData, &art, artIndex);
+
+ /* setup pointers */
+ pProgram = &pDLSData->pDLS->pDLSPrograms[pDLSData->instCount];
+
+ /* initialize instrument */
+ pProgram->locale = locale;
+ pProgram->regionIndex = (EAS_U16) pDLSData->regionCount | FLAG_RGN_IDX_DLS_SYNTH;
+
+ }
+
+ /* parse the region data */
+ if ((result = Parse_lrgn(pDLSData, lrgnPos, lrgnSize, artIndex, regionCount)) != EAS_SUCCESS)
+ return result;
+
+ /* bump instrument count */
+ pDLSData->instCount++;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_insh ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_insh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pRgnCount, EAS_U32 *pLocale)
+{
+ EAS_RESULT result;
+ EAS_U32 bank;
+ EAS_U32 program;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get the region count and locale */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pRgnCount, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &bank, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &program, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* verify the parameters are valid */
+ if (bank & 0x7fff8080)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS bank number is out of range: %08lx\n", bank); */ }
+ bank &= 0xff7f;
+ }
+ if (program > 127)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS program number is out of range: %08lx\n", program); */ }
+ program &= 0x7f;
+ }
+
+ /* save the program number */
+ *pLocale = (bank << 8) | program;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_lrgn ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_lrgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex, EAS_U32 numRegions)
+{
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 chunkPos;
+ EAS_I32 endChunk;
+ EAS_U16 regionCount;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* read to end of chunk */
+ regionCount = 0;
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ if ((temp == CHUNK_RGN) || (temp == CHUNK_RGN2))
+ {
+ if (regionCount == numRegions)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS region count exceeded cRegions value in insh, extra region ignored\n"); */ }
+ return EAS_SUCCESS;
+ }
+ if ((result = Parse_rgn(pDLSData, chunkPos + 12, size, artIndex)) != EAS_SUCCESS)
+ return result;
+ regionCount++;
+ }
+ }
+
+ /* set a flag in the last region */
+ if ((pDLSData->pDLS != NULL) && (regionCount > 0))
+ pDLSData->pDLS->pDLSRegions[pDLSData->regionCount - 1].wtRegion.region.keyGroupAndFlags |= REGION_FLAG_LAST_REGION;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_rgn ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex)
+{
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 chunkPos;
+ EAS_I32 endChunk;
+ EAS_I32 rgnhPos;
+ EAS_I32 lartPos;
+ EAS_I32 lartSize;
+ EAS_I32 lar2Pos;
+ EAS_I32 lar2Size;
+ EAS_I32 wlnkPos;
+ EAS_I32 wsmpPos;
+ EAS_U32 waveIndex;
+ S_DLS_ART_VALUES art;
+ S_WSMP_DATA wsmp;
+ S_WSMP_DATA *pWsmp;
+ EAS_U16 regionIndex;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* no chunks found yet */
+ rgnhPos = lartPos = lartSize = lar2Pos = lar2Size = wsmpPos = wlnkPos = 0;
+ regionIndex = (EAS_U16) pDLSData->regionCount;
+
+ /* read to end of chunk */
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* parse useful chunks */
+ switch (temp)
+ {
+ case CHUNK_CDL:
+ if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* if conditional chunk evaluates false, skip this list */
+ if (!temp)
+ return EAS_SUCCESS;
+ break;
+
+ case CHUNK_RGNH:
+ rgnhPos = chunkPos + 8;
+ break;
+
+ case CHUNK_WLNK:
+ wlnkPos = chunkPos + 8;
+ break;
+
+ case CHUNK_WSMP:
+ wsmpPos = chunkPos + 8;
+ break;
+
+ case CHUNK_LART:
+ lartPos = chunkPos + 12;
+ lartSize = size;
+ break;
+
+ case CHUNK_LAR2:
+ lar2Pos = chunkPos + 12;
+ lar2Size = size;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* must have a rgnh chunk to be useful */
+ if (!rgnhPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no rgnh chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* must have a wlnk chunk to be useful */
+ if (!wlnkPos)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no wlnk chunk\n"); */ }
+ return EAS_ERROR_UNRECOGNIZED_FORMAT;
+ }
+
+ /* parse wlnk chunk */
+ if ((result = Parse_wlnk(pDLSData, wlnkPos, &waveIndex)) != EAS_SUCCESS)
+ return result;
+ pWsmp = &pDLSData->wsmpData[waveIndex];
+
+ /* if there is any articulation data, parse it */
+ EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
+ if (lartPos)
+ {
+ if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
+ return result;
+ }
+
+ if (lar2Pos)
+ {
+ if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* if second pass, process region header */
+ if (pDLSData->pDLS)
+ {
+
+ /* if local data was found convert it */
+ if (art.values[PARAM_MODIFIED] == EAS_TRUE)
+ {
+ Convert_art(pDLSData, &art, (EAS_U16) pDLSData->artCount);
+ artIndex = (EAS_U16) pDLSData->artCount;
+ }
+
+ /* parse region header */
+ if ((result = Parse_rgnh(pDLSData, rgnhPos, &pDLSData->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK])) != EAS_SUCCESS)
+ return result;
+
+ /* parse wsmp chunk, copying parameters from original first */
+ if (wsmpPos)
+ {
+ EAS_HWMemCpy(&wsmp, pWsmp, sizeof(wsmp));
+ if ((result = Parse_wsmp(pDLSData, wsmpPos, &wsmp)) != EAS_SUCCESS)
+ return result;
+
+ pWsmp = &wsmp;
+ }
+
+ Convert_rgn(pDLSData, regionIndex, artIndex, (EAS_U16) waveIndex, pWsmp);
+ }
+
+ /* if local articulation, bump count */
+ if (art.values[PARAM_MODIFIED])
+ pDLSData->artCount++;
+
+ /* increment region count */
+ pDLSData->regionCount++;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_rgnh ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_rgnh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_REGION *pRgn)
+{
+ EAS_RESULT result;
+ EAS_U16 lowKey;
+ EAS_U16 highKey;
+ EAS_U16 lowVel;
+ EAS_U16 highVel;
+ EAS_U16 optionFlags;
+ EAS_U16 keyGroup;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get the key range */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowKey, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highKey, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* check the range */
+ if (lowKey > 127)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low key out of range [%u]\n", lowKey); */ }
+ lowKey = 127;
+ }
+ if (highKey > 127)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High key out of range [%u]\n", lowKey); */ }
+ highKey = 127;
+ }
+
+ /* get the velocity range */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowVel, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highVel, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* check the range */
+ if (lowVel > 127)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low velocity out of range [%u]\n", lowVel); */ }
+ lowVel = 127;
+ }
+ if (highVel > 127)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High velocity out of range [%u]\n", highVel); */ }
+ highVel = 127;
+ }
+
+ /* get the option flags */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &optionFlags, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* get the key group */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &keyGroup, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* save the key range and key group */
+ pRgn->wtRegion.region.rangeLow = (EAS_U8) lowKey;
+ pRgn->wtRegion.region.rangeHigh = (EAS_U8) highKey;
+
+ /*lint -e{734} keyGroup will always be from 0-15 */
+ pRgn->wtRegion.region.keyGroupAndFlags = keyGroup << 8;
+ pRgn->velLow = (EAS_U8) lowVel;
+ pRgn->velHigh = (EAS_U8) highVel;
+ if (optionFlags & F_RGN_OPTION_SELFNONEXCLUSIVE)
+ pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_NON_SELF_EXCLUSIVE;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_lart ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_lart (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_DLS_ART_VALUES *pArt)
+{
+ EAS_RESULT result;
+ EAS_U32 temp;
+ EAS_I32 endChunk;
+ EAS_I32 chunkPos;
+ EAS_I32 art1Pos;
+ EAS_I32 art2Pos;
+
+ /* seek to start of chunk */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* no articulation chunks yet */
+ art1Pos = art2Pos = 0;
+
+ /* read to end of chunk */
+ endChunk = pos + size;
+ while (pos < endChunk)
+ {
+ chunkPos = pos;
+
+ /* get the next chunk type */
+ if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
+ return result;
+
+ /* parse useful chunks */
+ switch (temp)
+ {
+ case CHUNK_CDL:
+ if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* if conditional chunk evaluates false, skip this list */
+ if (!temp)
+ return EAS_SUCCESS;
+ break;
+
+ case CHUNK_ART1:
+ art1Pos = chunkPos + 8;
+ break;
+
+ case CHUNK_ART2:
+ art2Pos = chunkPos + 8;
+ break;
+
+ default:
+ break;
+
+ }
+ }
+
+ if (art1Pos)
+ {
+ if ((result = Parse_art(pDLSData, art1Pos, pArt)) != EAS_SUCCESS)
+ return result;
+ }
+
+ if (art2Pos)
+ {
+ if ((result = Parse_art(pDLSData, art2Pos, pArt)) != EAS_SUCCESS)
+ return result;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_art()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_art (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_ART_VALUES *pArt)
+{
+ EAS_RESULT result;
+ EAS_U32 structSize;
+ EAS_U32 numConnections;
+ EAS_U16 source;
+ EAS_U16 control;
+ EAS_U16 destination;
+ EAS_U16 transform;
+ EAS_I32 scale;
+ EAS_INT i;
+
+ /* seek to start of data */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ /* get the structure size */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &structSize, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ pos += (EAS_I32) structSize;
+
+ /* get the number of connections */
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &numConnections, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* skip to start of connections */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
+ return result;
+
+ while (numConnections--)
+ {
+
+ /* read the connection data */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &source, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &control, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &destination, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &transform, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &scale, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* look up the connection */
+ for (i = 0; i < (EAS_INT) ENTRIES_IN_CONN_TABLE; i++)
+ {
+ if ((connTable[i].source == source) &&
+ (connTable[i].destination == destination) &&
+ (connTable[i].control == control))
+ {
+ /*lint -e{704} use shift for performance */
+ pArt->values[connTable[i].connection] = (EAS_I16) (scale >> 16);
+ pArt->values[PARAM_MODIFIED] = EAS_TRUE;
+ break;
+ }
+ }
+ if (i == PARAM_TABLE_SIZE)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "WARN: Unsupported parameter in DLS file\n"); */ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_wlnk ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_wlnk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pWaveIndex)
+{
+ EAS_RESULT result;
+
+ /* we only care about the the index */
+ if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + 8)) != EAS_SUCCESS)
+ return result;
+
+ /* read the index */
+ return EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle,pWaveIndex, EAS_FALSE);
+}
+
+/*----------------------------------------------------------------------------
+ * PopcdlStack ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT PopcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 *pValue)
+{
+
+ /* stack underflow, cdl block has an errorr */
+ if (*pStackPtr < 0)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* pop the value off the stack */
+ *pValue = pStack[*pStackPtr];
+ *pStackPtr = *pStackPtr - 1;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * PushcdlStack ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT PushcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 value)
+{
+
+ /* stack overflow, return an error */
+ if (*pStackPtr >= CDL_STACK_SIZE)
+ return EAS_ERROR_FILE_FORMAT;
+
+ /* push the value onto the stack */
+ *pStackPtr = *pStackPtr + 1;
+ pStack[*pStackPtr] = value;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * QueryGUID ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_BOOL QueryGUID (const DLSID *pGUID, EAS_U32 *pValue)
+{
+
+ /* assume false */
+ *pValue = 0;
+ if (EAS_HWMemCmp(&DLSID_GMInHardware, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = 0xffffffff;
+ return EAS_TRUE;
+ }
+
+ if (EAS_HWMemCmp(&DLSID_GSInHardware, pGUID, sizeof(DLSID)) == 0)
+ return EAS_TRUE;
+
+ if (EAS_HWMemCmp(&DLSID_XGInHardware, pGUID, sizeof(DLSID)) == 0)
+ return EAS_TRUE;
+
+ if (EAS_HWMemCmp(&DLSID_SupportsDLS1, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = 0xffffffff;
+ return EAS_TRUE;
+ }
+
+ if (EAS_HWMemCmp(&DLSID_SupportsDLS2, pGUID, sizeof(DLSID)) == 0)
+ return EAS_TRUE;
+
+ if (EAS_HWMemCmp(&DLSID_SampleMemorySize, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = MAX_DLS_MEMORY;
+ return EAS_TRUE;
+ }
+
+ if (EAS_HWMemCmp(&DLSID_ManufacturersID, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = 0x0000013A;
+ return EAS_TRUE;
+ }
+
+ if (EAS_HWMemCmp(&DLSID_ProductID, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = LIB_VERSION;
+ return EAS_TRUE;
+ }
+
+ if (EAS_HWMemCmp(&DLSID_SamplePlaybackRate, pGUID, sizeof(DLSID)) == 0)
+ {
+ *pValue = (EAS_U32) outputSampleRate;
+ return EAS_TRUE;
+ }
+
+ /* unrecognized DLSID */
+ return EAS_FALSE;
+}
+
+/*----------------------------------------------------------------------------
+ * ReadDLSID ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a DLSID in a manner that is not sensitive to processor endian-ness
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ReadDLSID (SDLS_SYNTHESIZER_DATA *pDLSData, DLSID *pDLSID)
+{
+ EAS_RESULT result;
+ EAS_I32 n;
+
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data1, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data2, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data3, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ return EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pDLSID->Data4, sizeof(pDLSID->Data4), &n);
+}
+
+/*----------------------------------------------------------------------------
+ * Parse_cdl ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT Parse_cdl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 size, EAS_U32 *pValue)
+{
+ EAS_RESULT result;
+ EAS_U32 stack[CDL_STACK_SIZE];
+ EAS_U16 opcode;
+ EAS_INT stackPtr;
+ EAS_U32 x, y;
+ DLSID dlsid;
+
+ stackPtr = -1;
+ *pValue = 0;
+ x = 0;
+ while (size)
+ {
+ /* read the opcode */
+ if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &opcode, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+
+ /* handle binary opcodes */
+ if (opcode <= DLS_CDL_EQ)
+ {
+ /* pop X and Y */
+ if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
+ return result;
+ if ((result = PopcdlStack(stack, &stackPtr, &y)) != EAS_SUCCESS)
+ return result;
+ switch (opcode)
+ {
+ case DLS_CDL_AND:
+ x = x & y;
+ break;
+ case DLS_CDL_OR:
+ x = x | y;
+ break;
+ case DLS_CDL_XOR:
+ x = x ^ y;
+ break;
+ case DLS_CDL_ADD:
+ x = x + y;
+ break;
+ case DLS_CDL_SUBTRACT:
+ x = x - y;
+ break;
+ case DLS_CDL_MULTIPLY:
+ x = x * y;
+ break;
+ case DLS_CDL_DIVIDE:
+ if (!y)
+ return EAS_ERROR_FILE_FORMAT;
+ x = x / y;
+ break;
+ case DLS_CDL_LOGICAL_AND:
+ x = (x && y);
+ break;
+ case DLS_CDL_LOGICAL_OR:
+ x = (x || y);
+ break;
+ case DLS_CDL_LT:
+ x = (x < y);
+ break;
+ case DLS_CDL_LE:
+ x = (x <= y);
+ break;
+ case DLS_CDL_GT:
+ x = (x > y);
+ break;
+ case DLS_CDL_GE:
+ x = (x >= y);
+ break;
+ case DLS_CDL_EQ:
+ x = (x == y);
+ break;
+ default:
+ break;
+ }
+ }
+
+ else if (opcode == DLS_CDL_NOT)
+ {
+ if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
+ return result;
+ x = !x;
+ }
+
+ else if (opcode == DLS_CDL_CONST)
+ {
+ if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &x, EAS_FALSE)) != EAS_SUCCESS)
+ return result;
+ }
+
+ else if (opcode == DLS_CDL_QUERY)
+ {
+ if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
+ return result;
+ QueryGUID(&dlsid, &x);
+ }
+
+ else if (opcode == DLS_CDL_QUERYSUPPORTED)
+ {
+ if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
+ return result;
+ x = QueryGUID(&dlsid, &y);
+ }
+ else
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported opcode %d in DLS file\n", opcode); */ }
+
+ /* push the result on the stack */
+ if ((result = PushcdlStack(stack, &stackPtr, x)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* pop the last result off the stack */
+ return PopcdlStack(stack, &stackPtr, pValue);
+}
+
+/*----------------------------------------------------------------------------
+ * Convert_rgn()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Convert region data from DLS to EAS
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static void Convert_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_U16 regionIndex, EAS_U16 artIndex, EAS_U16 waveIndex, S_WSMP_DATA *pWsmp)
+{
+ S_DLS_REGION *pRgn;
+
+ /* setup pointers to data structures */
+ pRgn = &pDLSData->pDLS->pDLSRegions[regionIndex];
+
+ /* intiailize indices */
+ pRgn->wtRegion.artIndex = artIndex;
+ pRgn->wtRegion.waveIndex = waveIndex;
+
+ /* convert region data */
+ /*lint -e{704} use shift for performance */
+ pRgn->wtRegion.gain = (EAS_I16) (pWsmp->gain >> 16);
+ pRgn->wtRegion.loopStart = pWsmp->loopStart;
+ pRgn->wtRegion.loopEnd = (pWsmp->loopStart + pWsmp->loopLength);
+ pRgn->wtRegion.tuning = pWsmp->fineTune -(pWsmp->unityNote * 100) + ConvertSampleRate(pWsmp->sampleRate);
+ if (pWsmp->loopLength != 0)
+ pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_IS_LOOPED;
+}
+
+/*----------------------------------------------------------------------------
+ * Convert_art()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Convert articulation data from DLS to EAS
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ *----------------------------------------------------------------------------
+*/
+static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES *pDLSArt, EAS_U16 artIndex)
+{
+ S_DLS_ARTICULATION *pArt;
+
+ /* setup pointers to data structures */
+ pArt = &pDLSData->pDLS->pDLSArticulations[artIndex];
+
+ /* LFO parameters */
+ pArt->modLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_MOD_LFO_FREQ]);
+ pArt->modLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_MOD_LFO_DELAY]);
+ pArt->vibLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_VIB_LFO_FREQ]);
+ pArt->vibLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_VIB_LFO_DELAY]);
+
+ /* EG1 parameters */
+ pArt->eg1.delayTime = ConvertDelay(pDLSArt->values[PARAM_VOL_EG_DELAY]);
+ pArt->eg1.attackTime = pDLSArt->values[PARAM_VOL_EG_ATTACK];
+ pArt->eg1.holdTime = pDLSArt->values[PARAM_VOL_EG_HOLD];
+ pArt->eg1.decayTime = pDLSArt->values[PARAM_VOL_EG_DECAY];
+ pArt->eg1.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_VOL_EG_SUSTAIN]);
+ pArt->eg1.releaseTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_RELEASE]);
+ pArt->eg1.velToAttack = pDLSArt->values[PARAM_VOL_EG_VEL_TO_ATTACK];
+ pArt->eg1.keyNumToDecay = pDLSArt->values[PARAM_VOL_EG_KEY_TO_DECAY];
+ pArt->eg1.keyNumToHold = pDLSArt->values[PARAM_VOL_EG_KEY_TO_HOLD];
+ pArt->eg1ShutdownTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_SHUTDOWN]);
+
+ /* EG2 parameters */
+ pArt->eg2.delayTime = ConvertDelay(pDLSArt->values[PARAM_MOD_EG_DELAY]);
+ pArt->eg2.attackTime = pDLSArt->values[PARAM_MOD_EG_ATTACK];
+ pArt->eg2.holdTime = pDLSArt->values[PARAM_MOD_EG_HOLD];
+ pArt->eg2.decayTime = pDLSArt->values[PARAM_MOD_EG_DECAY];
+ pArt->eg2.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_MOD_EG_SUSTAIN]);
+ pArt->eg2.releaseTime = ConvertRate(pDLSArt->values[PARAM_MOD_EG_RELEASE]);
+ pArt->eg2.velToAttack = pDLSArt->values[PARAM_MOD_EG_VEL_TO_ATTACK];
+ pArt->eg2.keyNumToDecay = pDLSArt->values[PARAM_MOD_EG_KEY_TO_DECAY];
+ pArt->eg2.keyNumToHold = pDLSArt->values[PARAM_MOD_EG_KEY_TO_HOLD];
+
+ /* filter parameters */
+ pArt->filterCutoff = pDLSArt->values[PARAM_INITIAL_FC];
+ pArt->filterQandFlags = ConvertQ(pDLSArt->values[PARAM_INITIAL_Q]);
+ pArt->modLFOToFc = pDLSArt->values[PARAM_MOD_LFO_TO_FC];
+ pArt->modLFOCC1ToFc = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_FC];
+ pArt->modLFOChanPressToFc = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_FC];
+ pArt->eg2ToFc = pDLSArt->values[PARAM_MOD_EG_TO_FC];
+ pArt->velToFc = pDLSArt->values[PARAM_VEL_TO_FC];
+ pArt->keyNumToFc = pDLSArt->values[PARAM_KEYNUM_TO_FC];
+
+ /* gain parameters */
+ pArt->modLFOToGain = pDLSArt->values[PARAM_MOD_LFO_TO_GAIN];
+ pArt->modLFOCC1ToGain = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_GAIN];
+ pArt->modLFOChanPressToGain = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN];
+
+ /* pitch parameters */
+ pArt->tuning = pDLSArt->values[PARAM_TUNING];
+ pArt->keyNumToPitch = pDLSArt->values[PARAM_KEYNUM_TO_PITCH];
+ pArt->vibLFOToPitch = pDLSArt->values[PARAM_VIB_LFO_TO_PITCH];
+ pArt->vibLFOCC1ToPitch = pDLSArt->values[PARAM_VIB_LFO_CC1_TO_PITCH];
+ pArt->vibLFOChanPressToPitch = pDLSArt->values[PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH];
+ pArt->modLFOToPitch = pDLSArt->values[PARAM_MOD_LFO_TO_PITCH];
+ pArt->modLFOCC1ToPitch = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_PITCH];
+ pArt->modLFOChanPressToPitch = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH];
+ pArt->eg2ToPitch = pDLSArt->values[PARAM_MOD_EG_TO_PITCH];
+
+ /* output parameters */
+ pArt->pan = ConvertPan(pDLSArt->values[PARAM_DEFAULT_PAN]);
+
+ if (pDLSArt->values[PARAM_VEL_TO_GAIN] != 0)
+ pArt->filterQandFlags |= FLAG_DLS_VELOCITY_SENSITIVE;
+
+#ifdef _REVERB
+ pArt->reverbSend = pDLSArt->values[PARAM_DEFAULT_REVERB_SEND];
+ pArt->cc91ToReverbSend = pDLSArt->values[PARAM_MIDI_CC91_TO_REVERB_SEND];
+#endif
+
+#ifdef _CHORUS
+ pArt->chorusSend = pDLSArt->values[PARAM_DEFAULT_CHORUS_SEND];
+ pArt->cc93ToChorusSend = pDLSArt->values[PARAM_MIDI_CC93_TO_CHORUS_SEND];
+#endif
+}
+
+/*----------------------------------------------------------------------------
+ * ConvertSampleRate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate)
+{
+ return (EAS_I16) (1200.0 * log10((double) sampleRate / (double) outputSampleRate) / log10(2.0));
+}
+
+/*----------------------------------------------------------------------------
+ * ConvertSustainEG2()
+ *----------------------------------------------------------------------------
+ * Convert sustain level to pitch/Fc multipler for EG2
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 ConvertSustain (EAS_I32 sustain)
+{
+ /* check for sustain level of zero */
+ if (sustain == 0)
+ return 0;
+
+ /* convert to log2 factor */
+ /*lint -e{704} use shift for performance */
+ sustain = (sustain * SUSTAIN_LINEAR_CONVERSION_FACTOR) >> 15;
+
+ if (sustain > SYNTH_FULL_SCALE_EG1_GAIN)
+ return SYNTH_FULL_SCALE_EG1_GAIN;
+ return (EAS_I16) sustain;
+}
+
+/*----------------------------------------------------------------------------
+ * ConvertDelay ()
+ *----------------------------------------------------------------------------
+ * Converts timecents to frame count. Used for LFO and envelope
+ * delay times.
+ *----------------------------------------------------------------------------
+*/
+EAS_I16 ConvertDelay (EAS_I32 timeCents)
+{
+ EAS_I32 temp;
+
+ if (timeCents == ZERO_TIME_IN_CENTS)
+ return 0;
+
+ /* divide time by secs per frame to get number of frames */
+ temp = timeCents - dlsRateConvert;
+
+ /* convert from time cents to 10-bit fraction */
+ temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);
+
+ /* convert to frame count */
+ temp = EAS_LogToLinear16(temp - (15 << 10));
+
+ if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
+ return (EAS_I16) temp;
+ return SYNTH_FULL_SCALE_EG1_GAIN;
+}
+
+/*----------------------------------------------------------------------------
+ * ConvertRate ()
+ *----------------------------------------------------------------------------
+ * Convert timecents to rate
+ *----------------------------------------------------------------------------
+*/
+EAS_I16 ConvertRate (EAS_I32 timeCents)
+{
+ EAS_I32 temp;
+
+ if (timeCents == ZERO_TIME_IN_CENTS)
+ return SYNTH_FULL_SCALE_EG1_GAIN;
+
+ /* divide frame rate by time in log domain to get rate */
+ temp = dlsRateConvert - timeCents;
+
+#if 1
+ temp = EAS_Calculate2toX(temp);
+#else
+ /* convert from time cents to 10-bit fraction */
+ temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);
+
+ /* convert to rate */
+ temp = EAS_LogToLinear16(temp);
+#endif
+
+ if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
+ return (EAS_I16) temp;
+ return SYNTH_FULL_SCALE_EG1_GAIN;
+}
+
+
+/*----------------------------------------------------------------------------
+ * ConvertLFOPhaseIncrement()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents)
+{
+
+ /* check range */
+ if (pitchCents > MAX_LFO_FREQUENCY_IN_PITCHCENTS)
+ pitchCents = MAX_LFO_FREQUENCY_IN_PITCHCENTS;
+ if (pitchCents < MIN_LFO_FREQUENCY_IN_PITCHCENTS)
+ pitchCents = MIN_LFO_FREQUENCY_IN_PITCHCENTS;
+
+ /* double the rate and divide by frame rate by subtracting in log domain */
+ pitchCents = pitchCents - dlsLFOFrequencyConvert;
+
+ /* convert to phase increment */
+ return (EAS_I16) EAS_Calculate2toX(pitchCents);
+}
+
+/*----------------------------------------------------------------------------
+ * ConvertPan()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+static EAS_I8 ConvertPan (EAS_I32 pan)
+{
+
+ /* multiply by conversion factor */
+ pan = FMUL_15x15 (PAN_CONVERSION_FACTOR, pan);
+ if (pan < MIN_PAN_VALUE)
+ return MIN_PAN_VALUE;
+ if (pan > MAX_PAN_VALUE)
+ return MAX_PAN_VALUE;
+ return (EAS_I8) pan;
+}
+
+/*----------------------------------------------------------------------------
+ * ConvertQ()
+ *----------------------------------------------------------------------------
+ * Convert the DLS filter resonance to an index value used by the synth
+ * that accesses tables of coefficients based on the Q.
+ *----------------------------------------------------------------------------
+*/
+static EAS_U8 ConvertQ (EAS_I32 q)
+{
+
+ /* apply limits */
+ if (q <= 0)
+ return 0;
+
+ /* convert to table index */
+ /*lint -e{704} use shift for performance */
+ q = (FILTER_Q_CONVERSION_FACTOR * q + 0x4000) >> 15;
+
+ /* apply upper limit */
+ if (q >= FILTER_RESONANCE_NUM_ENTRIES)
+ q = FILTER_RESONANCE_NUM_ENTRIES - 1;
+ return (EAS_U8) q;
+}
+
+#ifdef _DEBUG_DLS
+/*----------------------------------------------------------------------------
+ * DumpDLS()
+ *----------------------------------------------------------------------------
+*/
+static void DumpDLS (S_EAS *pEAS)
+{
+ S_DLS_ARTICULATION *pArt;
+ S_DLS_REGION *pRegion;
+ EAS_INT i;
+ EAS_INT j;
+
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000022 , pEAS->numPrograms);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000023 , pEAS->numWTRegions);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000024 , pEAS->numDLSArticulations);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000025 , pEAS->numSamples);
+
+ /* dump the instruments */
+ for (i = 0; i < pEAS->numPrograms; i++)
+ {
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000026 ,
+ pEAS->pPrograms[i].locale >> 16,
+ (pEAS->pPrograms[i].locale >> 8) & 0x7f,
+ pEAS->pPrograms[i].locale & 0x7f);
+
+ for (j = pEAS->pPrograms[i].regionIndex; ; j++)
+ {
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000027 , j);
+ pRegion = &pEAS->pWTRegions[j];
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000028 , pRegion->gain);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000029 , pRegion->region.rangeLow, pRegion->region.rangeHigh);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002a , pRegion->region.keyGroupAndFlags);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002b , pRegion->loopStart);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002c , pRegion->loopEnd);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002d , pRegion->tuning);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002e , pRegion->artIndex);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002f , pRegion->waveIndex);
+
+ if (pRegion->region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
+ break;
+ }
+
+ }
+
+ /* dump the articulation data */
+ for (i = 0; i < pEAS->numDLSArticulations; i++)
+ {
+ /* articulation data */
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000030 , i);
+ pArt = &pEAS->pDLSArticulations[i];
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000031 , pArt->m_nEG2toFilterDepth);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000032 , pArt->m_nEG2toPitchDepth);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000033 , pArt->m_nFilterCutoffFrequency);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000034 , pArt->m_nFilterResonance);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000035 , pArt->m_nLFOAmplitudeDepth);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000036 , pArt->m_nLFODelayTime);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000037 , pArt->m_nLFOFrequency);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000038 , pArt->m_nLFOPitchDepth);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000039 , pArt->m_nPan);
+
+ /* EG1 data */
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003a , pArt->m_sEG1.m_nAttack);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003b , pArt->m_sEG1.m_nDecay);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003c , pArt->m_sEG1.m_nSustain);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003d , pArt->m_sEG1.m_nRelease);
+
+ /* EG2 data */
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003e , pArt->m_sEG2.m_nAttack);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003f , pArt->m_sEG2.m_nDecay);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000040 , pArt->m_sEG2.m_nSustain);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000041 , pArt->m_sEG2.m_nRelease);
+
+ }
+
+ /* dump the waves */
+ for (i = 0; i < pEAS->numSamples; i++)
+ {
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000042 , i);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000043 , pEAS->pSampleLen[i]);
+ EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000044 , pEAS->ppSamples[i]);
+ }
+
+}
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_mdls.h b/arm-wt-22k/lib_src/eas_mdls.h
new file mode 100644
index 0000000..f7dbf2f
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_mdls.h
@@ -0,0 +1,295 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mdls.h
+ *
+ * Contents and purpose:
+ * Declarations, interfaces, and prototypes for eas_mdls.c
+ *
+ * Copyright Sonic Network Inc. 2004
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MDLS_H
+#define _EAS_MDLS_H
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+#include "eas_data.h"
+
+
+/*------------------------------------
+ * Some defines for dls.h
+ *------------------------------------
+*/
+#ifndef DWORD
+#define DWORD EAS_I32
+#define FAR
+#define SHORT EAS_I16
+#define USHORT EAS_U16
+#define LONG EAS_I32
+#define ULONG EAS_U32
+#endif
+
+
+/* GUID struct (call it DLSID in case GUID is defined elsewhere) */
+typedef struct
+{
+ EAS_U32 Data1;
+ EAS_U16 Data2;
+ EAS_U16 Data3;
+ EAS_U8 Data4[8];
+} DLSID;
+
+#define DEFINE_DLSID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const DLSID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+
+/*------------------------------------
+ * defines
+ *------------------------------------
+*/
+
+/* maximum sample memory for DLS query support */
+#ifndef MAX_DLS_MEMORY
+#define MAX_DLS_MEMORY 65536
+#endif
+
+/* size of conditional chunk stack */
+#ifndef CDL_STACK_SIZE
+#define CDL_STACK_SIZE 8
+#endif
+
+/* size of read buffer for sample conversion */
+#ifndef SAMPLE_CONVERT_CHUNK_SIZE
+#define SAMPLE_CONVERT_CHUNK_SIZE 32
+#endif
+
+
+#define ZERO_TIME_IN_CENTS -32768
+
+/* Pan calculation macros */
+#define PAN_CONVERSION_FACTOR 4129
+#define MAX_PAN_VALUE 63
+#define MIN_PAN_VALUE -63
+
+/* multiplier to convert time cents to 10-bit fraction log for EAS_LogToLinear16 */
+#define TIME_CENTS_TO_LOG2 27962
+
+/* conversion factor sustain level from percent to exponent for LogToLinear16 */
+#define SUSTAIN_LOG_CONVERSION_FACTOR 536871
+#define SUSTAIN_LOG_CONVERSION_SHIFT 15
+
+/* conversion factor sustain level from percent to EG full scale */
+#define SUSTAIN_LINEAR_CONVERSION_FACTOR 1073709
+
+/* conversion factor to convert frame period to decay rate */
+#define DECAY_CONVERSION_FACTOR -16
+
+/*----------------------------------------------------------------------------
+ * These macros define the various characteristics of the defined sample rates
+ *----------------------------------------------------------------------------
+ * DLS_ATTACK_TIME_CONVERT log offset for conversion from time cents to attack rate
+ * DLS_LFO_FREQUENCY_CONVERT pitch-cents offset for LFO frequency conversion
+ *----------------------------------------------------------------------------
+*/
+
+#if defined (_SAMPLE_RATE_8000)
+#define DLS_RATE_CONVERT -9559
+#define DLS_LFO_FREQUENCY_CONVERT 5921
+
+#elif defined (_SAMPLE_RATE_16000)
+#define DLS_RATE_CONVERT -9559
+#define DLS_LFO_FREQUENCY_CONVERT 5921
+
+#elif defined (_SAMPLE_RATE_20000)
+#define DLS_RATE_CONVERT -8745
+#define DLS_LFO_FREQUENCY_CONVERT 5108
+
+#elif defined (_SAMPLE_RATE_22050)
+#define DLS_RATE_CONVERT -8914
+#define DLS_LFO_FREQUENCY_CONVERT 5277
+
+#elif defined (_SAMPLE_RATE_24000)
+#define DLS_RATE_CONVERT -9061
+#define DLS_LFO_FREQUENCY_CONVERT 5423
+
+#elif defined (_SAMPLE_RATE_32000)
+#define DLS_RATE_CONVERT -9559
+#define DLS_LFO_FREQUENCY_CONVERT 5921
+
+#elif defined (_SAMPLE_RATE_44100)
+#define DLS_RATE_CONVERT -8914
+#define DLS_LFO_FREQUENCY_CONVERT 5277
+
+#elif defined (_SAMPLE_RATE_48000)
+#define DLS_RATE_CONVERT -9061
+#define DLS_LFO_FREQUENCY_CONVERT 5423
+
+#else
+#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
+#endif
+
+/*
+ * FILTER_Q_CONVERSION_FACTOR convers the 0.1dB steps in the DLS
+ * file to our internal 0.75 dB steps. The value is calculated
+ * as follows:
+ *
+ * 32768 / (10 * <step-size in dB>)
+ *
+ * FILTER_RESONANCE_NUM_ENTRIES is the number of entries in the table
+*/
+#define FILTER_Q_CONVERSION_FACTOR 4369
+#define FILTER_RESONANCE_NUM_ENTRIES 31
+
+/*
+ * Multiplier to convert DLS gain units (10ths of a dB) to a
+ * power-of-two exponent for conversion to linear gain using our
+ * piece-wise linear approximator. Note that we ignore the lower
+ * 16-bits of the DLS gain value. The result is a 10-bit fraction
+ * that works with the EAS_LogToLinear16 function.
+ *
+ * DLS_GAIN_FACTOR = (2^18) / (200 * log10(2))
+ */
+#define DLS_GAIN_FACTOR 4354
+#define DLS_GAIN_SHIFT 8
+
+/*
+ * Reciprocal of 10 for quick divide by 10's
+ *
+ * DLS_GAIN_FACTOR = (2^18) / (200 * log10(2))
+ */
+#define DLS_DIV_10_FACTOR 3277
+#define DLS_DIV_10_SHIFT 16
+
+/*
+ * Multiplier to convert DLS time cents units to a power-of-two
+ * exponent for conversion to absolute time units using our
+ * piece-wise linear approximator.
+ *
+ * DLS_TIME_FACTOR = (2^22) / 1200
+ */
+#define DLS_TIME_FACTOR 3495
+#define DLS_TIME_SHIFT 22
+
+
+/* LFO limits */
+#define MAX_LFO_FREQUENCY_IN_HERTZ 20
+#define MIN_LFO_FREQUENCY_IN_HERTZ 0.1
+#define MAX_LFO_FREQUENCY_IN_PITCHCENTS 1549
+#define MIN_LFO_FREQUENCY_IN_PITCHCENTS -7624
+#define MAX_LFO_AMPLITUDE_DEPTH 12 /* in dB, DLS2.1 p 31*/
+#define MIN_LFO_AMPLITUDE_DEPTH -12 /* in dB, DLS2.1 p 31*/
+
+/* add to pitch cents before pow(2.0, n) to convert to frequency */
+#define ABSOLUTE_PITCH_BIAS 238395828
+
+#define A5_PITCH_OFFSET 6900
+
+/*
+CHUNK_TYPE is a macro that converts the 4 input args into a 32-bit int
+where
+argument a is placed at the MSB location and
+argument d is placed at the LSB location.
+This is useful for determining the DLS chunk types
+*/
+#define CHUNK_TYPE(a,b,c,d) ( \
+ ( ((EAS_U32)(a) & 0xFF) << 24 ) \
+ + ( ((EAS_U32)(b) & 0xFF) << 16 ) \
+ + ( ((EAS_U32)(c) & 0xFF) << 8 ) \
+ + ( ((EAS_U32)(d) & 0xFF) ) )
+
+#define CHUNK_RIFF CHUNK_TYPE('R','I','F','F')
+#define CHUNK_DLS CHUNK_TYPE('D','L','S',' ')
+#define CHUNK_CDL CHUNK_TYPE('c','d','l',' ')
+#define CHUNK_VERS CHUNK_TYPE('v','e','r','s')
+#define CHUNK_DLID CHUNK_TYPE('d','l','i','d')
+#define CHUNK_LIST CHUNK_TYPE('L','I','S','T')
+#define CHUNK_COLH CHUNK_TYPE('c','o','l','h')
+#define CHUNK_LINS CHUNK_TYPE('l','i','n','s')
+#define CHUNK_PTBL CHUNK_TYPE('p','t','b','l')
+#define CHUNK_WVPL CHUNK_TYPE('w','v','p','l')
+#define CHUNK_INFO CHUNK_TYPE('I','N','F','O')
+#define CHUNK_INAM CHUNK_TYPE('I','N','A','M')
+#define CHUNK_INS CHUNK_TYPE('i','n','s',' ')
+#define CHUNK_INSH CHUNK_TYPE('i','n','s','h')
+#define CHUNK_LRGN CHUNK_TYPE('l','r','g','n')
+#define CHUNK_RGN CHUNK_TYPE('r','g','n',' ')
+#define CHUNK_RGN2 CHUNK_TYPE('r','g','n','2')
+#define CHUNK_RGNH CHUNK_TYPE('r','g','n','h')
+#define CHUNK_WSMP CHUNK_TYPE('w','s','m','p')
+#define CHUNK_WLNK CHUNK_TYPE('w','l','n','k')
+#define CHUNK_LART CHUNK_TYPE('l','a','r','t')
+#define CHUNK_LAR2 CHUNK_TYPE('l','a','r','2')
+#define CHUNK_ART1 CHUNK_TYPE('a','r','t','1')
+#define CHUNK_ART2 CHUNK_TYPE('a','r','t','2')
+#define CHUNK_WAVE CHUNK_TYPE('w','a','v','e')
+#define CHUNK_FMT CHUNK_TYPE('f','m','t',' ')
+#define CHUNK_DATA CHUNK_TYPE('d','a','t','a')
+#define CHUNK_DMPR CHUNK_TYPE('d','m','p','r')
+
+
+#define WAVE_FORMAT_PCM 0x0001 /* Microsoft PCM format, see DLS2.1 p60 */
+#define WAVE_FORMAT_EXTENSIBLE 0xffff
+
+/* defines for wave table structures */
+
+/* initialize each articulation structure to a harmless state */
+/* change art values after we've determined EAS internals */
+#define DEFAULT_DLS_FILTER_CUTOFF_FREQUENCY 0x7FFF /* DLS2.1, p 31 means leave filter off */
+
+/**********/
+
+/* define the waves that we expect to generate instead of store */
+/* NOTE: our comparison routine converts the input string
+to lowercase, so the following comparison values should all
+be in lowercase.
+*/
+#define STRING_NOISE "noise"
+
+
+/*------------------------------------
+ * type definitions
+ *------------------------------------
+*/
+#ifdef _STANDALONE_CONVERTER
+typedef struct s_dls_params
+{
+ EAS_INT sampleRate;
+ EAS_INT samplesPerFrame;
+ EAS_INT bitDepth;
+ double ditherLevel;
+ double ditherFilterCoeff;
+ EAS_BOOL compatibility;
+ EAS_BOOL encodeADPCM;
+} S_DLS_PARAMS;
+#endif
+
+
+/* function prototypes */
+EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, S_DLS **pDLS);
+EAS_RESULT DLSCleanup (EAS_HW_DATA_HANDLE hwInstData, S_DLS *pDLS);
+void DLSAddRef (S_DLS *pDLS);
+EAS_I16 ConvertDelay (EAS_I32 timeCents);
+EAS_I16 ConvertRate (EAS_I32 timeCents);
+
+
+#ifdef _STANDALONE_CONVERTER
+void DLSConvParams (S_DLS_PARAMS *pParams, EAS_BOOL set);
+#endif
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_midi.c b/arm-wt-22k/lib_src/eas_midi.c
new file mode 100644
index 0000000..0c77aea
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_midi.c
@@ -0,0 +1,569 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midi.c
+ *
+ * Contents and purpose:
+ * This file implements the MIDI stream parser. It is called by eas_smf.c to parse MIDI messages
+ * that are streamed out of the file. It can also parse live MIDI streams.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 794 $
+ * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_miditypes.h"
+#include "eas_midi.h"
+#include "eas_vm_protos.h"
+#include "eas_parser.h"
+
+#ifdef JET_INTERFACE
+#include "jet_data.h"
+#endif
+
+
+/* state enumerations for ProcessSysExMessage */
+typedef enum
+{
+ eSysEx,
+ eSysExUnivNonRealTime,
+ eSysExUnivNrtTargetID,
+ eSysExGMControl,
+ eSysExUnivRealTime,
+ eSysExUnivRtTargetID,
+ eSysExDeviceControl,
+ eSysExMasterVolume,
+ eSysExMasterVolLSB,
+ eSysExSPMIDI,
+ eSysExSPMIDIchan,
+ eSysExSPMIDIMIP,
+ eSysExMfgID1,
+ eSysExMfgID2,
+ eSysExMfgID3,
+ eSysExEnhancer,
+ eSysExEnhancerSubID,
+ eSysExEnhancerFeedback1,
+ eSysExEnhancerFeedback2,
+ eSysExEnhancerDrive,
+ eSysExEnhancerWet,
+ eSysExEOX,
+ eSysExIgnore
+} E_SYSEX_STATES;
+
+/* local prototypes */
+static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode);
+static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
+
+/*----------------------------------------------------------------------------
+ * EAS_InitMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the MIDI stream state for parsing.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream)
+{
+ pMIDIStream->byte3 = EAS_FALSE;
+ pMIDIStream->pending = EAS_FALSE;
+ pMIDIStream->runningStatus = 0;
+ pMIDIStream->status = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
+ * so the interface works equally well for both file and stream I/O.
+ *
+ * Inputs:
+ * c - character from MIDI stream
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
+{
+
+ /* check for new status byte */
+ if (c & 0x80)
+ {
+ /* save new running status */
+ if (c < 0xf8)
+ {
+ pMIDIStream->runningStatus = c;
+ pMIDIStream->byte3 = EAS_FALSE;
+
+ /* deal with SysEx */
+ if ((c == 0xf7) || (c == 0xf0))
+ {
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
+ }
+
+ /* inform the file parser that we're in the middle of a message */
+ if ((c < 0xf4) || (c > 0xf6))
+ pMIDIStream->pending = EAS_TRUE;
+ }
+
+ /* real-time message - ignore it */
+ return EAS_SUCCESS;
+ }
+
+ /* 3rd byte of a 3-byte message? */
+ if (pMIDIStream->byte3)
+ {
+ pMIDIStream->d2 = c;
+ pMIDIStream->byte3 = EAS_FALSE;
+ pMIDIStream->pending = EAS_FALSE;
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
+ }
+
+ /* check for status received */
+ if (pMIDIStream->runningStatus)
+ {
+
+ /* save new status and data byte */
+ pMIDIStream->status = pMIDIStream->runningStatus;
+
+ /* check for 3-byte messages */
+ if (pMIDIStream->status < 0xc0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_TRUE;
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+
+ /* check for 2-byte messages */
+ if (pMIDIStream->status < 0xe0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_FALSE;
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
+ }
+
+ /* check for more 3-bytes message */
+ if (pMIDIStream->status < 0xf0)
+ {
+ pMIDIStream->d1 = c;
+ pMIDIStream->pending = EAS_TRUE;
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+
+ /* SysEx message? */
+ if (pMIDIStream->status == 0xF0)
+ {
+ if (parserMode == eParserModeMetaData)
+ return EAS_SUCCESS;
+ return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
+ }
+
+ /* remaining messages all clear running status */
+ pMIDIStream->runningStatus = 0;
+
+ /* F2 is 3-byte message */
+ if (pMIDIStream->status == 0xf2)
+ {
+ pMIDIStream->byte3 = EAS_TRUE;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* no status byte received, provide a warning, but we should be able to recover */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Received MIDI data without a valid status byte: %d\n",c); */ }
+ pMIDIStream->pending = EAS_FALSE;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * ProcessMIDIMessage()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function processes a typical MIDI message. All of the data has been received, just need
+ * to take appropriate action.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode)
+{
+ EAS_U8 channel;
+
+ channel = pMIDIStream->status & 0x0f;
+ switch (pMIDIStream->status & 0xf0)
+ {
+ case 0x80:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode <= eParserModeMute)
+ VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ break;
+
+ case 0x90:
+ if (pMIDIStream->d2)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOn: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ pMIDIStream->flags |= MIDI_FLAG_FIRST_NOTE;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode <= eParserModeMute)
+ VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+ break;
+
+ case 0xa0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PolyPres: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ break;
+
+ case 0xb0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Control: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode <= eParserModeMute)
+ VMControlChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+#ifdef JET_INTERFACE
+ if (pMIDIStream->jetData & MIDI_FLAGS_JET_CB)
+ {
+ JET_Event(pEASData, pMIDIStream->jetData & (JET_EVENT_SEG_MASK | JET_EVENT_TRACK_MASK),
+ channel, pMIDIStream->d1, pMIDIStream->d2);
+ }
+#endif
+ break;
+
+ case 0xc0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Program: %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1); */ }
+ if (parserMode <= eParserModeMute)
+ VMProgramChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1);
+ break;
+
+ case 0xd0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"ChanPres: %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1); */ }
+ if (parserMode <= eParserModeMute)
+ VMChannelPressure(pSynth, channel, pMIDIStream->d1);
+ break;
+
+ case 0xe0:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PBend: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ if (parserMode <= eParserModeMute)
+ VMPitchBend(pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Unknown: %02x %02x %02x\n",
+ pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * ProcessSysExMessage()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Process a SysEx character byte from the MIDI stream. Since we cannot
+ * simply wait for the next character to arrive, we are forced to save
+ * state after each character. It would be easier to parse at the file
+ * level, but then we lose the nice feature of being able to support
+ * these messages in a real-time MIDI stream.
+ *
+ * Inputs:
+ * pEASData - pointer to synthesizer instance data
+ * c - character to be processed
+ * locating - if true, the sequencer is relocating to a new position
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * These are the SysEx messages we can receive:
+ *
+ * SysEx messages
+ * { f0 7e 7f 09 01 f7 } GM 1 On
+ * { f0 7e 7f 09 02 f7 } GM 1/2 Off
+ * { f0 7e 7f 09 03 f7 } GM 2 On
+ * { f0 7f 7f 04 01 lsb msb } Master Volume
+ * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI
+ * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
+{
+
+ /* check for start byte */
+ if (c == 0xf0)
+ {
+ pMIDIStream->sysExState = eSysEx;
+ }
+ /* check for end byte */
+ else if (c == 0xf7)
+ {
+ /* if this was a MIP message, update the MIP table */
+ if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData))
+ VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
+ pMIDIStream->sysExState = eSysExIgnore;
+ }
+
+ /* process SysEx message */
+ else
+ {
+ switch (pMIDIStream->sysExState)
+ {
+ case eSysEx:
+
+ /* first byte, determine message class */
+ switch (c)
+ {
+ case 0x7e:
+ pMIDIStream->sysExState = eSysExUnivNonRealTime;
+ break;
+ case 0x7f:
+ pMIDIStream->sysExState = eSysExUnivRealTime;
+ break;
+ case 0x00:
+ pMIDIStream->sysExState = eSysExMfgID1;
+ break;
+ default:
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+ }
+ break;
+
+ /* process GM message */
+ case eSysExUnivNonRealTime:
+ if (c == 0x7f)
+ pMIDIStream->sysExState = eSysExUnivNrtTargetID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExUnivNrtTargetID:
+ if (c == 0x09)
+ pMIDIStream->sysExState = eSysExGMControl;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExGMControl:
+ if ((c == 1) || (c == 3))
+ {
+ /* GM 1 or GM2 On, reset synth */
+ if (parserMode != eParserModeMetaData)
+ {
+ pMIDIStream->flags |= MIDI_FLAG_GM_ON;
+ VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE);
+ VMInitMIPTable(pSynth);
+ }
+ pMIDIStream->sysExState = eSysExEOX;
+ }
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ /* Process Master Volume and SP-MIDI */
+ case eSysExUnivRealTime:
+ if (c == 0x7f)
+ pMIDIStream->sysExState = eSysExUnivRtTargetID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExUnivRtTargetID:
+ if (c == 0x04)
+ pMIDIStream->sysExState = eSysExDeviceControl;
+ else if (c == 0x0b)
+ pMIDIStream->sysExState = eSysExSPMIDI;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ /* process master volume */
+ case eSysExDeviceControl:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExMasterVolume;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMasterVolume:
+ /* save LSB */
+ pMIDIStream->d1 = c;
+ pMIDIStream->sysExState = eSysExMasterVolLSB;
+ break;
+
+ case eSysExMasterVolLSB:
+ if (parserMode != eParserModeMetaData)
+ {
+ EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1);
+ gain = (gain * gain) >> 15;
+ VMSetVolume(pSynth, (EAS_U16) gain);
+ }
+ pMIDIStream->sysExState = eSysExEOX;
+ break;
+
+ /* process SP-MIDI MIP message */
+ case eSysExSPMIDI:
+ if (c == 0x01)
+ {
+ /* assume all channels are muted */
+ if (parserMode != eParserModeMetaData)
+ VMInitMIPTable(pSynth);
+ pMIDIStream->d1 = 0;
+ pMIDIStream->sysExState = eSysExSPMIDIchan;
+ }
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExSPMIDIchan:
+ if (c < NUM_SYNTH_CHANNELS)
+ {
+ pMIDIStream->d2 = c;
+ pMIDIStream->sysExState = eSysExSPMIDIMIP;
+ }
+ else
+ {
+ /* bad MIP message - unmute channels */
+ if (parserMode != eParserModeMetaData)
+ VMInitMIPTable(pSynth);
+ pMIDIStream->sysExState = eSysExIgnore;
+ }
+ break;
+
+ case eSysExSPMIDIMIP:
+ /* process MIP entry here */
+ if (parserMode != eParserModeMetaData)
+ VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c);
+ pMIDIStream->sysExState = eSysExSPMIDIchan;
+
+ /* if 16 channels received, update MIP table */
+ if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS)
+ {
+ if (parserMode != eParserModeMetaData)
+ VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
+ pMIDIStream->sysExState = eSysExEOX;
+ }
+ break;
+
+ /* process Enhancer */
+ case eSysExMfgID1:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExMfgID1;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMfgID2:
+ if (c == 0x3a)
+ pMIDIStream->sysExState = eSysExMfgID1;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExMfgID3:
+ if (c == 0x04)
+ pMIDIStream->sysExState = eSysExEnhancer;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExEnhancer:
+ if (c == 0x01)
+ pMIDIStream->sysExState = eSysExEnhancerSubID;
+ else
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExEnhancerSubID:
+ pMIDIStream->sysExState = eSysExEnhancerFeedback1;
+ break;
+
+ case eSysExEnhancerFeedback1:
+ pMIDIStream->sysExState = eSysExEnhancerFeedback2;
+ break;
+
+ case eSysExEnhancerFeedback2:
+ pMIDIStream->sysExState = eSysExEnhancerDrive;
+ break;
+
+ case eSysExEnhancerDrive:
+ pMIDIStream->sysExState = eSysExEnhancerWet;
+ break;
+
+ case eSysExEnhancerWet:
+ pMIDIStream->sysExState = eSysExEOX;
+ break;
+
+ case eSysExEOX:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ }
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+
+ case eSysExIgnore:
+ break;
+
+ default:
+ pMIDIStream->sysExState = eSysExIgnore;
+ break;
+ }
+ }
+
+ if (pMIDIStream->sysExState == eSysExIgnore)
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Ignoring SysEx byte %02x\n", c); */ }
+ return EAS_SUCCESS;
+} /* end ProcessSysExMessage */
+
diff --git a/arm-wt-22k/lib_src/eas_midi.h b/arm-wt-22k/lib_src/eas_midi.h
new file mode 100644
index 0000000..37a03ee
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_midi.h
@@ -0,0 +1,71 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midi.h
+ *
+ * Contents and purpose:
+ * Prototypes for MIDI stream parsing functions
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDI_H
+#define _EAS_MIDI_H
+
+/*----------------------------------------------------------------------------
+ * EAS_InitMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the MIDI stream state for parsing.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream);
+
+/*----------------------------------------------------------------------------
+ * EAS_ParseMIDIStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
+ * so the interface works equally well for both file and stream I/O.
+ *
+ * Inputs:
+ * c - character from MIDI stream
+ *
+ * Outputs:
+ * returns EAS_RESULT (EAS_SUCCESS is OK)
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
+
+#endif /* #define _EAS_MIDI_H */
+
diff --git a/arm-wt-22k/lib_src/eas_midictrl.h b/arm-wt-22k/lib_src/eas_midictrl.h
new file mode 100644
index 0000000..0c4217d
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_midictrl.h
@@ -0,0 +1,64 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_midictrl.h
+ *
+ * Contents and purpose:
+ * MIDI controller definitions
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDICTRL_H
+#define _EAS_MIDICTRL_H
+
+/* define controller types */
+/*
+ Note that these controller types are specified in base 10 (decimal)
+ and not in hexadecimal. The above midi messages are specified
+ in hexadecimal.
+*/
+#define MIDI_CONTROLLER_BANK_SELECT 0
+#define MIDI_CONTROLLER_BANK_SELECT_MSB 0
+#define MIDI_CONTROLLER_MOD_WHEEL 1
+#define MIDI_CONTROLLER_ENTER_DATA_MSB 6
+#define MIDI_CONTROLLER_VOLUME 7
+#define MIDI_CONTROLLER_PAN 10
+#define MIDI_CONTROLLER_EXPRESSION 11
+#define MIDI_CONTROLLER_BANK_SELECT_LSB 32
+#define MIDI_CONTROLLER_ENTER_DATA_LSB 38 /* 0x26 */
+#define MIDI_CONTROLLER_SUSTAIN_PEDAL 64
+#define MIDI_CONTROLLER_SELECT_NRPN_LSB 98
+#define MIDI_CONTROLLER_SELECT_NRPN_MSB 99
+#define MIDI_CONTROLLER_SELECT_RPN_LSB 100 /* 0x64 */
+#define MIDI_CONTROLLER_SELECT_RPN_MSB 101 /* 0x65 */
+#define MIDI_CONTROLLER_ALL_SOUND_OFF 120
+#define MIDI_CONTROLLER_RESET_CONTROLLERS 121
+#define MIDI_CONTROLLER_ALL_NOTES_OFF 123
+#define MIDI_CONTROLLER_OMNI_OFF 124
+#define MIDI_CONTROLLER_OMNI_ON 125
+#define MIDI_CONTROLLER_MONO_ON_POLY_OFF 126
+#define MIDI_CONTROLLER_POLY_ON_MONO_OFF 127
+
+#endif /* #ifndef _EAS_MIDICTRL_H */
diff --git a/arm-wt-22k/lib_src/eas_mididata.c b/arm-wt-22k/lib_src/eas_mididata.c
new file mode 100644
index 0000000..2ee907e
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_mididata.c
@@ -0,0 +1,34 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mididata.c
+ *
+ * Contents and purpose:
+ * Data module for MIDI stream interface
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_miditypes.h"
+
+S_INTERACTIVE_MIDI eas_MIDIData;
+
diff --git a/arm-wt-22k/lib_src/eas_miditypes.h b/arm-wt-22k/lib_src/eas_miditypes.h
new file mode 100644
index 0000000..0b7f96e
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_miditypes.h
@@ -0,0 +1,138 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_miditypes.h
+ *
+ * Contents and purpose:
+ * Contains declarations for the MIDI stream parser.
+ *
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 778 $
+ * $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIDITYPES_H
+#define _EAS_MIDITYPES_H
+
+#include "eas_data.h"
+#include "eas_parser.h"
+
+/*----------------------------------------------------------------------------
+ * S_MIDI_STREAM
+ *
+ * Maintains parser state for the MIDI stream parser
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_midi_stream_tag
+{
+ EAS_BOOL8 byte3; /* flag indicates 3rd byte expected */
+ EAS_BOOL8 pending; /* flag indicates more data expected */
+ EAS_U8 sysExState; /* maintains the SysEx state */
+ EAS_U8 runningStatus; /* last running status received */
+ EAS_U8 status; /* status byte */
+ EAS_U8 d1; /* first data byte */
+ EAS_U8 d2; /* second data byte */
+ EAS_U8 flags; /* flags - see below for definition */
+#ifdef JET_INTERFACE
+ EAS_U32 jetData; /* JET data */
+#endif
+} S_MIDI_STREAM;
+
+/* flags for S_MIDI_STREAM.flags */
+#define MIDI_FLAG_GM_ON 0x01 /* GM System On message received */
+#define MIDI_FLAG_FIRST_NOTE 0x02 /* first note received */
+
+/* flags for S_MIDI_STREAM.jetFlags */
+#define MIDI_FLAGS_JET_MUTE 0x00000001 /* track is muted */
+#define MIDI_FLAGS_JET_CB 0x00000002 /* JET callback enabled */
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_STREAM
+ *
+ * This structure contains data required to parse an SMF stream. For SMF0 files, there
+ * will be a single instance of this per file. For SMF1 files, there will be multiple instance,
+ * one for each separate stream in the file.
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_smf_stream_tag
+{
+ EAS_FILE_HANDLE fileHandle; /* host wrapper file handle */
+ EAS_U32 ticks; /* time of next event in stream */
+ EAS_I32 startFilePos; /* start location of track within file */
+ S_MIDI_STREAM midiStream; /* MIDI stream state */
+} S_SMF_STREAM;
+
+/*----------------------------------------------------------------------------
+ *
+ * S_SMF_DATA
+ *
+ * This structure contains the instance data required to parse an SMF stream.
+ *
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct s_smf_data_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ S_SMF_STREAM *streams; /* pointer to individual streams in file */
+ S_SMF_STREAM *nextStream; /* pointer to next stream with event */
+ S_SYNTH *pSynth; /* pointer to synth */
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_I32 fileOffset; /* for embedded files */
+ EAS_I32 time; /* current time in milliseconds/256 */
+ EAS_U16 numStreams; /* actual number of streams */
+ EAS_U16 tickConv; /* current MIDI tick to msec conversion */
+ EAS_U16 ppqn; /* ticks per quarter note */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 flags; /* flags - see definitions below */
+} S_SMF_DATA;
+
+#define SMF_FLAGS_CHASE_MODE 0x01 /* chase mode - skip to first note */
+#define SMF_FLAGS_HAS_TIME_SIG 0x02 /* time signature encountered at time 0 */
+#define SMF_FLAGS_HAS_TEMPO 0x04 /* tempo encountered at time 0 */
+#define SMF_FLAGS_HAS_GM_ON 0x08 /* GM System On encountered at time 0 */
+#define SMF_FLAGS_JET_STREAM 0x80 /* JET in use - keep strict timing */
+
+/* combo flags indicate setup bar */
+#define SMF_FLAGS_SETUP_BAR (SMF_FLAGS_HAS_TIME_SIG | SMF_FLAGS_HAS_TEMPO | SMF_FLAGS_HAS_GM_ON)
+
+/*----------------------------------------------------------------------------
+ * Interactive MIDI structure
+ *----------------------------------------------------------------------------
+*/
+typedef struct s_interactive_midi_tag
+{
+#ifdef _CHECKED_BUILD
+ EAS_U32 handleCheck; /* signature check for checked build */
+#endif
+ S_SYNTH *pSynth; /* pointer to synth */
+ S_MIDI_STREAM stream; /* stream data */
+} S_INTERACTIVE_MIDI;
+
+#endif /* #ifndef _EAS_MIDITYPES_H */
+
diff --git a/arm-wt-22k/lib_src/eas_mixbuf.c b/arm-wt-22k/lib_src/eas_mixbuf.c
new file mode 100644
index 0000000..73e969a
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_mixbuf.c
@@ -0,0 +1,36 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixbuf.c
+ *
+ * Contents and purpose:
+ * Contains a data allocation for synthesizer
+ *
+ * Copyright Sonic Network Inc. 2004
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+// includes
+#include "eas_data.h"
+#include "eas_mixer.h"
+
+// globals
+EAS_I32 eas_MixBuffer[BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS];
+
diff --git a/arm-wt-22k/lib_src/eas_mixer.c b/arm-wt-22k/lib_src/eas_mixer.c
new file mode 100644
index 0000000..c4a2f9f
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_mixer.c
@@ -0,0 +1,464 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixer.c
+ *
+ * Contents and purpose:
+ * This file contains the critical components of the mix engine that
+ * must be optimized for best performance.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 706 $
+ * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+//3 dls: This module is in the midst of being converted from a synth
+//3 specific module to a general purpose mix engine
+
+/*------------------------------------
+ * includes
+ *------------------------------------
+*/
+#include "eas_data.h"
+#include "eas_host.h"
+#include "eas_math.h"
+#include "eas_mixer.h"
+#include "eas_config.h"
+#include "eas_report.h"
+
+#ifdef _MAXIMIZER_ENABLED
+EAS_I32 MaximizerProcess (EAS_VOID_PTR pInstData, EAS_I32 *pSrc, EAS_I32 *pDst, EAS_I32 numSamples);
+#endif
+
+/*------------------------------------
+ * defines
+ *------------------------------------
+*/
+
+/* need to boost stereo by ~3dB to compensate for the panner */
+#define STEREO_3DB_GAIN_BOOST 512
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - pointer to variable to receive instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineInit (S_EAS_DATA *pEASData)
+{
+
+ /* check Configuration Module for mix buffer allocation */
+ if (pEASData->staticMemoryModel)
+ pEASData->pMixBuffer = EAS_CMEnumData(EAS_CM_MIX_BUFFER);
+ else
+ pEASData->pMixBuffer = EAS_HWMalloc(pEASData->hwInstData, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
+ if (pEASData->pMixBuffer == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate mix buffer memory\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet((void *)(pEASData->pMixBuffer), 0, BUFFER_SIZE_IN_MONO_SAMPLES * NUM_OUTPUT_CHANNELS * sizeof(EAS_I32));
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePrep()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Performs prep before synthesize a buffer of audio, such as clearing
+ * audio buffers, etc.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePrep (S_EAS_DATA *pEASData, EAS_I32 numSamples)
+{
+
+ /* clear the mix buffer */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_HWMemSet(pEASData->pMixBuffer, 0, numSamples * (EAS_I32) sizeof(long) * 2);
+#else
+ EAS_HWMemSet(pEASData->pMixBuffer, 0, (EAS_I32) numSamples * (EAS_I32) sizeof(long));
+#endif
+
+ /* need to clear other side-chain effect buffers (chorus & reverb) */
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePost
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the post-processing after all voices have been
+ * synthesized. It calls any sweeteners and does the final mixdown to
+ * the output buffer.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePost (S_EAS_DATA *pEASData, EAS_I32 numSamples)
+{
+ EAS_U16 gain;
+
+//3 dls: Need to restore the mix engine metrics
+
+ /* calculate the gain multiplier */
+#ifdef _MAXIMIZER_ENABLED
+ if (pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effect)
+ {
+ EAS_I32 temp;
+ temp = MaximizerProcess(pEASData->effectsModules[EAS_MODULE_MAXIMIZER].effectData, pEASData->pMixBuffer, pEASData->pMixBuffer, numSamples);
+ temp = (temp * pEASData->masterGain) >> 15;
+ if (temp > 32767)
+ gain = 32767;
+ else
+ gain = (EAS_U16) temp;
+ }
+ else
+ gain = (EAS_U16) pEASData->masterGain;
+#else
+ gain = (EAS_U16) pEASData->masterGain;
+#endif
+
+ /* Not using all the gain bits for now
+ * Reduce the input to the compressor by 6dB to prevent saturation
+ */
+#ifdef _COMPRESSOR_ENABLED
+ if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
+ gain = gain >> 5;
+ else
+ gain = gain >> 4;
+#else
+ gain = gain >> 4;
+#endif
+
+ /* convert 32-bit mix buffer to 16-bit output format */
+#if (NUM_OUTPUT_CHANNELS == 2)
+ SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) ((EAS_U16) numSamples * 2));
+#else
+ SynthMasterGain(pEASData->pMixBuffer, pEASData->pOutputAudioBuffer, gain, (EAS_U16) numSamples);
+#endif
+
+#ifdef _ENHANCER_ENABLED
+ /* enhancer effect */
+ if (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_ENHANCER].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_ENHANCER].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _GRAPHIC_EQ_ENABLED
+ /* graphic EQ effect */
+ if (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_GRAPHIC_EQ].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _COMPRESSOR_ENABLED
+ /* compressor effect */
+ if (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_COMPRESSOR].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _WOW_ENABLED
+ /* WOW requires a 32-bit buffer, borrow the mix buffer and
+ * pass it as the destination buffer
+ */
+ /*lint -e{740} temporarily passing a parameter through an existing I/F */
+ if (pEASData->effectsModules[EAS_MODULE_WOW].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_WOW].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_WOW].effectData,
+ pEASData->pOutputAudioBuffer,
+ (EAS_PCM*) pEASData->pMixBuffer,
+ numSamples);
+#endif
+
+#ifdef _TONECONTROLEQ_ENABLED
+ /* ToneControlEQ effect */
+ if (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_TONECONTROLEQ].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _REVERB_ENABLED
+ /* Reverb effect */
+ if (pEASData->effectsModules[EAS_MODULE_REVERB].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_REVERB].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_REVERB].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+#ifdef _CHORUS_ENABLED
+ /* Chorus effect */
+ if (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData)
+ (*pEASData->effectsModules[EAS_MODULE_CHORUS].effect->pfProcess)
+ (pEASData->effectsModules[EAS_MODULE_CHORUS].effectData,
+ pEASData->pOutputAudioBuffer,
+ pEASData->pOutputAudioBuffer,
+ numSamples);
+#endif
+
+}
+
+#ifndef NATIVE_EAS_KERNEL
+/*----------------------------------------------------------------------------
+ * SynthMasterGain
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mixes down audio from 32-bit to 16-bit target buffer
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+void SynthMasterGain (long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 numSamples) {
+
+ /* loop through the buffer */
+ while (numSamples--) {
+ long s;
+
+ /* read a sample from the input buffer and add some guard bits */
+ s = *pInputBuffer++;
+
+ /* add some guard bits */
+ /*lint -e{704} <avoid divide for performance>*/
+ s = s >> 7;
+
+ /* apply master gain */
+ s *= (long) nGain;
+
+ /* shift to lower 16-bits */
+ /*lint -e{704} <avoid divide for performance>*/
+ s = s >> 9;
+
+ /* saturate */
+ s = SATURATE(s);
+
+ *pOutputBuffer++ = (EAS_PCM)s;
+ }
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down effects modules and deallocates memory
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* check Configuration Module for static memory allocation */
+ if (!pEASData->staticMemoryModel && (pEASData->pMixBuffer != NULL))
+ EAS_HWFree(pEASData->hwInstData, pEASData->pMixBuffer);
+
+ return EAS_SUCCESS;
+}
+
+#ifdef UNIFIED_MIXER
+#ifndef NATIVE_MIX_STREAM
+/*----------------------------------------------------------------------------
+ * EAS_MixStream
+ *----------------------------------------------------------------------------
+ * Mix a 16-bit stream into a 32-bit buffer
+ *
+ * pInputBuffer 16-bit input buffer
+ * pMixBuffer 32-bit mix buffer
+ * numSamples number of samples to mix
+ * gainLeft initial gain left or mono
+ * gainRight initial gain right
+ * gainLeft left gain increment per sample
+ * gainRight right gain increment per sample
+ * flags bit 0 = stereo source
+ * bit 1 = stereo output
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags)
+{
+ EAS_I32 temp;
+ EAS_INT src, dest;
+
+ /* NOTE: There are a lot of optimizations that can be done
+ * in the native implementations based on register
+ * availability, etc. For example, it may make sense to
+ * break this down into 8 separate routines:
+ *
+ * 1. Mono source to mono output
+ * 2. Mono source to stereo output
+ * 3. Stereo source to mono output
+ * 4. Stereo source to stereo output
+ * 5. Mono source to mono output - no gain change
+ * 6. Mono source to stereo output - no gain change
+ * 7. Stereo source to mono output - no gain change
+ * 8. Stereo source to stereo output - no gain change
+ *
+ * Other possibilities include loop unrolling, skipping
+ * a gain calculation every 2 or 4 samples, etc.
+ */
+
+ /* no gain change, use fast loops */
+ if ((gainIncLeft == 0) && (gainIncRight == 0))
+ {
+ switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
+ {
+ /* mono to mono */
+ case 0:
+ gainLeft >>= 15;
+ for (src = dest = 0; src < numSamples; src++, dest++)
+ {
+
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* mono to stereo */
+ case MIX_FLAGS_STEREO_OUTPUT:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src++, dest+=2)
+ {
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src] * gainRight) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* stereo to mono */
+ case MIX_FLAGS_STEREO_SOURCE:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src+=2, dest++)
+ {
+ temp = (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ temp += ((pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS);
+ pMixBuffer[dest] += temp;
+ }
+ break;
+
+ /* stereo to stereo */
+ case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
+ gainLeft >>= 15;
+ gainRight >>= 15;
+ for (src = dest = 0; src < numSamples; src+=2, dest+=2)
+ {
+ pMixBuffer[dest] += (pInputBuffer[src] * gainLeft) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src+1] * gainRight) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+ }
+ }
+
+ /* gain change - do gain increment */
+ else
+ {
+ switch (flags & (MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT))
+ {
+ /* mono to mono */
+ case 0:
+ for (src = dest = 0; src < numSamples; src++, dest++)
+ {
+ gainLeft += gainIncLeft;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* mono to stereo */
+ case MIX_FLAGS_STEREO_OUTPUT:
+ for (src = dest = 0; src < numSamples; src++, dest+=2)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+
+ /* stereo to mono */
+ case MIX_FLAGS_STEREO_SOURCE:
+ for (src = dest = 0; src < numSamples; src+=2, dest++)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ temp = (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ temp += ((pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS);
+ pMixBuffer[dest] += temp;
+ }
+ break;
+
+ /* stereo to stereo */
+ case MIX_FLAGS_STEREO_SOURCE | MIX_FLAGS_STEREO_OUTPUT:
+ for (src = dest = 0; src < numSamples; src+=2, dest+=2)
+ {
+ gainLeft += gainIncLeft;
+ gainRight += gainIncRight;
+ pMixBuffer[dest] += (pInputBuffer[src] * (gainLeft >> 15)) >> NUM_MIXER_GUARD_BITS;
+ pMixBuffer[dest+1] += (pInputBuffer[src+1] * (gainRight >> 15)) >> NUM_MIXER_GUARD_BITS;
+ }
+ break;
+ }
+ }
+}
+#endif
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_mixer.h b/arm-wt-22k/lib_src/eas_mixer.h
new file mode 100644
index 0000000..2ba2d3d
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_mixer.h
@@ -0,0 +1,137 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_mixer.h
+ *
+ * Contents and purpose:
+ * This file contains the critical components of the mix engine that
+ * must be optimized for best performance.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 706 $
+ * $Date: 2007-05-31 17:22:51 -0700 (Thu, 31 May 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_MIXER_H
+#define _EAS_MIXER_H
+
+//3 dls: This module is in the midst of being converted from a synth
+//3 specific module to a general purpose mix engine
+
+#define MIX_FLAGS_STEREO_SOURCE 1
+#define MIX_FLAGS_STEREO_OUTPUT 2
+#define NUM_MIXER_GUARD_BITS 4
+
+#include "eas_effects.h"
+
+extern void SynthMasterGain( long *pInputBuffer, EAS_PCM *pOutputBuffer, EAS_U16 nGain, EAS_U16 nNumLoopSamples);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepares the mix engine for work, allocates buffers, locates effects modules, etc.
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - pointer to variable to receive instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineInit (EAS_DATA_HANDLE pEASData);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePrep()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Performs prep before synthesize a buffer of audio, such as clearing
+ * audio buffers, etc.
+ *
+ * Inputs:
+ * psEASData - pointer to overall EAS data structure
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePrep (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEnginePost
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This routine does the post-processing after all voices have been
+ * synthesized. It calls any sweeteners and does the final mixdown to
+ * the output buffer.
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ * Notes:
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixEnginePost (EAS_DATA_HANDLE pEASData, EAS_I32 nNumSamplesToAdd);
+
+/*----------------------------------------------------------------------------
+ * EAS_MixEngineShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down effects modules and deallocates memory
+ *
+ * Inputs:
+ * pEASData - instance data
+ * pInstData - instance data handle
+ *
+ * Outputs:
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_MixEngineShutdown (EAS_DATA_HANDLE pEASData);
+
+#ifdef UNIFIED_MIXER
+/*----------------------------------------------------------------------------
+ * EAS_MixStream
+ *----------------------------------------------------------------------------
+ * Mix a 16-bit stream into a 32-bit buffer
+ *
+ * pInputBuffer 16-bit input buffer
+ * pMixBuffer 32-bit mix buffer
+ * numSamples number of samples to mix
+ * gainLeft initial gain left or mono
+ * gainRight initial gain right
+ * gainLeft left gain increment per sample
+ * gainRight right gain increment per sample
+ * flags bit 0 = stereo source
+ * bit 1 = stereo output
+ *----------------------------------------------------------------------------
+*/
+void EAS_MixStream (EAS_PCM *pInputBuffer, EAS_I32 *pMixBuffer, EAS_I32 numSamples, EAS_I32 gainLeft, EAS_I32 gainRight, EAS_I32 gainIncLeft, EAS_I32 gainIncRight, EAS_I32 flags);
+#endif
+
+#endif /* #ifndef _EAS_MIXER_H */
+
diff --git a/arm-wt-22k/lib_src/eas_ota.c b/arm-wt-22k/lib_src/eas_ota.c
new file mode 100644
index 0000000..fb81d62
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_ota.c
@@ -0,0 +1,1077 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_ota.c
+ *
+ * Contents and purpose:
+ * OTA parser
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 795 $
+ * $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_otadata.h"
+
+/* increase gain for mono ringtones */
+#define OTA_GAIN_OFFSET 8
+
+/* file definitions */
+#define OTA_RINGTONE 0x25
+#define OTA_SOUND 0x1d
+#define OTA_UNICODE 0x22
+
+/* song type definitions */
+#define OTA_BASIC_SONG_TYPE 0x01
+#define OTA_TEMPORARY_SONG_TYPE 0x02
+
+/* instruction ID coding */
+#define OTA_PATTERN_HEADER_ID 0x00
+#define OTA_NOTE_INST_ID 0x01
+#define OTA_SCALE_INST_ID 0x02
+#define OTA_STYLE_INST_ID 0x03
+#define OTA_TEMPO_INST_ID 0x04
+#define OTA_VOLUME_INST_ID 0x05
+
+/* note durations */
+#define OTA_NORMAL_DURATION 0x00
+#define OTA_DOTTED_NOTE 0x01
+#define OTA_DOUBLE_DOTTED_NOTE 0x02
+#define OTA_TRIPLET_NOTE 0x03
+
+/* loop count value for infinite loop */
+#define OTA_INFINITE_LOOP 0x0f
+
+/* length of 32nd note in 1/256ths of a msec for 63 BPM tempo */
+#define DEFAULT_TICK_CONV 30476
+
+/* default channel and program for OTA playback */
+#define OTA_CHANNEL 0
+#define OTA_PROGRAM 80
+#define OTA_VEL_MUL 4
+#define OTA_VEL_OFS 67
+#define OTA_VEL_DEFAULT 95
+
+/* multiplier for fixed point triplet conversion */
+#define TRIPLET_MULTIPLIER 683
+#define TRIPLET_SHIFT 10
+
+/* local prototypes */
+static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData);
+static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue);
+static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
+static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * EAS_OTA_Parser
+ *
+ * This structure contains the functional interface for the OTA parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_OTA_Parser =
+{
+ OTA_CheckFileType,
+ OTA_Prepare,
+ OTA_Time,
+ OTA_Event,
+ OTA_State,
+ OTA_Close,
+ OTA_Reset,
+ OTA_Pause,
+ OTA_Resume,
+ NULL,
+ OTA_SetData,
+ OTA_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ *
+ * bpmTable
+ *
+ * BPM conversion table. Converts bpm values to 256ths of a millisecond for a 32nd note
+ *----------------------------------------------------------------------------
+*/
+static const EAS_U32 bpmTable[32] =
+{
+ 76800, 68571, 61935, 54857,
+ 48000, 42667, 38400, 34286,
+ 30476, 27429, 24000, 21333,
+ 19200, 17143, 15360, 13714,
+ 12000, 10667, 9600, 8533,
+ 7680, 6737, 6000, 5408,
+ 4800, 4267, 3840, 3398,
+ 3024, 2685, 2400, 2133
+};
+
+/*----------------------------------------------------------------------------
+ * OTA_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+ EAS_INT cmdLen;
+ EAS_INT state;
+ EAS_U8 temp;
+
+ /* read the first byte, should be command length */
+ *ppHandle = NULL;
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* read all the commands */
+ cmdLen = temp;
+ state = 0;
+ while (cmdLen--)
+ {
+
+ /* read the command, upper 7 bits */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+ temp = temp >> 1;
+
+ if (state == 0)
+ {
+ if (temp != OTA_RINGTONE)
+ break;
+ state++;
+ }
+ else
+ {
+
+ if (temp == OTA_SOUND)
+ {
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pData = EAS_CMEnumData(EAS_CM_OTA_DATA);
+ else
+ pData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_OTA_DATA));
+ if (!pData)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Malloc failed in OTA_Prepare\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+ EAS_HWMemSet(pData, 0, sizeof(S_OTA_DATA));
+
+ /* return a pointer to the instance data */
+ pData->fileHandle = fileHandle;
+ pData->fileOffset = offset;
+ pData->state = EAS_STATE_OPEN;
+ *ppHandle = pData;
+ break;
+ }
+
+ if (temp != OTA_UNICODE)
+ break;
+ }
+ }
+
+ /* not recognized */
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ /* check for valid state */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state != EAS_STATE_OPEN)
+ return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
+
+ /* instantiate a synthesizer */
+ if ((result = VMInitMIDI(pEASData, &pData->pSynth)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
+ return result;
+ }
+
+ pData->state = EAS_STATE_ERROR;
+ if ((result = OTA_ParseHeader(pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* return time in milliseconds */
+ /*lint -e{704} use shift instead of division */
+ *pTime = pData->time >> 8;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+ EAS_U32 duration;
+ EAS_U8 temp;
+
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state >= EAS_STATE_OPEN)
+ return EAS_SUCCESS;
+
+ /* initialize MIDI channel when the track starts playing */
+ if (pData->time == 0)
+ {
+ /* set program to square lead */
+ if (parserMode != eParserModeMetaData)
+ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, OTA_PROGRAM);
+
+ /* set channel volume to max */
+ if (parserMode != eParserModeMetaData)
+ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, 7, 127);
+ }
+
+ /* check for end of note */
+ if (pData->note)
+ {
+ /* stop the note */
+ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, 0);
+ pData->note = 0;
+
+ /* check for rest between notes */
+ if (pData->restTicks)
+ {
+ pData->time += (EAS_I32) pData->restTicks;
+ pData->restTicks = 0;
+ return EAS_SUCCESS;
+ }
+ }
+
+ /* if not in a pattern, read the pattern header */
+ while (pData->current.patternLen == 0)
+ {
+
+ /* check for loop - don't do infinite loops when locating */
+ if (pData->loopCount && ((parserMode == eParserModePlay) || (pData->loopCount != OTA_INFINITE_LOOP)))
+ {
+ /* if not infinite loop, decrement loop count */
+ if (pData->loopCount != OTA_INFINITE_LOOP)
+ pData->loopCount--;
+
+ /* back to start of pattern*/
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* if no previous position to restore, continue forward */
+ else if (pData->restore.fileOffset < 0)
+ {
+
+ /* check for end of song */
+ if (pData->numPatterns == 0)
+ {
+ pData->state = EAS_STATE_STOPPING;
+ VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ return EAS_SUCCESS;
+ }
+
+ /* read the next pattern header */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+ if (temp != OTA_PATTERN_HEADER_ID)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA pattern header\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* get the pattern ID */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->currentPattern)) != EAS_SUCCESS)
+ return result;
+
+ /* get the loop count */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->loopCount)) != EAS_SUCCESS)
+ return result;
+
+ /* get the pattern length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->current.patternLen)) != EAS_SUCCESS)
+ return result;
+
+ /* if pattern definition, save the current position */
+ if (pData->current.patternLen)
+ {
+ if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* if pattern length is zero, repeat a previous pattern */
+ else
+ {
+ /* make sure it's a valid pattern */
+ if (pData->patterns[pData->currentPattern].fileOffset < 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA pattern error, invalid pattern specified\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* save current position and data */
+ if ((result = OTA_SavePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
+ return result;
+
+ /* seek to the pattern in the file */
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->patterns[pData->currentPattern])) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* decrement pattern count */
+ pData->numPatterns--;
+ }
+
+ /* restore previous position */
+ else
+ {
+ if ((result = OTA_RestorePosition(pEASData->hwInstData, pData, &pData->restore)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ /* get the next event */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+
+ switch (temp)
+ {
+ case OTA_NOTE_INST_ID:
+ /* fetch note value */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &pData->note)) != EAS_SUCCESS)
+ return result;
+
+ /* fetch note duration */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+ duration = pData->tick * (0x20 >> temp);
+
+ /* fetch note duration modifier */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
+ return result;
+ switch (temp)
+ {
+ case OTA_NORMAL_DURATION:
+ break;
+
+ case OTA_DOTTED_NOTE:
+ duration += duration >> 1;
+ break;
+
+ case OTA_DOUBLE_DOTTED_NOTE:
+ duration += (duration >> 1) + (duration >> 2);
+ break;
+
+ case OTA_TRIPLET_NOTE:
+ duration = (duration * TRIPLET_MULTIPLIER) >> TRIPLET_SHIFT;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note duration ignored\n"); */ }
+ break;
+ }
+
+ /* check for note */
+ if (pData->note)
+ {
+
+ /* determine note length based on style */
+ switch (pData->style)
+ {
+ case 0:
+ pData->restTicks = duration >> 4;
+ break;
+ case 1:
+ pData->restTicks = 0;
+ break;
+ case 2:
+ pData->restTicks = duration >> 1;
+ break;
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unrecognized note style ignored\n"); */ }
+ }
+
+ /* add octave */
+ pData->note += pData->octave;
+ if (parserMode == eParserModePlay)
+ VMStartNote(pEASData->pVoiceMgr, pData->pSynth, OTA_CHANNEL, pData->note, pData->velocity);
+ pData->time += (EAS_I32) duration - (EAS_I32) pData->restTicks;
+ }
+
+ /* this is a rest */
+ else
+ pData->time += (EAS_I32) duration;
+ break;
+
+ case OTA_SCALE_INST_ID:
+ /* fetch octave */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->octave = (EAS_U8) (temp * 12 + 59);
+ break;
+
+ case OTA_STYLE_INST_ID:
+ /* fetch note style */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 2, &pData->style)) != EAS_SUCCESS)
+ return result;
+ break;
+
+ case OTA_TEMPO_INST_ID:
+ /* fetch tempo */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 5, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->tick = bpmTable[temp];
+ break;
+
+ case OTA_VOLUME_INST_ID:
+ /* fetch volume */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &temp)) != EAS_SUCCESS)
+ return result;
+ pData->velocity = temp ? (EAS_U8) (temp * OTA_VEL_MUL + OTA_VEL_OFS) : 0;
+ break;
+
+ default:
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected instruction ID in OTA stream\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* decrement pattern length */
+ pData->current.patternLen--;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ S_OTA_DATA* pData;
+
+ /* establish pointer to instance data */
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* if stopping, check to see if synth voices are active */
+ if (pData->state == EAS_STATE_STOPPING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_STOPPED;
+ }
+
+ if (pData->state == EAS_STATE_PAUSING)
+ {
+ if (VMActiveVoices(pData->pSynth) == 0)
+ pData->state = EAS_STATE_PAUSED;
+ }
+
+ /* return current state */
+ *pState = pData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* close the file */
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pData->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ /* free the synth */
+ if (pData->pSynth != NULL)
+ VMMIDIShutdown(pEASData, pData->pSynth);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ EAS_HWFree(pEASData->hwInstData, pData);
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA* pData;
+ EAS_RESULT result;
+
+ pData = (S_OTA_DATA*) pInstData;
+
+ /* reset the synth */
+ VMReset(pEASData->pVoiceMgr, pData->pSynth, EAS_TRUE);
+ pData->note = 0;
+
+ /* reset file position and re-parse header */
+ pData->state = EAS_STATE_ERROR;
+ if ((result = OTA_ParseHeader (pEASData, pData)) != EAS_SUCCESS)
+ return result;
+
+ pData->state = EAS_STATE_READY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA *pData;
+
+ /* can't pause a stopped stream */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* mute the synthesizer */
+ VMMuteAllVoices(pEASData->pVoiceMgr, pData->pSynth);
+ pData->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_OTA_DATA *pData;
+
+ /* can't resume a stopped stream */
+ pData = (S_OTA_DATA*) pInstData;
+ if (pData->state == EAS_STATE_STOPPED)
+ return EAS_ERROR_ALREADY_STOPPED;
+
+ /* nothing to do but resume playback */
+ pData->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA *) pInstData;
+ switch (param)
+ {
+
+ /* set metadata callback */
+ case PARSER_DATA_METADATA_CB:
+ EAS_HWMemCpy(&pData->metadata, (void*) value, sizeof(S_METADATA_CB));
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Return file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
+static EAS_RESULT OTA_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ S_OTA_DATA *pData;
+
+ pData = (S_OTA_DATA*) pInstData;
+ switch (param)
+ {
+ /* return file type as OTA */
+ case PARSER_DATA_FILE_TYPE:
+ *pValue = EAS_FILE_OTA;
+ break;
+
+#if 0
+ /* set transposition */
+ case PARSER_DATA_TRANSPOSITION:
+ *pValue = pData->transposition;
+ break;
+#endif
+
+ case PARSER_DATA_SYNTH_HANDLE:
+ *pValue = (EAS_I32) pData->pSynth;
+ break;
+
+ case PARSER_DATA_GAIN_OFFSET:
+ *pValue = OTA_GAIN_OFFSET;
+ break;
+
+ default:
+ return EAS_ERROR_INVALID_PARAMETER;
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_ParseHeader()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_ParseHeader (S_EAS_DATA *pEASData, S_OTA_DATA* pData)
+{
+ EAS_RESULT result;
+ EAS_INT i;
+ EAS_INT state;
+ EAS_U8 temp;
+ EAS_U8 titleLen;
+
+ /* initialize some data */
+ pData->flags = 0;
+ pData->time = 0;
+ pData->tick = DEFAULT_TICK_CONV;
+ pData->patterns[0].fileOffset = pData->patterns[1].fileOffset =
+ pData->patterns[2].fileOffset = pData->patterns[3].fileOffset = -1;
+ pData->current.bitCount = 0;
+ pData->current.patternLen = 0;
+ pData->loopCount = 0;
+ pData->restore.fileOffset = -1;
+ pData->note = 0;
+ pData->restTicks = 0;
+ pData->velocity = OTA_VEL_DEFAULT;
+ pData->style = 0;
+ pData->octave = 59;
+
+ /* seek to start of data */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->fileOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* read the first byte, should be command length */
+ if ((result = EAS_HWGetByte(pEASData->hwInstData, pData->fileHandle, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* read all the commands */
+ i = temp;
+ state = 0;
+ while (i--)
+ {
+
+ /* fetch command, always starts on byte boundary */
+ pData->current.bitCount = 0;
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 7, &temp)) != EAS_SUCCESS)
+ return result;
+
+ if (state == 0)
+ {
+ if (temp != OTA_RINGTONE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Ring Tone Programming type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ state++;
+ }
+ else
+ {
+
+ if (temp == OTA_SOUND)
+ break;
+
+ if (temp == OTA_UNICODE)
+ pData->flags |= OTA_FLAGS_UNICODE;
+ else
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA Sound or Unicode type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+ }
+ }
+
+ /* get song type */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 3, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for basic song type */
+ if (temp == OTA_BASIC_SONG_TYPE)
+ {
+ /* fetch title length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 4, &titleLen)) != EAS_SUCCESS)
+ return result;
+
+ /* if unicode, double the length */
+ if (pData->flags & OTA_FLAGS_UNICODE)
+ titleLen = (EAS_U8) (titleLen << 1);
+
+ /* zero the metadata buffer */
+ if (pData->metadata.buffer)
+ EAS_HWMemSet(pData->metadata.buffer, 0, pData->metadata.bufferSize);
+
+ /* read the song title */
+ for (i = 0; i < titleLen; i++)
+ {
+ /* fetch character */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &temp)) != EAS_SUCCESS)
+ return result;
+
+ /* check for metadata callback */
+ if (pData->metadata.callback)
+ {
+ if (i < (pData->metadata.bufferSize - 1))
+ pData->metadata.buffer[i] = (char) temp;
+ }
+ }
+
+ /* if host has registered callback, call it now */
+ if (pData->metadata.callback)
+ (*pData->metadata.callback)(EAS_METADATA_TITLE, pData->metadata.buffer, pData->metadata.pUserData);
+ }
+
+ /* must be temporary song */
+ else if (temp != OTA_TEMPORARY_SONG_TYPE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected OTA basic or temporary song type\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* get the song length */
+ if ((result = OTA_FetchBitField(pEASData->hwInstData, pData, 8, &pData->numPatterns)) != EAS_SUCCESS)
+ return result;
+
+ /* sanity check */
+ if (pData->numPatterns == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "OTA number of patterns is zero\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* at start of first pattern */
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_FetchBitField()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Fetch a specified number of bits from the input stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_FetchBitField (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, EAS_I32 numBits, EAS_U8 *pValue)
+{
+ EAS_RESULT result;
+ EAS_I32 bitsLeft;
+ EAS_U8 value;
+
+ value = 0;
+
+ /* do we have enough bits? */
+ bitsLeft = pData->current.bitCount - numBits;
+
+ /* not enough bits, assemble them from 2 characters */
+ if (bitsLeft < 0)
+ {
+ /* grab the remaining bits from the previous byte */
+ if (pData->current.bitCount)
+ /*lint -e{504,734} this is a legitimate shift operation */
+ value = pData->current.dataByte << -bitsLeft;
+
+ /* read the next byte */
+ if ((result = EAS_HWGetByte(hwInstData, pData->fileHandle, &pData->current.dataByte)) != EAS_SUCCESS)
+ return result;
+ bitsLeft += 8;
+ }
+
+ /* more bits than needed? */
+ if (bitsLeft > 0)
+ {
+ value |= pData->current.dataByte >> bitsLeft;
+ pData->current.bitCount = (EAS_U8) bitsLeft;
+ pData->current.dataByte = pData->current.dataByte & (0xff >> (8 - bitsLeft));
+ }
+
+ /* exactly the right number of bits */
+ else
+ {
+ value |= pData->current.dataByte;
+ pData->current.bitCount = 0;
+ }
+
+ *pValue = value;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_SavePosition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_SavePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
+{
+ EAS_HWMemCpy(pLoc, &pData->current, sizeof(S_OTA_LOC));
+ return EAS_HWFilePos(hwInstData, pData->fileHandle, &pLoc->fileOffset);
+}
+
+/*----------------------------------------------------------------------------
+ * OTA_RestorePosition()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT OTA_RestorePosition (EAS_HW_DATA_HANDLE hwInstData, S_OTA_DATA *pData, S_OTA_LOC *pLoc)
+{
+ EAS_HWMemCpy(&pData->current, pLoc, sizeof(S_OTA_LOC));
+ pData->restore.fileOffset = -1;
+ return EAS_HWFileSeek(hwInstData, pData->fileHandle, pLoc->fileOffset);
+}
+
diff --git a/arm-wt-22k/lib_src/eas_otadata.c b/arm-wt-22k/lib_src/eas_otadata.c
new file mode 100644
index 0000000..237f832
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_otadata.c
@@ -0,0 +1,41 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_otadata..c
+ *
+ * Contents and purpose:
+ * OTA Stream Parser data module for static memory model
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 547 $
+ * $Date: 2007-01-31 16:30:17 -0800 (Wed, 31 Jan 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_types.h"
+#include "eas_otadata.h"
+
+/*----------------------------------------------------------------------------
+ *
+ * eas_OTAData
+ *
+ * Static memory allocation for OTA parser
+ *----------------------------------------------------------------------------
+*/
+S_OTA_DATA eas_OTAData;
+
diff --git a/arm-wt-22k/lib_src/eas_otadata.h b/arm-wt-22k/lib_src/eas_otadata.h
new file mode 100644
index 0000000..63e963f
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_otadata.h
@@ -0,0 +1,81 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_otadata.h
+ *
+ * Contents and purpose:
+ * OTA File Parser
+ *
+ * This file contains data declarations for the OTA parser.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_OTADATA_H
+#define EAS_OTADATA_H
+
+#include "eas_data.h"
+
+/* definition for state flags */
+#define OTA_FLAGS_UNICODE 0x01 /* unicode text */
+
+/*----------------------------------------------------------------------------
+ *
+ * S_OTA_DATA
+ *
+ * This structure contains the state data for the OTA parser
+ *----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ EAS_I32 fileOffset; /* offset to location in file */
+ EAS_U8 patternLen; /* length of current pattern */
+ EAS_U8 dataByte; /* previous char from file */
+ EAS_U8 bitCount; /* bit count in char */
+} S_OTA_LOC;
+
+typedef struct
+{
+ EAS_FILE_HANDLE fileHandle; /* file handle */
+ S_SYNTH *pSynth; /* synth handle */
+ EAS_I32 fileOffset; /* offset to start of data */
+ EAS_I32 time; /* current time in 256ths of a msec */
+ EAS_U32 tick; /* length of 32nd note in 256th of a msec */
+ EAS_U32 restTicks; /* ticks to rest after current note */
+ S_OTA_LOC patterns[4]; /* pattern locations */
+ S_OTA_LOC current; /* current location */
+ S_OTA_LOC restore; /* previous location */
+ S_METADATA_CB metadata; /* metadata callback */
+ EAS_U8 flags; /* bit flags */
+ EAS_U8 numPatterns; /* number of patterns left in song */
+ EAS_U8 currentPattern; /* current pattern for loop */
+ EAS_U8 note; /* MIDI note number */
+ EAS_U8 octave; /* octave modifier */
+ EAS_U8 style; /* from STYLE */
+ EAS_U8 velocity; /* current volume */
+ EAS_U8 state; /* current state EAS_STATE_XXXX */
+ EAS_U8 loopCount; /* loop count for pattern */
+} S_OTA_DATA;
+
+#endif
+
+
diff --git a/arm-wt-22k/lib_src/eas_pan.c b/arm-wt-22k/lib_src/eas_pan.c
new file mode 100644
index 0000000..373d90e
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_pan.c
@@ -0,0 +1,98 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pan.c
+ *
+ * Contents and purpose:
+ * Calculates left and right gain multipliers based on a pan value from -63 to +63
+ *
+ * NOTES:
+ * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
+ * whether the parser works for those particular file formats.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_pan.h"
+#include "eas_math.h"
+
+/*----------------------------------------------------------------------------
+ * EAS_CalcPanControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the left and right gain values corresponding to the given pan value.
+ *
+ * This routine uses sin/cos approximations for an equal power curve:
+ *
+ * sin(x) = (2-4*c)*x^2 + c + x
+ * cos(x) = (2-4*c)*x^2 + c - x
+ *
+ * where c = 1/sqrt(2)
+ * using the a0 + x*(a1 + x*a2) approach
+ *
+ * Inputs:
+ * pan - pan value (-63 to + 63)
+ *
+ * Outputs:
+ * pGainLeft linear gain multiplier for left channel (15-bit fraction)
+ * pGainRight linear gain multiplier for left channel (15-bit fraction)
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight)
+{
+ EAS_INT temp;
+ EAS_INT netAngle;
+
+ /* impose hard limit */
+ if (pan < -63)
+ netAngle = -63;
+ else if (pan > 63)
+ netAngle = 63;
+ else
+ netAngle = pan;
+
+ /*lint -e{701} <avoid multiply for performance reasons>*/
+ netAngle = netAngle << 8;
+
+ /* calculate sin */
+ temp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
+ temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
+
+ if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (temp < 0)
+ temp = 0;
+
+ *pGainRight = (EAS_I16) temp;
+
+ /* calculate cos */
+ temp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, netAngle);
+ temp = COEFF_PAN_G0 + FMUL_15x15(temp, netAngle);
+ if (temp > SYNTH_FULL_SCALE_EG1_GAIN)
+ temp = SYNTH_FULL_SCALE_EG1_GAIN;
+ else if (temp < 0)
+ temp = 0;
+
+ *pGainLeft = (EAS_I16) temp;
+}
+
diff --git a/arm-wt-22k/lib_src/eas_pan.h b/arm-wt-22k/lib_src/eas_pan.h
new file mode 100644
index 0000000..cefa650
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_pan.h
@@ -0,0 +1,66 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pan.h
+ *
+ * Contents and purpose:
+ * Calculates left and right gain multipliers based on a pan value from -63 to +63
+ *
+ * NOTES:
+ * The _CMX_PARSER and _MFI_PARSER preprocessor symbols determine
+ * whether the parser works for those particular file formats.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 82 $
+ * $Date: 2006-07-10 11:45:19 -0700 (Mon, 10 Jul 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef EAS_PAN_H
+#define _EAS_PAN_H
+
+#include "eas_types.h"
+
+/*----------------------------------------------------------------------------
+ * EAS_CalcPanControl()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Assign the left and right gain values corresponding to the given pan value.
+ *
+ * This routine uses sin/cos approximations for an equal power curve:
+ *
+ * sin(x) = (2-4*c)*x^2 + c + x
+ * cos(x) = (2-4*c)*x^2 + c - x
+ *
+ * where c = 1/sqrt(2)
+ * using the a0 + x*(a1 + x*a2) approach
+ *
+ * Inputs:
+ * pan - pan value (-63 to + 63)
+ *
+ * Outputs:
+ * pGainLeft linear gain multiplier for left channel (15-bit fraction)
+ * pGainRight linear gain multiplier for left channel (15-bit fraction)
+ *
+ * Side Effects:
+ *----------------------------------------------------------------------------
+*/
+void EAS_CalcPanControl (EAS_INT pan, EAS_I16 *pGainLeft, EAS_I16 *pGainRight);
+
+#endif
+
diff --git a/arm-wt-22k/lib_src/eas_parser.h b/arm-wt-22k/lib_src/eas_parser.h
new file mode 100644
index 0000000..5512c82
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_parser.h
@@ -0,0 +1,98 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_parser.h
+ *
+ * Contents and purpose:
+ * Interface declarations for the generic parser interface
+ *
+ * This header only contains declarations that are specific
+ * to this implementation.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 767 $
+ * $Date: 2007-07-19 13:47:31 -0700 (Thu, 19 Jul 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#ifndef _EAS_PARSER_H
+#define _EAS_PARSER_H
+
+#include "eas_types.h"
+
+
+/* metadata callback */
+typedef struct s_metadata_cb_tag
+{
+ EAS_METADATA_CBFUNC callback;
+ char *buffer;
+ EAS_VOID_PTR pUserData;
+ EAS_I32 bufferSize;
+} S_METADATA_CB;
+
+/* generic parser interface */
+typedef struct
+{
+ EAS_RESULT (* EAS_CONST pfCheckFileType)(struct s_eas_data_tag *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+ EAS_RESULT (* EAS_CONST pfPrepare)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfTime)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+ EAS_RESULT (* EAS_CONST pfEvent)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_INT parseMode);
+ EAS_RESULT (* EAS_CONST pfState)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+ EAS_RESULT (* EAS_CONST pfClose)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfReset)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfPause)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfResume)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData);
+ EAS_RESULT (* EAS_CONST pfLocate)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
+ EAS_RESULT (* EAS_CONST pfSetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+ EAS_RESULT (* EAS_CONST pfGetData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+ EAS_RESULT (* EAS_CONST pfGetMetaData)(struct s_eas_data_tag *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
+} S_FILE_PARSER_INTERFACE;
+
+typedef enum
+{
+ eParserModePlay,
+ eParserModeLocate,
+ eParserModeMute,
+ eParserModeMetaData
+} E_PARSE_MODE;
+
+typedef enum
+{
+ PARSER_DATA_FILE_TYPE,
+ PARSER_DATA_PLAYBACK_RATE,
+ PARSER_DATA_TRANSPOSITION,
+ PARSER_DATA_VOLUME,
+ PARSER_DATA_SYNTH_HANDLE,
+ PARSER_DATA_METADATA_CB,
+ PARSER_DATA_DLS_COLLECTION,
+ PARSER_DATA_EAS_LIBRARY,
+ PARSER_DATA_POLYPHONY,
+ PARSER_DATA_PRIORITY,
+ PARSER_DATA_FORMAT,
+ PARSER_DATA_MEDIA_LENGTH,
+ PARSER_DATA_JET_CB,
+ PARSER_DATA_MUTE_FLAGS,
+ PARSER_DATA_SET_MUTE,
+ PARSER_DATA_CLEAR_MUTE,
+ PARSER_DATA_NOTE_COUNT,
+ PARSER_DATA_MAX_PCM_STREAMS,
+ PARSER_DATA_GAIN_OFFSET,
+ PARSER_DATA_PLAY_MODE
+} E_PARSER_DATA;
+
+#endif /* #ifndef _EAS_PARSER_H */
diff --git a/arm-wt-22k/lib_src/eas_pcm.c b/arm-wt-22k/lib_src/eas_pcm.c
new file mode 100644
index 0000000..64b8f71
--- /dev/null
+++ b/arm-wt-22k/lib_src/eas_pcm.c
@@ -0,0 +1,1482 @@
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_pcm.c
+ *
+ * Contents and purpose:
+ * Implements the PCM engine including ADPCM decode for SMAF and CMX audio playback.
+ *
+ * Copyright Sonic Network Inc. 2005
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 849 $
+ * $Date: 2007-08-28 08:59:11 -0700 (Tue, 28 Aug 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_config.h"
+#include "eas_parser.h"
+#include "eas_pcm.h"
+#include "eas_math.h"
+#include "eas_mixer.h"
+
+#define PCM_MIXER_GUARD_BITS (NUM_MIXER_GUARD_BITS + 1)
+
+/*----------------------------------------------------------------------------
+ * Decoder interfaces
+ *----------------------------------------------------------------------------
+*/
+
+static EAS_RESULT LinearPCMDecode (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
+static EAS_RESULT LinearPCMLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
+
+static const S_DECODER_INTERFACE PCMDecoder =
+{
+ NULL,
+ LinearPCMDecode,
+ LinearPCMLocate,
+};
+
+/* SMAF ADPCM decoder */
+#ifdef _SMAF_PARSER
+extern S_DECODER_INTERFACE SmafDecoder;
+#define SMAF_DECODER &SmafDecoder
+extern S_DECODER_INTERFACE Smaf7BitDecoder;
+#define SMAF_7BIT_DECODER &Smaf7BitDecoder
+#else
+#define SMAF_DECODER NULL
+#define SMAF_7BIT_DECODER NULL
+#endif
+
+/* IMA ADPCM decoder */
+#ifdef _IMA_DECODER
+extern S_DECODER_INTERFACE IMADecoder;
+#define IMA_DECODER &IMADecoder
+#else
+#define IMA_DECODER NULL
+#endif
+
+static const S_DECODER_INTERFACE * const decoders[] =
+{
+ &PCMDecoder,
+ SMAF_DECODER,
+ IMA_DECODER,
+ SMAF_7BIT_DECODER
+};
+
+/*----------------------------------------------------------------------------
+ * Sample rate conversion
+ *----------------------------------------------------------------------------
+*/
+
+#define SRC_RATE_MULTIPLER (0x40000000 / _OUTPUT_SAMPLE_RATE)
+
+#ifdef _LOOKUP_SAMPLE_RATE
+static const EAS_U32 srcConvRate[][2] =
+{
+ 4000L, (4000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 8000L, (8000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 11025L, (11025L << 15) / _OUTPUT_SAMPLE_RATE,
+ 12000L, (12000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 16000L, (16000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 22050L, (22050L << 15) / _OUTPUT_SAMPLE_RATE,
+ 24000L, (24000L << 15) / _OUTPUT_SAMPLE_RATE,
+ 32000L, (32000L << 15) / _OUTPUT_SAMPLE_RATE
+};
+static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate);
+#define SRC_CONV_RATE_ENTRIES (sizeof(srcConvRate)/sizeof(EAS_U32)/2)
+#endif
+
+
+/* interface prototypes */
+static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples);
+
+
+/* local prototypes */
+static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData);
+static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState);
+
+/*----------------------------------------------------------------------------
+ * EAS_PEInit()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initializes the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEInit (S_EAS_DATA *pEASData)
+{
+ S_PCM_STATE *pState;
+ EAS_INT i;
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pEASData->pPCMStreams = EAS_CMEnumData(EAS_CM_PCM_DATA);
+ /* allocate dynamic memory */
+ else
+ pEASData->pPCMStreams = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
+
+ if (!pEASData->pPCMStreams)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL, "Failed to allocate memory for PCM streams\n"); */ }
+ return EAS_ERROR_MALLOC_FAILED;
+ }
+
+ //zero the memory to insure complete initialization
+ EAS_HWMemSet((void *)(pEASData->pPCMStreams),0, sizeof(S_PCM_STATE) * MAX_PCM_STREAMS);
+
+ /* initialize the state data */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ pState->fileHandle = NULL;
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEShutdown()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Shuts down the PCM engine
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEShutdown (S_EAS_DATA *pEASData)
+{
+
+ /* free any dynamic memory */
+ if (!pEASData->staticMemoryModel)
+ {
+ if (pEASData->pPCMStreams)
+ {
+ EAS_HWFree(pEASData->hwInstData, pEASData->pPCMStreams);
+ pEASData->pPCMStreams = NULL;
+ }
+ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PERender()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Render a buffer of PCM audio
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PERender (S_EAS_DATA* pEASData, EAS_I32 numSamples)
+{
+ S_PCM_STATE *pState;
+ EAS_RESULT result;
+ EAS_INT i;
+
+ /* render all the active streams */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ {
+ if ((pState->fileHandle) && (pState->state != EAS_STATE_STOPPED) && (pState->state != EAS_STATE_PAUSED))
+ if ((result = RenderPCMStream(pEASData, pState, numSamples)) != EAS_SUCCESS)
+ return result;
+ }
+ return EAS_SUCCESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EAS_PEState()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * This interface is also exposed in the internal library for use by the other modules.
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEState (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pInstData, EAS_STATE *pState)
+{
+ /* return current state */
+ *pState = pInstData->state;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEClose()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEClose (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_RESULT result;
+
+ if ((result = EAS_HWCloseFile(pEASData->hwInstData, pState->fileHandle)) != EAS_SUCCESS)
+ return result;
+
+ pState->fileHandle = NULL;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * PCM_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEReset (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_RESULT result;
+
+ /* reset file position to first byte of data in the stream */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, pState->startPos)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Error %d seeking to start of PCM file\n", result); */ }
+ return result;
+ }
+
+ /* re-initialize stream */
+ return InitPCMStream(pEASData, pState);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEOpenStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Starts up a PCM playback
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PEOpenStream (S_EAS_DATA *pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle)
+{
+ EAS_RESULT result;
+ S_PCM_STATE *pState;
+ EAS_I32 filePos;
+
+ /* make sure we support this decoder */
+ if (pParams->decoder >= NUM_DECODER_MODULES)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder selector out of range\n"); */ }
+ return EAS_ERROR_PARAMETER_RANGE;
+ }
+ if (decoders[pParams->decoder] == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Decoder module not available\n"); */ }
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+ }
+
+ /* find a slot for the new stream */
+ if ((pState = FindSlot(pEASData, pParams->fileHandle, pParams->pCallbackFunc, pParams->cbInstData)) == NULL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unable to open ADPCM stream, too many streams open\n"); */ }
+ return EAS_ERROR_MAX_PCM_STREAMS;
+ }
+
+ /* get the current file position */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, pState->fileHandle, &filePos)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWFilePos returned %ld\n",result); */ }
+ pState->fileHandle = NULL;
+ return result;
+ }
+
+ pState->pDecoder = decoders[pParams->decoder];
+ pState->startPos = filePos;
+ pState->bytesLeftLoop = pState->byteCount = pParams->size;
+ pState->loopStart = pParams->loopStart;
+ pState->samplesTilLoop = (EAS_I32) pState->loopStart;
+ pState->loopSamples = pParams->loopSamples;
+ pState->samplesInLoop = 0;
+ pState->blockSize = (EAS_U16) pParams->blockSize;
+ pState->flags = pParams->flags;
+ pState->envData = pParams->envData;
+ pState->volume = pParams->volume;
+ pState->sampleRate = (EAS_U16) pParams->sampleRate;
+
+ /* set the base frequency */
+ pState->basefreq = (SRC_RATE_MULTIPLER * (EAS_U32) pParams->sampleRate) >> 15;
+
+ /* calculate shift for frequencies > 1.0 */
+ pState->rateShift = 0;
+ while (pState->basefreq > 32767)
+ {
+ pState->basefreq = pState->basefreq >> 1;
+ pState->rateShift++;
+ }
+
+ /* initialize */
+ if ((result = InitPCMStream(pEASData, pState)) != EAS_SUCCESS)
+ return result;
+
+ *pHandle = pState;
+
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "EAS_PEOpenStream: StartPos=%d, byteCount = %d, loopSamples=%d\n",
+ pState->startPos, pState->byteCount, pState->loopSamples); */ }
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEContinueStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Continues a PCM stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -e{715} reserved for future use */
+EAS_RESULT EAS_PEContinueStream (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 size)
+{
+
+ /* add new samples to count */
+ pState->bytesLeft += size;
+ if (pState->bytesLeft > 0)
+ pState->flags &= ~PCM_FLAGS_EMPTY;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEGetFileHandle()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the file handle of a stream
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEGetFileHandle (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_FILE_HANDLE *pFileHandle)
+{
+ *pFileHandle = pState->fileHandle;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateParams()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch and volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * pitch - pitch shift in cents
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+/*lint -esym(715, gainRight) used only in 2-channel version */
+EAS_RESULT EAS_PEUpdateParams (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight)
+{
+
+ pState->gainLeft = gainLeft;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ pState->gainRight = gainRight;
+#endif
+
+ pState->pitch = pitch;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PELocate()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * This function seeks to the requested place in the file. Accuracy
+ * is dependent on the sample rate and block size.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pState - stream handle
+ * time - media time in milliseconds
+ *----------------------------------------------------------------------------
+*/
+EAS_RESULT EAS_PELocate (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState, EAS_I32 time)
+{
+ if (pState->pDecoder->pfLocate == NULL)
+ return EAS_ERROR_FEATURE_NOT_AVAILABLE;
+
+ return pState->pDecoder->pfLocate(pEASData, pState, time);
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdateVolume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the volume parameters for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ * gainLeft - linear gain multipler in 1.15 fraction format
+ * gainRight - linear gain multipler in 1.15 fraction format
+ * initial - initial settings, set current gain
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ * Notes
+ * In mono mode, leftGain controls the output gain and rightGain is ignored
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdateVolume (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume)
+{
+ pState->volume = volume;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEUpdatePitch()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Update the pitch parameter for a PCM stream
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * pState - pointer to S_PCM_STATE for this stream
+ * pitch - new pitch value in pitch cents
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEUpdatePitch (S_EAS_DATA* pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch)
+{
+ pState->pitch = pitch;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEPause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Mute and stop rendering a PCM stream. Sets the gain target to zero and stops the playback
+ * at the end of the next audio frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEPause (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ /* set state to stopping */
+ pState->state = EAS_STATE_PAUSING;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PEResume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume rendering a PCM stream. Sets the gain target back to its
+ * previous setting and restarts playback at the end of the next audio
+ * frame.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PEResume (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ /* set state to stopping */
+ pState->state = EAS_STATE_PLAY;
+ return EAS_SUCCESS;
+}
+
+EAS_U32 getDecayScale(EAS_U32 index)
+{
+ EAS_U32 utemp;
+
+ //envelope decay segment
+ switch (index)
+ {
+ case 0: //no decay
+ utemp = 512;//32768;
+ break;
+ case 1: //.0156 dB per update
+ utemp = 511;//32709;
+ break;
+ case 2: //.03125
+ utemp = 510;//32649;
+ break;
+ case 3: //.0625
+ utemp = 508;//32532;
+ break;
+ case 4: //.125
+ utemp = 505;//32298;
+ break;
+ case 5: //.25
+ utemp = 497;//31835;
+ break;
+ case 6: //.5
+ utemp = 483;//30929;
+ break;
+ case 7: //1.0
+ utemp = 456;//29193;
+ break;
+ case 8: //2.0
+ utemp = 406;//26008;
+ break;
+ case 9: //4.0
+ utemp = 323;//20642;
+ break;
+ case 10: //8.0
+ utemp = 203;//13004;
+ break;
+ case 11: //16.0
+ utemp = 81;//5160;
+ break;
+ case 12: //32.0
+ utemp = 13;//813;
+ break;
+ case 13: //64.0
+ utemp = 0;//20;
+ break;
+ case 14: //128.0
+ utemp = 0;
+ break;
+ case 15: //256.0
+ default:
+ utemp = 0;
+ break;
+ }
+ //printf("getdecayscale returned %d\n",utemp);
+ return utemp;
+}
+
+EAS_U32 getAttackIncrement(EAS_U32 index)
+{
+ EAS_U32 utemp;
+
+ //envelope decay segment
+ switch (index)
+ {
+ case 0:
+ utemp = 32;
+ break;
+ case 1:
+ utemp = 64;
+ break;
+ case 2:
+ utemp = 128;
+ break;
+ case 3:
+ utemp = 256;
+ break;
+ case 4:
+ utemp = 512;
+ break;
+ case 5:
+ utemp = 1024;
+ break;
+ case 6:
+ utemp = 2048;
+ break;
+ case 7:
+ utemp = 4096;
+ break;
+ case 8:
+ utemp = 8192;
+ break;
+ case 9:
+ utemp = 16384;
+ break;
+ case 10:
+ utemp = 32768;
+ break;
+ case 11:
+ utemp = 65536;
+ break;
+ case 12:
+ utemp = 65536;
+ break;
+ case 13:
+ utemp = 65536;
+ break;
+ case 14:
+ utemp = 65535;
+ break;
+ case 15:
+ default:
+ utemp = 0;
+ break;
+ }
+ //printf("getattackincrement returned %d\n",utemp);
+ return utemp;
+}
+
+/*----------------------------------------------------------------------------
+ * EAS_PERelease()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Put the PCM stream envelope into release.
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * handle - pointer to S_PCM_STATE for this stream
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+/*lint -esym(715, pEASData) reserved for future use */
+EAS_RESULT EAS_PERelease (S_EAS_DATA *pEASData, EAS_PCM_HANDLE pState)
+{
+ EAS_U32 utemp;
+
+ //printf("handling note-off part of envelope\n");
+ /*if the note is not ignore release or sustained*/
+ if (((pState->envData >> 24) & 0x0F)==0)
+ {
+ /* set envelope state to release */
+ pState->envState = PCM_ENV_RELEASE;
+ utemp = ((pState->envData >> 20) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getReleaseScale(utemp);
+ }
+ else
+ {
+ /*else change envelope state to sustain */
+ pState->envState = PCM_ENV_SUSTAIN;
+ utemp = ((pState->envData >> 28) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
+ }
+ //since we are in release, don't let anything hang around too long
+ //printf("checking env scale, val = %d\n",((S_PCM_STATE*) handle)->envScale);
+ if (pState->envScale > 505)
+ pState->envScale = 505;
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * FindSlot()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Locates an empty stream slot and assigns the file handle
+ *
+ * Inputs:
+ * pEASData - pointer to EAS library instance data
+ * fileHandle - file handle
+ * pCallbackFunc - function to be called back upon EAS_STATE_STOPPED
+ *
+ * Outputs:
+ * returns handle to slot or NULL if all slots are used
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static S_PCM_STATE *FindSlot (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_PCM_CALLBACK pCallbackFunc, EAS_VOID_PTR cbInstData)
+{
+ EAS_INT i;
+ S_PCM_STATE *pState;
+
+#ifndef NO_PCM_STEAL
+ S_PCM_STATE *foundState = NULL;
+ EAS_INT count = 0;
+ EAS_U32 startOrder = 0xFFFFFFFF;
+ S_PCM_STATE *stealState = NULL;
+ EAS_U32 youngest = 0;
+
+ /* find an empty slot, count total in use, and find oldest in use (lowest start order) */
+ for (i = 0, pState = pEASData->pPCMStreams; i < MAX_PCM_STREAMS; i++, pState++)
+ {
+ /* if this one is available */
+ if (pState->fileHandle == NULL)
+ {
+ foundState = pState;
+ }
+ /* else this one is in use, so see if it is the oldest, and count total in use */
+ /* also find youngest */
+ else
+ {
+ /*one more voice in use*/
+ count++;
+ /* is this the oldest? (lowest start order) */
+ if ((pState->state != EAS_STATE_STOPPING) && (pState->startOrder < startOrder))
+ {
+ /* remember this one */
+ stealState = pState;
+ /* remember the oldest so far */
+ startOrder = pState->startOrder;
+ }
+ /* is this the youngest? (highest start order) */
+ if (pState->startOrder >= youngest)
+ {
+ youngest = pState->startOrder;
+ }
+ }
+ }
+
+ /* if there are too many voices active, stop the oldest one */
+ if (count > PCM_STREAM_THRESHOLD)
+ {
+ //printf("stealing!!!\n");
+ /* make sure we got one, although we should always have one at this point */
+ if (stealState != NULL)
+ {
+ //flag this as stopping, so it will get shut off
+ stealState->state = EAS_STATE_STOPPING;
+ }
+ }
+
+ /* if there are no available open streams (we won't likely see this, due to stealing) */
+ if (foundState == NULL)
+ return NULL;
+
+ /* save info */
+ foundState->startOrder = youngest + 1;
+ foundState->fileHandle = fileHandle;
+ foundState->pCallback = pCallbackFunc;
+ foundState->cbInstData = cbInstData;
+ return foundState;
+#else
+ /* find an empty slot*/
+ for (i = 0; i < MAX_PCM_STREAMS; i++)
+ {
+ pState = &pEASData->pPCMStreams[i];
+ if (pState->fileHandle != NULL)
+ continue;
+
+ pState->fileHandle = fileHandle;
+ pState->pCallback = pCallbackFunc;
+ pState->cbInstData = cbInstData;
+ return pState;
+ }
+ return NULL;
+#endif
+}
+
+#ifdef _LOOKUP_SAMPLE_RATE
+/*----------------------------------------------------------------------------
+ * CalcBaseFreq()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Calculates the fractional phase increment for the sample rate converter
+ *
+ * Inputs:
+ * sampleRate - sample rate in samples/sec
+ *
+ * Outputs:
+ * Returns fractional sample rate with a 15-bit fraction
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_U32 CalcBaseFreq (EAS_U32 sampleRate)
+{
+ EAS_INT i;
+
+ /* look up the conversion rate */
+ for (i = 0; i < (EAS_INT)(SRC_CONV_RATE_ENTRIES); i ++)
+ {
+ if (srcConvRate[i][0] == sampleRate)
+ return srcConvRate[i][1];
+ }
+
+ /* if not found in table, do it the long way */
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Sample rate %u not in table, calculating by division\n", sampleRate); */ }
+
+ return (SRC_RATE_MULTIPLER * (EAS_U32) sampleRate) >> 15;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * InitPCMStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Start an ADPCM stream playback. Decodes the header, preps the engine.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT InitPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState)
+{
+
+ /* initialize the data structure */
+ pState->bytesLeft = pState->byteCount;
+ pState->phase = 0;
+ pState->srcByte = 0;
+ pState->decoderL.acc = 0;
+ pState->decoderL.output = 0;
+ pState->decoderL.x0 = pState->decoderL.x1 = 0;
+ pState->decoderL.step = 0;
+ pState->decoderR.acc = 0;
+ pState->decoderR.output = 0;
+ pState->decoderR.x0 = pState->decoderR.x1 = 0;
+ pState->decoderR.step = 0;
+ pState->hiNibble = EAS_FALSE;
+ pState->pitch = 0;
+ pState->blockCount = 0;
+ pState->gainLeft = PCM_DEFAULT_GAIN_SETTING;
+// pState->currentGainLeft = PCM_DEFAULT_GAIN_SETTING;
+ pState->envValue = 0;
+ pState->envState = PCM_ENV_START;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ pState->gainRight = PCM_DEFAULT_GAIN_SETTING;
+// pState->currentGainRight = PCM_DEFAULT_GAIN_SETTING;
+#endif
+ pState->state = EAS_STATE_READY;
+
+ /* initialize the decoder */
+ if (pState->pDecoder->pfInit)
+ return (*pState->pDecoder->pfInit)(pEASData, pState);
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * RenderPCMStream()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Decodes a buffer of ADPCM data.
+ *
+ * Inputs:
+ *
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT RenderPCMStream (S_EAS_DATA *pEASData, S_PCM_STATE *pState, EAS_I32 numSamples)
+{
+ EAS_RESULT result;
+ EAS_U32 phaseInc;
+ EAS_I32 gainLeft, gainIncLeft;
+ EAS_I32 *pOut;
+ EAS_I32 temp;
+ EAS_U32 utemp;
+
+#if (NUM_OUTPUT_CHANNELS == 2)
+ EAS_I32 gainRight, gainIncRight;
+#endif
+
+#if 0
+ printf("env data: AR = %d, DR = %d, SL = %d, SR = %d, RR = %d\n",
+ ((pState->envData >> 12) & 0x0F),
+ ((pState->envData >> 16) & 0x0F),
+ ((pState->envData >> 8) & 0x0F),
+ ((pState->envData >> 28) & 0x0F),
+ ((pState->envData >> 20) & 0x0F));
+#endif
+
+ if (pState->envState == PCM_ENV_START)
+ {
+ //printf("env start\n");
+ utemp = ((pState->envData >> 12) & 0x0F);
+ //if fastest rate, attack is already completed
+ //do the same for slowest rate, since that allows zero to be passed for default envelope
+ if (utemp == 0x0F || utemp == 0x00)
+ {
+ //start envelope at full
+ pState->envValue = (32768<<7);
+ //jump right into decay
+ utemp = ((pState->envData >> 16) & 0x0F);
+ pState->envScale = getDecayScale(utemp);
+ pState->envState = PCM_ENV_DECAY;
+ pState->currentGainLeft = (EAS_I16) FMUL_15x15(pState->gainLeft, pState->volume);
+ pState->currentGainRight = (EAS_I16) FMUL_15x15(pState->gainRight, pState->volume);
+ }
+ //else attack has a ramp
+ else
+ {
+ //start the envelope very low
+ pState->envValue = (2<<7);
+ pState->currentGainLeft = 0;
+ pState->currentGainRight = 0;
+ //get envelope attack scaling value
+ pState->envScale = getAttackIncrement(utemp);
+ //go to attack state
+ pState->envState = PCM_ENV_ATTACK;
+ }
+ }
+ if (pState->envState == PCM_ENV_ATTACK)
+ {
+ //printf("env attack, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = pState->envValue + (pState->envScale << 7);
+ //check envelope level and update state if needed
+ if (pState->envValue >= (32768<<7))
+ {
+ pState->envValue = (32768<<7);
+ utemp = ((pState->envData >> 16) & 0x0F);
+ pState->envScale = getDecayScale(utemp);
+ pState->envState = PCM_ENV_DECAY;
+ }
+ }
+ else if (pState->envState == PCM_ENV_DECAY)
+ {
+ //printf("env decay, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against sustain level and update state if needed
+ utemp = ((pState->envData >> 8) & 0x0F);
+ if (utemp == (EAS_U32)0x0F)
+ utemp = (2<<7);
+ else
+ {
+ utemp = ((32769<<7) >> (utemp>>1));
+ }
+ if (pState->envValue <= utemp)
+ {
+ utemp = ((pState->envData >> 28) & 0x0F);
+ pState->envScale = getDecayScale(utemp); //getSustainScale(utemp);
+ pState->envState = PCM_ENV_SUSTAIN;
+ }
+ }
+ else if (pState->envState == PCM_ENV_SUSTAIN)
+ {
+ //printf("env sustain, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against bottom level and update state if needed
+ if (pState->envValue <= (2<<7))
+ {
+ //no more decay
+ pState->envScale = 512;
+ pState->envState = PCM_ENV_END;
+ }
+ }
+ else if (pState->envState == PCM_ENV_RELEASE)
+ {
+ //printf("env release, env value = %d, env scale = %d\n",pState->envValue>>7,pState->envScale);
+ //update envelope value
+ pState->envValue = (pState->envValue * pState->envScale)>>9;
+ //check envelope level against bottom level and update state if needed
+ if (pState->envValue <= (2<<7))
+ {
+ //no more decay
+ pState->envScale = 512;
+ pState->envState = PCM_ENV_END;
+ }
+ }
+ else if (pState->envState == PCM_ENV_END)
+ {
+ //printf("env end\n");
+ /* set state to stopping, already ramped down */
+ pState->state = EAS_STATE_STOPPING;
+ }
+
+ //pState->gainLeft = (EAS_U16)((pState->gainLeft * (pState->envValue>>7))>>15);
+ //pState->gainRight = (EAS_U16)((pState->gainRight * (pState->envValue>>7))>>15);
+
+ /* gain to 32-bits to increase resolution on anti-zipper filter */
+ /*lint -e{703} use shift for performance */
+ gainLeft = (EAS_I32) pState->currentGainLeft << SYNTH_UPDATE_PERIOD_IN_BITS;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ /*lint -e{703} use shift for performance */
+ gainRight = (EAS_I32) pState->currentGainRight << SYNTH_UPDATE_PERIOD_IN_BITS;
+#endif
+
+ /* calculate a new gain increment, gain target is zero if pausing */
+ if ((pState->state == EAS_STATE_PAUSING) || (pState->state == EAS_STATE_PAUSED))
+ {
+ gainIncLeft = -pState->currentGainLeft;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainIncRight= -pState->currentGainRight;
+#endif
+ }
+ else
+ {
+ EAS_I32 gain = FMUL_15x15(pState->envValue >> 7, pState->volume);
+ gainIncLeft = FMUL_15x15(pState->gainLeft, gain) - pState->currentGainLeft;
+#if (NUM_OUTPUT_CHANNELS == 2)
+ gainIncRight = FMUL_15x15(pState->gainRight, gain) - pState->currentGainRight;
+#endif
+ }
+
+ /* calculate phase increment */
+ phaseInc = pState->basefreq;
+
+ /* convert pitch cents to linear multiplier */
+ if (pState->pitch)
+ {
+ temp = EAS_Calculate2toX(pState->pitch);
+ phaseInc = FMUL_15x15(phaseInc, temp);
+ }
+ phaseInc = phaseInc << pState->rateShift;
+
+ /* pointer to mix buffer */
+ pOut = pEASData->pMixBuffer;
+
+ /* render a buffer of samples */
+ while (numSamples--)
+ {
+
+ /* interpolate an output sample */
+ pState->decoderL.output = pState->decoderL.x0 + FMUL_15x15((pState->decoderL.x1 - pState->decoderL.x0), pState->phase & PHASE_FRAC_MASK);
+
+ /* stereo output */
+#if (NUM_OUTPUT_CH