Initial Commit

This commit is contained in:
Jeff Farrand
2014-01-12 09:48:16 -06:00
commit 5b1ff23e0f
759 changed files with 319871 additions and 0 deletions

102
common/SDL_shim/SDL_Mixer.h Executable file
View File

@@ -0,0 +1,102 @@
/*
Copyright (C) 2011 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef doomengine_SDL_Mixer_h
#define doomengine_SDL_Mixer_h
#ifdef __cplusplus
extern "C" {
#endif
/*
===============================
This is a minimal implemenation of SDL_Mixer for iOS, just to get MIDI files
playing so that we can play the music directly from the WADs.
===============================
*/
#include <stdint.h>
typedef struct Mix_Music_tag {
char unused;
} Mix_Music;
/* Open the mixer with a certain audio format */
extern int Mix_OpenAudio(int frequency, uint16_t format, int channels,
int chunksize);
/* Close the mixer, halting all playing audio */
extern void Mix_CloseAudio(void);
/* Set a function that is called after all mixing is performed.
This can be used to provide real-time visual display of the audio stream
or add a custom mixer filter for the stream data.
*/
extern void Mix_SetPostMix(void (*mix_func)
(void *udata, uint8_t *stream, int len), void *arg);
/* Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions */
extern int Mix_FadeInMusic(Mix_Music *music, int loops, int ms);
/* Pause/Resume the music stream */
extern void Mix_PauseMusic(void);
extern void Mix_ResumeMusic(void);
/* Halt a channel, fading it out progressively till it's silent
The ms parameter indicates the number of milliseconds the fading
will take.
*/
extern int Mix_FadeOutMusic(int ms);
/* Free an audio chunk previously loaded */
extern void Mix_FreeMusic(Mix_Music *music);
/* Load a wave file or a music (.mod .s3m .it .xm) file */
extern Mix_Music * Mix_LoadMUS(const char *file);
extern const char * Mix_GetError(void);
/* Set the volume in the range of 0-128 of a specific channel or chunk.
If the specified channel is -1, set volume for all channels.
Returns the original volume.
If the specified volume is -1, just return the current volume.
*/
extern int Mix_VolumeMusic(int volume);
#ifdef __cplusplus
}
#endif
#endif

517
common/SDL_shim/ios/SDL_Mixer.m Executable file
View File

@@ -0,0 +1,517 @@
/*
Copyright (C) 2011 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
===============================
iOS implementation of our SDL_Mixer shim for playing MIDI files.
===============================
*/
#include <stddef.h>
#include "SDL_Mixer.h"
// Use the Embedded Audio Synthesis library as the backend MIDI renderer.
#include "embeddedaudiosynthesis/EASGlue.h"
// Use Core Audio Units for sound output on the device.
#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>
/*
===============================
"Constants"
===============================
*/
#define ID_GRAPH_SAMPLE_RATE 22050
/*
===============================
Internal Structures
===============================
*/
// Data structure for mono or stereo sound, to pass to the application's render callback function,
// which gets invoked by a Mixer unit input bus when it needs more audio to play.
typedef struct {
BOOL isStereo; // set to true if there is data in the audioDataRight member
UInt32 frameCount; // the total number of frames in the audio data
UInt32 sampleNumber; // the next audio sample to play
} soundStruct, *soundStructPtr;
typedef struct MIDIPlayerGraph_tag {
AUGraph processingGraph;
AudioUnit ioUnit;
BOOL playing;
AudioStreamBasicDescription streamFormat;
soundStruct soundStructInst;
} MIDIPlayerGraph;
static MIDIPlayerGraph midiPlayer;
/*
===============================
Internal prototypes
===============================
*/
AudioStreamBasicDescription getStreamFormat( void );
static void printASBD( AudioStreamBasicDescription asbd );
static void printErrorMessage( NSString * errorString, OSStatus result );
static void configureAndInitializeAudioProcessingGraph( MIDIPlayerGraph * player );
static void startMIDIPlayer( MIDIPlayerGraph * player );
// AU graph callback.
static OSStatus inputRenderCallback (
void *inRefCon, // A pointer to a struct containing the complete audio data
// to play, as well as state information such as the
// first sample to play on this invocation of the callback.
AudioUnitRenderActionFlags *ioActionFlags, // Unused here. When generating audio, use ioActionFlags to indicate silence
// between sounds; for silence, also memset the ioData buffers to 0.
const AudioTimeStamp *inTimeStamp, // Unused here.
UInt32 inBusNumber, // The mixer unit input bus that is requesting some new
// frames of audio data to play.
UInt32 inNumberFrames, // The number of frames of audio to provide to the buffer(s)
// pointed to by the ioData parameter.
AudioBufferList *ioData // On output, the audio data to play. The callback's primary
// responsibility is to fill the buffer(s) in the
// AudioBufferList.
);
/* Open the mixer with a certain audio format */
int Mix_OpenAudio(int frequency, uint16_t format, int channels,
int chunksize) {
EASGlueInit();
midiPlayer.streamFormat = getStreamFormat();
midiPlayer.playing = FALSE;
configureAndInitializeAudioProcessingGraph( &midiPlayer );
return 0;
}
/* Close the mixer, halting all playing audio */
void Mix_CloseAudio(void) {
AUGraphStop( midiPlayer.processingGraph );
EASGlueShutdown();
}
/* Set a function that is called after all mixing is performed.
This can be used to provide real-time visual display of the audio stream
or add a custom mixer filter for the stream data.
*/
void Mix_SetPostMix(void (*mix_func)
(void *udata, uint8_t *stream, int len), void *arg) {
}
/* Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions */
int Mix_FadeInMusic(Mix_Music *music, int loops, int ms) {
startMIDIPlayer( &midiPlayer );
return 0;
}
/* Pause/Resume the music stream */
void Mix_PauseMusic(void) {
EASGluePause();
}
void Mix_ResumeMusic(void) {
EASGlueResume();
}
/* Halt a channel, fading it out progressively till it's silent
The ms parameter indicates the number of milliseconds the fading
will take.
*/
int Mix_FadeOutMusic(int ms) {
EASGlueCloseFile();
AUGraphStop( midiPlayer.processingGraph );
return 1;
}
/* Free an audio chunk previously loaded */
void Mix_FreeMusic(Mix_Music *music) {
free(music);
}
/* Load a wave file or a music (.mod .s3m .it .xm) file */
Mix_Music * Mix_LoadMUS(const char *file) {
EASGlueOpenFile( file );
Mix_Music * musicStruct = malloc( sizeof(Mix_Music) );
return musicStruct;
}
const char * Mix_GetError(void) {
return "";
}
/* Set the volume in the range of 0-128 of a specific channel or chunk.
If the specified channel is -1, set volume for all channels.
Returns the original volume.
If the specified volume is -1, just return the current volume.
*/
int Mix_VolumeMusic(int volume) {
return 0;
}
/*
=================================
Audio Unit helper functions
=================================
*/
AudioStreamBasicDescription getStreamFormat( void ) {
AudioStreamBasicDescription streamFormat = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// The AudioUnitSampleType data type is the recommended type for sample data in audio
// units. This obtains the byte size of the type for use in filling in the ASBD.
size_t bytesPerSample = sizeof (AudioUnitSampleType);
// Fill the application audio format struct's fields to define a linear PCM,
// stereo, noninterleaved stream at the hardware sample rate.
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
streamFormat.mBytesPerPacket = bytesPerSample;
streamFormat.mFramesPerPacket = 1;
streamFormat.mBytesPerFrame = bytesPerSample;
streamFormat.mChannelsPerFrame = 2; // 2 indicates stereo
streamFormat.mBitsPerChannel = 8 * bytesPerSample;
streamFormat.mSampleRate = ID_GRAPH_SAMPLE_RATE;
NSLog (@"The stereo stream format for the I/O unit:");
printASBD( streamFormat );
return streamFormat;
}
static void startMIDIPlayer( MIDIPlayerGraph * player ) {
if ( player == 0 ) {
NSLog( @"NULL player object, can't start!" );
return;
}
NSLog (@"Starting audio processing graph");
OSStatus result = AUGraphStart (player->processingGraph);
if (noErr != result) { printErrorMessage( @"AUGraphStart", result ); return;}
player->playing = YES;
}
// You can use this method during development and debugging to look at the
// fields of an AudioStreamBasicDescription struct.
static void printASBD( AudioStreamBasicDescription asbd ) {
char formatIDString[5];
UInt32 formatID = CFSwapInt32HostToBig (asbd.mFormatID);
bcopy (&formatID, formatIDString, 4);
formatIDString[4] = '\0';
NSLog (@" Sample Rate: %10.0f", asbd.mSampleRate);
NSLog (@" Format ID: %10s", formatIDString);
NSLog (@" Format Flags: %10lX", asbd.mFormatFlags);
NSLog (@" Bytes per Packet: %10lu", asbd.mBytesPerPacket);
NSLog (@" Frames per Packet: %10lu", asbd.mFramesPerPacket);
NSLog (@" Bytes per Frame: %10lu", asbd.mBytesPerFrame);
NSLog (@" Channels per Frame: %10lu", asbd.mChannelsPerFrame);
NSLog (@" Bits per Channel: %10lu", asbd.mBitsPerChannel);
}
static void printErrorMessage( NSString * errorString, OSStatus result ) {
char resultString[5];
UInt32 swappedResult = CFSwapInt32HostToBig (result);
bcopy (&swappedResult, resultString, 4);
resultString[4] = '\0';
NSLog (
@"*** %@ error: %s\n",
errorString,
(char*) &resultString
);
}
// This method performs all the work needed to set up the audio processing graph:
// 1. Instantiate and open an audio processing graph
// 2. Obtain the audio unit nodes for the graph
// 3. Configure the Multichannel Mixer unit
// * specify the number of input buses
// * specify the output sample rate
// * specify the maximum frames-per-slice
// 4. Initialize the audio processing graph
static void configureAndInitializeAudioProcessingGraph( MIDIPlayerGraph * player ) {
if ( player == 0 ) {
NSLog( @"NULL player graph object, can't initialize it!" );
return;
}
NSLog (@"Configuring and then initializing audio processing graph");
OSStatus result = noErr;
//............................................................................
// Create a new audio processing graph.
result = NewAUGraph (&player->processingGraph);
if (noErr != result) { printErrorMessage( @"NewAUGraph", result ); return;}
//............................................................................
// Specify the audio unit component descriptions for the audio units to be
// added to the graph.
// I/O unit
AudioComponentDescription iOUnitDescription;
iOUnitDescription.componentType = kAudioUnitType_Output;
iOUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;
iOUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
iOUnitDescription.componentFlags = 0;
iOUnitDescription.componentFlagsMask = 0;
//............................................................................
// Add nodes to the audio processing graph.
NSLog (@"Adding nodes to audio processing graph");
AUNode iONode; // node for I/O unit
// Add the nodes to the audio processing graph
result = AUGraphAddNode (
player->processingGraph,
&iOUnitDescription,
&iONode);
if (noErr != result) { printErrorMessage( @"AUGraphNewNode failed for I/O unit", result ); return;}
//............................................................................
// Open the audio processing graph
// Following this call, the audio units are instantiated but not initialized
// (no resource allocation occurs and the audio units are not in a state to
// process audio).
result = AUGraphOpen (player->processingGraph);
if (noErr != result) { printErrorMessage( @"AUGraphOpen", result ); return;}
//............................................................................
// Obtain the mixer unit instance from its corresponding node.
result = AUGraphNodeInfo (
player->processingGraph,
iONode,
NULL,
&player->ioUnit
);
if (noErr != result) { printErrorMessage( @"AUGraphNodeInfo", result ); return;}
//............................................................................
// Multichannel Mixer unit Setup
// Setup the struture that contains the input render callback
AURenderCallbackStruct inputCallbackStruct;
inputCallbackStruct.inputProc = &inputRenderCallback;
inputCallbackStruct.inputProcRefCon = &player->soundStructInst;
NSLog (@"Registering the render callback with the I/O unit" );
// Set a callback for the specified node's specified input
result = AUGraphSetNodeInputCallback (
player->processingGraph,
iONode,
0,
&inputCallbackStruct
);
if (noErr != result) { printErrorMessage( @"AUGraphSetNodeInputCallback", result ); return;}
NSLog (@"Setting stereo stream format for I/O unit input bus");
result = AudioUnitSetProperty (
player->ioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&player->streamFormat,
sizeof (player->streamFormat)
);
if (noErr != result) { printErrorMessage( @"AudioUnitSetProperty (set input bus stream format)", result ); return;}
//............................................................................
// Initialize audio processing graph
// Diagnostic code
// Call CAShow if you want to look at the state of the audio processing
// graph.
NSLog (@"Audio processing graph state immediately before initializing it:");
CAShow (player->processingGraph);
NSLog (@"Initializing the audio processing graph");
// Initialize the audio processing graph, configure audio data stream formats for
// each input and output, and validate the connections between audio units.
result = AUGraphInitialize (player->processingGraph);
if (noErr != result) { printErrorMessage( @"AUGraphInitialize", result ); return;}
}
#define RAW_EAS_BUFFER_FRAMES 128
static OSStatus inputRenderCallback (
void *inRefCon, // A pointer to a struct containing the complete audio data
// to play, as well as state information such as the
// first sample to play on this invocation of the callback.
AudioUnitRenderActionFlags *ioActionFlags, // Unused here. When generating audio, use ioActionFlags to indicate silence
// between sounds; for silence, also memset the ioData buffers to 0.
const AudioTimeStamp *inTimeStamp, // Unused here.
UInt32 inBusNumber, // The mixer unit input bus that is requesting some new
// frames of audio data to play.
UInt32 inNumberFrames, // The number of frames of audio to provide to the buffer(s)
// pointed to by the ioData parameter.
AudioBufferList *ioData // On output, the audio data to play. The callback's primary
// responsibility is to fill the buffer(s) in the
// AudioBufferList.
) {
//printf( "Need %lu samples in %lu buffers!\n", inNumberFrames, ioData->mNumberBuffers );
EAS_I32 generatedThisRender = 0;
EAS_I32 totalGenerated = 0;
// It looks like EAS interleaves stereo samples, so we have to separate them into the two
// different buffers that the audio unit provides.
//const UInt32 totalInterleavedSamplesNeeded = inNumberFrames * 2;
AudioBuffer * audioBufferLeft = &ioData->mBuffers[0];
AudioBuffer * audioBufferRight = &ioData->mBuffers[1];
/*
printf( "Need %lu samples in %lu buffers!\n"
"audioBuffer byte size: %lu channels: %lu\n",
inNumberFrames, ioData->mNumberBuffers,
audioBuffer->mDataByteSize, audioBuffer->mNumberChannels );
*/
AudioUnitSampleType * hardwareBufferLeft = (AudioUnitSampleType *) audioBufferLeft->mData;
AudioUnitSampleType * hardwareBufferRight = (AudioUnitSampleType *) audioBufferRight->mData;
// EAS_Render always produces BUFFER_SIZE_IN_MONO_SAMPLES frames per call. Currently, this
// is defined to 128. Let's fill up a 128 frame buffer, then do a conversion from EAS_PCM
// (which is signed 16-bit integer) to AudioUnitSampleType (which is 8.24 fixed-point with
// a range of -1 to +1).
//
// Note that EAS renders interleaved stereo, so we actually a buffer size of
// 2 * BUFFER_SIZE_IN_MONO_SAMPLES.
EAS_PCM rawEASSamples[RAW_EAS_BUFFER_FRAMES * 2];
// EAS generates interleaved stereo samples, but the AudioUnit wants noninterleaved.
while ( totalGenerated < inNumberFrames ) {
//EASGlueRender( hardwareBuffer + totalGenerated*2, &generatedThisRender );
EASGlueRender( rawEASSamples, &generatedThisRender );
// Convert from EAS's signed 16-bit format to the AudioUnit's 8.24 fixed-point format.
// Couldn't find this in the Apple docs, but the 8.24 format should be in the range of
// -1.0 to 1.0, wasting 6 bits of precision.
// All we have to do here is left-shift by 9 bits. This will not overflow, because the
// destination is a 32-bit value.
// Also take this opportunity to de-interleave the EAS-rendered samples.
for ( int i = 0; i < RAW_EAS_BUFFER_FRAMES; ++i ) {
hardwareBufferLeft[totalGenerated + i] = rawEASSamples[i * 2 + 0] << 9;
hardwareBufferRight[totalGenerated + i] = rawEASSamples[i * 2 + 1] << 9;
}
totalGenerated += generatedThisRender;
}
return noErr;
}

View File

@@ -0,0 +1 @@
include $(all-subdir-makefiles)

View File

@@ -0,0 +1,211 @@
/*
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "EASGlue.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "eas.h"
#include "eas_wave.h"
#include "eas_report.h"
#define NUM_BUFFERS 1
#ifndef NDEBUG
static EAS_BOOL EASLibraryCheck (const S_EAS_LIB_CONFIG *pLibConfig);
#endif
static EAS_DATA_HANDLE pEASData;
static const S_EAS_LIB_CONFIG *pLibConfig;
static int polyphony;
static int bufferSize;
static EAS_FILE file;
static EAS_HANDLE handle;
void EASGlueInit(void) {
EAS_RESULT result;
/* get the library configuration */
pLibConfig = EAS_Config();
assert( EASLibraryCheck(pLibConfig) );
if (polyphony > pLibConfig->maxVoices)
polyphony = pLibConfig->maxVoices;
EAS_I32 mixSize = pLibConfig->mixBufferSize;
bufferSize = mixSize * pLibConfig->numChannels * (EAS_I32)sizeof(EAS_PCM) * NUM_BUFFERS;
/* calculate buffer size */
//bufferSize = pLibConfig->mixBufferSize * pLibConfig->numChannels * (EAS_I32)sizeof(EAS_PCM) * NUM_BUFFERS;
if ( (result = EAS_Init(&pEASData)) != EAS_SUCCESS ) {
printf( "Error initializing EAS: %li\n", result );
}
}
void EASGlueShutdown(void) {
EAS_RESULT result;
EASGlueCloseFile();
if ( (result = EAS_Shutdown(pEASData)) != EAS_SUCCESS ) {
printf( "Error shutting down EAS: %li\n", result );
}
}
void EASGlueOpenFile( const char * filename ) {
EAS_RESULT result;
/* open the file */
file.path = filename;
file.fd = 0;
if ((result = EAS_OpenFile(pEASData, &file, &handle)) != EAS_SUCCESS) {
printf( "Error opening EAS file: %li\n", result );
return;
}
EAS_SetRepeat( pEASData, handle, -1 );
/* prepare for playback */
if ((result = EAS_Prepare(pEASData, handle)) != EAS_SUCCESS) {
printf( "Error preparing EAS file: %li\n", result );
return;
}
}
void EASGluePause(void) {
EAS_RESULT result;
if ( handle == 0 ) {
return;
}
result = EAS_Pause( pEASData, handle );
if ( result != EAS_SUCCESS ) {
printf( "Error pausing EAS file: %li\n", result );
}
}
void EASGlueResume(void) {
EAS_RESULT result;
result = EAS_Resume( pEASData, handle );
if ( result != EAS_SUCCESS ) {
printf( "Error pausing EAS file: %li\n", result );
}
}
void EASGlueCloseFile(void) {
if ( handle == 0 ) {
return;
}
// File must be paused or stopped before closing it.
EASGluePause();
EAS_RESULT result;
result = EAS_CloseFile( pEASData, handle );
if ( result != EAS_SUCCESS ) {
printf( "Error closing EAS file: %li\n", result );
}
handle = 0;
}
void EASGlueRender( EAS_PCM * outputBuffer, EAS_I32 * generatedSamples ) {
EAS_RESULT result;
if ( ( result = EAS_Render( pEASData, outputBuffer, pLibConfig->mixBufferSize, generatedSamples ) ) != EAS_SUCCESS ) {
printf( "Error rendering EAS: %li\n.", result );
return;
}
}
#ifndef NDEBUG
/*----------------------------------------------------------------------------
* 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 *libConfig)
{
/* display the library version */
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "EAS Library Version %d.%d.%d.%d\n",
libConfig->libVersion >> 24,
(libConfig->libVersion >> 16) & 0x0f,
(libConfig->libVersion >> 8) & 0x0f,
libConfig->libVersion & 0x0f); */ }
/* display some info about the library build */
if (libConfig->checkedVersion)
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tChecked library\n"); */ }
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMaximum polyphony: %d\n", libConfig->maxVoices); */ }
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tNumber of channels: %d\n", libConfig->numChannels); */ }
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tSample rate: %d\n", libConfig->sampleRate); */ }
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tMix buffer size: %d\n", libConfig->mixBufferSize); */ }
if (libConfig->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*)&libConfig->buildTimeStamp)); */ }
#endif
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "\tLibrary Build ID: %s\n", libConfig->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 != libConfig->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 */
#endif

View File

@@ -0,0 +1,36 @@
/*
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef EAS_GLUE_H
#define EAS_GLUE_H
#include "arm-wt-22k/host_src/eas.h"
void EASGlueInit( void );
void EASGlueShutdown( void );
void EASGlueOpenFile( const char * filename );
void EASGluePause();
void EASGlueResume();
void EASGlueCloseFile();
void EASGlueRender( EAS_PCM * outputBuffer, EAS_I32 * generatedSamples );
#endif

View File

@@ -0,0 +1,14 @@
Copyright (c) 2004-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.

View File

@@ -0,0 +1,9 @@
# Copyright 2010 Google Inc. All Rights Reserved.
#Fri Jul 16 10:03:09 PDT 2010
currentVersion=Unknown
version=3.6.10.14?
isNative=true
name=sonivox
keywords=sonivox
onDevice=true
homepage=http\://source.android.com/

View File

@@ -0,0 +1,63 @@
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_fmengine.c \
lib_src/eas_fmsndlib.c \
lib_src/eas_fmsynth.c \
lib_src/eas_fmtables.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_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_wavefile.c \
lib_src/eas_wavefiledata.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
LOCAL_CFLAGS+= -O2 -D NUM_OUTPUT_CHANNELS=2 \
-D _SAMPLE_RATE_22050 -D EAS_FM_SYNTH \
-D MAX_SYNTH_VOICES=16 -D _IMELODY_PARSER \
-D _RTTTL_PARSER -D _OTA_PARSER \
-D _WAVE_PARSER -D _REVERB_ENABLED \
-D _CHORUS_ENABLED -D _IMA_DECODER \
-D UNIFIED_DEBUG_MESSAGES
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
include $(BUILD_SHARED_LIBRARY)

Binary file not shown.

View File

@@ -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_FM_SYNTH -D _IMELODY_PARSER -D _RTTTL_PARSER -D _OTA_PARSER -D _WAVE_PARSER -D _REVERB_ENABLED -D _CHORUS_ENABLED $<
%.o: %.s
$(AS) -o $@ -EL -mcpu=arm946e-s -mfpu=softfpa $<
OBJS = eas_main.o eas_report.o eas_wave.o eas_hostmm.o eas_config.o
arm-fm-22k: $(OBJS)
$(LD) -o $@ $(OBJS) libarm-fm-22k.a -lm

File diff suppressed because it is too large Load Diff

View File

@@ -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_53c2509edf8f42e3975a054126c0cc1b_
#define _GUID_53c2509edf8f42e3975a054126c0cc1b_
#define _BUILD_VERSION_ "53c2509e-df8f-42e3-975a-054126c0cc1b"
#define _BUILD_TIME_ 0x4743b8c9
#endif /* _GUID_53c2509edf8f42e3975a054126c0cc1b_ */

View File

@@ -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

View File

@@ -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];
}

View File

@@ -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 */

View File

@@ -0,0 +1,43 @@
/* Auto-generated from source file: eas_chorusdata.c */
/* Auto-generated from source file: eas_imelodydata.c */
/* 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_voicemgt.c */
/* Auto-generated from source file: eas_ota.c */
/* Auto-generated from source file: eas_mixbuf.c */
/* Auto-generated from source file: eas_fmsndlib.c */
/* Auto-generated from source file: eas_rtttl.c */
/* Auto-generated from source file: eas_reverb.c */
/* Auto-generated from source file: eas_fmsynth.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_fmengine.c */
/* Auto-generated from source file: eas_smfdata.c */
/* Auto-generated from source file: eas_fmtables.c */
/* Auto-generated from source file: eas_imelody.c */
/* Auto-generated from source file: eas_public.c */
/* Auto-generated from source file: eas_rtttldata.c */
/* Auto-generated from source file: eas_reverbdata.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_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_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" },
/* 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" },

View File

@@ -0,0 +1,83 @@
/*----------------------------------------------------------------------------
*
* 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);
/* 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 */

View File

@@ -0,0 +1,660 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_hostmm.c
*
* Contents and purpose:
* This file contains the host wrapper functions for stdio, stdlib, etc.
* This is a sample version that maps the requested files to an
* allocated memory block and uses in-memory pointers to replace
* file system calls. The file locator (EAS_FILE_LOCATOR) handle passed
* HWOpenFile is the same one that is passed to EAS_OpenFile. If your
* system stores data in fixed locations (such as flash) instead of
* using a file system, you can use the locator handle to point to
* your memory. You will need a way of knowing the length of the
* data stored at that location in order to respond correctly in the
* HW_FileLength function.
*
* 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 base memory pointer, the file read pointer, and
* the dup flag, which when sets, indicates that the file handle has
* been duplicated. If your system uses in-memory resources, you
* can eliminate the duplicate handle logic, and simply copy the
* base memory pointer and file read pointer to the duplicate handle.
*
* 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>
#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;
EAS_U8 *buffer;
} EAS_HW_FILE;
typedef struct eas_hw_inst_data_tag
{
EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
} EAS_HW_INST_DATA;
/*----------------------------------------------------------------------------
* EAS_HWInit
*
* Initialize host wrapper interface
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
{
/* 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));
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)
{
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)
{
return memcpy(dest, src, (size_t) amount);
}
/*----------------------------------------------------------------------------
*
* EAS_HWMemSet
*
* Set memory wrapper
*
*----------------------------------------------------------------------------
*/
void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
{
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)
{
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;
FILE *ioFile;
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->buffer == NULL)
{
/* open the file */
if ((ioFile = fopen(locator,"rb")) == NULL)
return EAS_ERROR_FILE_OPEN_FAILED;
/* determine the file size */
if (fseek(ioFile, 0L, SEEK_END) != 0)
return EAS_ERROR_FILE_LENGTH;
if ((file->fileSize = ftell(ioFile)) == -1L)
return EAS_ERROR_FILE_LENGTH;
if (fseek(ioFile, 0L, SEEK_SET) != 0)
return EAS_ERROR_FILE_LENGTH;
/* allocate a buffer */
file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
if (file->buffer == NULL)
{
fclose(ioFile);
return EAS_ERROR_MALLOC_FAILED;
}
/* read the file into memory */
temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
/* close the file - don't need it any more */
fclose(ioFile);
/* check for error reading file */
if (temp != 1)
return EAS_ERROR_FILE_READ_FAILED;
/* 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->buffer == NULL)
return EAS_ERROR_INVALID_HANDLE;
/* calculate the bytes to read */
count = file->fileSize - file->filePos;
if (n < count)
count = n;
/* copy the data to the requested location, and advance the pointer */
if (count)
EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], 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)
{
/* make sure we have a valid handle */
if (file->buffer == NULL)
return EAS_ERROR_INVALID_HANDLE;
/* check for end of file */
if (file->filePos >= file->fileSize)
{
*((EAS_U8*) p) = 0;
return EAS_EOF;
}
/* get a character from the buffer */
*((EAS_U8*) p) = file->buffer[file->filePos++];
return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
*
* EAS_HWGetWord
*
* Returns the current location in the 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->buffer == NULL)
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->buffer == NULL)
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->buffer == NULL)
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->buffer == NULL)
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->buffer == NULL)
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->buffer == NULL)
{
/* copy info from the handle to be duplicated */
dupFile->filePos = file->filePos;
dupFile->fileSize = file->fileSize;
dupFile->buffer = file->buffer;
/* 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->buffer == NULL)
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->buffer == file1->buffer))
{
/* is there more than one duplicate? */
if (dupFile != NULL)
{
/* clear this entry and return */
file1->buffer = NULL;
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->buffer = NULL;
return EAS_SUCCESS;
}
/* no duplicates -free the buffer */
EAS_HWFree(hwInstData, file1->buffer);
/* clear this entry and return */
file1->buffer = NULL;
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;
}

View File

@@ -0,0 +1,461 @@
/*----------------------------------------------------------------------------
*
* 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;
/* 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 */
if ((reportResult = EAS_OpenFile(easData, filename, &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 */

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 */

View File

@@ -0,0 +1,268 @@
/*----------------------------------------------------------------------------
*
* 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 const void *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 */

View File

@@ -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

View File

@@ -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 */

Binary file not shown.

View File

@@ -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=16 -D EAS_FM_SYNTH -D _IMELODY_PARSER -D _RTTTL_PARSER -D _OTA_PARSER -D _WAVE_PARSER -D _REVERB_ENABLED -D _CHORUS_ENABLED -D _IMA_DECODER $<
%.o: %.s
$(AS) -o $@ -EL -mcpu=arm946e-s -mfpu=softfpa $<
OBJS = eas_mididata.o eas_pan.o eas_wavefiledata.o eas_smfdata.o eas_imelody.o eas_math.o eas_fmengine.o eas_chorusdata.o eas_ima_tables.o eas_ota.o eas_rtttldata.o eas_imelodydata.o eas_fmtables.o eas_public.o eas_rtttl.o eas_reverb.o eas_fmsynth.o eas_midi.o eas_otadata.o eas_mixbuf.o eas_fmsndlib.o eas_imaadpcm.o eas_smf.o eas_chorus.o eas_pcm.o eas_mixer.o eas_wavefile.o eas_pcmdata.o eas_data.o eas_reverbdata.o eas_voicemgt.o
arm-fm-22k.a: $(OBJS)
$(AR) rc lib$@ $(OBJS)

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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

View File

@@ -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;

View File

@@ -0,0 +1,131 @@
/*----------------------------------------------------------------------------
*
* 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
#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

View File

@@ -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 */

View File

@@ -0,0 +1,785 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_fmengine.c
*
* Contents and purpose:
* Implements the low-level FM synthesizer functions.
*
* Copyright Sonic Network Inc. 2004, 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) $
*----------------------------------------------------------------------------
*/
/* includes */
#include "eas_types.h"
#include "eas_math.h"
#include "eas_audioconst.h"
#include "eas_fmengine.h"
#if defined(EAS_FM_SYNTH) || defined(EAS_HYBRID_SYNTH) || defined(EAS_SPLIT_HYBRID_SYNTH) || defined(EAS_SPLIT_FM_SYNTH)
#include "eas_data.h"
#endif
/* externals */
extern const EAS_I16 sineTable[];
extern const EAS_U8 fmScaleTable[16];
// saturation constants for 32-bit to 16-bit conversion
#define _EAS_MAX_OUTPUT 32767
#define _EAS_MIN_OUTPUT -32767
static S_FM_ENG_VOICE voices[NUM_FM_VOICES];
/* local prototypes */
void FM_SynthMixVoice (S_FM_ENG_VOICE *p, EAS_U16 gainTarget, EAS_I32 numSamplesToAdd, EAS_PCM *pInputBuffer, EAS_I32 *pBuffer);
/* used in development environment */
#if defined(_SATURATION_MONITOR)
static EAS_BOOL bSaturated = EAS_FALSE;
/*----------------------------------------------------------------------------
* FM_CheckSaturation()
*----------------------------------------------------------------------------
* Purpose:
* Allows the sound development tool to check for saturation at the voice
* level. Useful for tuning the level controls.
*
* Inputs:
*
* Outputs:
* Returns true if saturation has occurred since the last time the function
* was called.
*
* Side Effects:
* Resets the saturation flag
*----------------------------------------------------------------------------
*/
EAS_BOOL FM_CheckSaturation ()
{
EAS_BOOL bTemp;
bTemp = bSaturated;
bSaturated = EAS_FALSE;
return bTemp;
}
#endif
/*----------------------------------------------------------------------------
* FM_Saturate()
*----------------------------------------------------------------------------
* Purpose:
* This inline function saturates a 32-bit number to 16-bits
*
* Inputs:
* psEASData - pointer to overall EAS data structure
*
* Outputs:
* Returns a 16-bit integer
*----------------------------------------------------------------------------
*/
EAS_INLINE EAS_I16 FM_Saturate (EAS_I32 nValue)
{
if (nValue > _EAS_MAX_OUTPUT)
{
#if defined(_SATURATION_MONITOR)
bSaturated = EAS_TRUE;
#endif
return _EAS_MAX_OUTPUT;
}
if (nValue < _EAS_MIN_OUTPUT)
{
#if defined(_SATURATION_MONITOR)
bSaturated = EAS_TRUE;
#endif
return _EAS_MIN_OUTPUT;
}
return (EAS_I16) nValue;
}
/*----------------------------------------------------------------------------
* FM_Noise()
*----------------------------------------------------------------------------
* Purpose:
* A 31-bit low-cost linear congruential PRNG algorithm used to
* generate noise.
*
* Inputs:
* pnSeed - pointer to 32-bit PRNG seed
*
* Outputs:
* Returns a 16-bit integer
*----------------------------------------------------------------------------
*/
EAS_INLINE EAS_I16 FM_Noise (EAS_U32 *pnSeed)
{
*pnSeed = *pnSeed * 214013L + 2531011L;
return (EAS_I16) ((*pnSeed >> 15) & 0xffff);
}
/*----------------------------------------------------------------------------
* FM_PhaseInc()
*----------------------------------------------------------------------------
* Purpose:
* Transform pitch cents to linear phase increment
*
* 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:
*
*----------------------------------------------------------------------------
*/
static EAS_I32 FM_PhaseInc (EAS_I32 nCents)
{
EAS_I32 nDents;
EAS_I32 nExponentInt, nExponentFrac;
EAS_I32 nTemp1, nTemp2;
EAS_I32 nResult;
/* convert cents to dents */
nDents = FMUL_15x15(nCents, CENTS_TO_DENTS);
nExponentInt = GET_DENTS_INT_PART(nDents) + (32 - SINE_TABLE_SIZE_IN_BITS - NUM_EG1_FRAC_BITS);
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;
}
#if (NUM_OUTPUT_CHANNELS == 2)
/*----------------------------------------------------------------------------
* FM_CalculatePan()
*----------------------------------------------------------------------------
* Purpose:
* Assign the left and right gain values corresponding to the given pan value.
*
* Inputs:
* psVoice - ptr to the voice we have assigned for this channel
* psArticulation - ptr to this voice's articulation
* psEASData - pointer to overall EAS data structure
*
* Outputs:
*
* Side Effects:
* the given voice's m_nGainLeft and m_nGainRight are assigned
*----------------------------------------------------------------------------
*/
static void FM_CalculatePan (EAS_I16 pan, EAS_U16 *pGainLeft, EAS_U16 *pGainRight)
{
EAS_I32 nTemp;
EAS_INT nNetAngle;
/*
Implement the following
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
*/
/*
Get the Midi CC10 pan value for this voice's channel
convert the pan value to an "angle" representation suitable for
our sin, cos calculator. This representation is NOT necessarily the same
as the transform in the GM manuals because of our sin, cos calculator.
"angle" = (CC10 - 64)/128
*/
/*lint -e{703} <avoid multiply for performance reasons>*/
nNetAngle = ((EAS_I32) pan) << (NUM_EG1_FRAC_BITS -7);
/* calculate sin */
nTemp = EG1_ONE + FMUL_15x15(COEFF_PAN_G2, nNetAngle);
nTemp = COEFF_PAN_G0 + FMUL_15x15(nTemp, nNetAngle);
if (nTemp > SYNTH_FULL_SCALE_EG1_GAIN)
nTemp = SYNTH_FULL_SCALE_EG1_GAIN;
else if (nTemp < 0)
nTemp = 0;
*pGainRight = (EAS_U16) nTemp;
/* calculate cos */
nTemp = -EG1_ONE + FMUL_15x15(COEFF_PAN_G2, nNetAngle);
nTemp = COEFF_PAN_G0 + FMUL_15x15(nTemp, nNetAngle);
if (nTemp > SYNTH_FULL_SCALE_EG1_GAIN)
nTemp = SYNTH_FULL_SCALE_EG1_GAIN;
else if (nTemp < 0)
nTemp = 0;
*pGainLeft = (EAS_U16) nTemp;
}
#endif /* #if (NUM_OUTPUT_CHANNELS == 2) */
/*----------------------------------------------------------------------------
* FM_Operator()
*----------------------------------------------------------------------------
* Purpose:
* Synthesizes a buffer of samples based on passed parameters.
*
* Inputs:
* nNumSamplesToAdd - number of samples to synthesize
* psEASData - pointer to overall EAS data structure
*
* Outputs:
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
void FM_Operator (
S_FM_ENG_OPER *p,
EAS_I32 numSamplesToAdd,
EAS_PCM *pBuffer,
EAS_PCM *pModBuffer,
EAS_BOOL mix,
EAS_U16 gainTarget,
EAS_I16 pitch,
EAS_U8 feedback,
EAS_I16 *pLastOutput)
{
EAS_I32 gain;
EAS_I32 gainInc;
EAS_U32 phase;
EAS_U32 phaseInc;
EAS_U32 phaseTemp;
EAS_I32 temp;
EAS_I32 temp2;
/* establish local gain variable */
gain = (EAS_I32) p->gain << 16;
/* calculate gain increment */
/*lint -e{703} use shift for performance */
gainInc = ((EAS_I32) gainTarget - (EAS_I32) p->gain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
/* establish local phase variables */
phase = p->phase;
/* calculate the new phase increment */
phaseInc = (EAS_U32) FM_PhaseInc(pitch);
/* restore final output from previous frame for feedback loop */
if (pLastOutput)
temp = *pLastOutput;
else
temp = 0;
/* generate a buffer of samples */
while (numSamplesToAdd--)
{
/* incorporate modulation */
if (pModBuffer)
{
/*lint -e{701} use shift for performance */
temp = *pModBuffer++ << FM_MODULATOR_INPUT_SHIFT;
}
/* incorporate feedback */
else
{
/*lint -e{703} use shift for performance */
temp = (temp * (EAS_I32) feedback) << FM_FEEDBACK_SHIFT;
}
/*lint -e{737} <use this behavior to avoid extra mask step> */
phaseTemp = phase + temp;
/* fetch sample from wavetable */
temp = sineTable[phaseTemp >> (32 - SINE_TABLE_SIZE_IN_BITS)];
/* increment operator phase */
phase += phaseInc;
/* internal gain for modulation effects */
temp = FMUL_15x15(temp, (gain >> 16));
/* output gain calculation */
temp2 = FMUL_15x15(temp, p->outputGain);
/* saturating add to buffer */
if (mix)
{
temp2 += *pBuffer;
*pBuffer++ = FM_Saturate(temp2);
}
/* output to buffer */
else
*pBuffer++ = (EAS_I16) temp2;
/* increment gain */
gain += gainInc;
}
/* save phase and gain */
p->phase = phase;
p->gain = gainTarget;
/* save last output for feedback in next frame */
if (pLastOutput)
*pLastOutput = (EAS_I16) temp;
}
/*----------------------------------------------------------------------------
* FM_NoiseOperator()
*----------------------------------------------------------------------------
* Purpose:
* Synthesizes a buffer of samples based on passed parameters.
*
* Inputs:
* nNumSamplesToAdd - number of samples to synthesize
* psEASData - pointer to overall EAS data structure
*
* Outputs:
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
void FM_NoiseOperator (
S_FM_ENG_OPER *p,
EAS_I32 numSamplesToAdd,
EAS_PCM *pBuffer,
EAS_BOOL mix,
EAS_U16 gainTarget,
EAS_U8 feedback,
EAS_I16 *pLastOutput)
{
EAS_I32 gain;
EAS_I32 gainInc;
EAS_U32 phase;
EAS_I32 temp;
EAS_I32 temp2;
/* establish local gain variable */
gain = (EAS_I32) p->gain << 16;
/* calculate gain increment */
/*lint -e{703} use shift for performance */
gainInc = ((EAS_I32) gainTarget - (EAS_I32) p->gain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
/* establish local phase variables */
phase = p->phase;
/* establish local phase variables */
phase = p->phase;
/* recall last sample for filter Z-1 term */
temp = 0;
if (pLastOutput)
temp = *pLastOutput;
/* generate a buffer of samples */
while (numSamplesToAdd--)
{
/* if using filter */
if (pLastOutput)
{
/* use PRNG for noise */
temp2 = FM_Noise(&phase);
/*lint -e{704} use shift for performance */
temp += ((temp2 -temp) * feedback) >> 8;
}
else
{
temp = FM_Noise(&phase);
}
/* internal gain for modulation effects */
temp2 = FMUL_15x15(temp, (gain >> 16));
/* output gain calculation */
temp2 = FMUL_15x15(temp2, p->outputGain);
/* saturating add to buffer */
if (mix)
{
temp2 += *pBuffer;
*pBuffer++ = FM_Saturate(temp2);
}
/* output to buffer */
else
*pBuffer++ = (EAS_I16) temp2;
/* increment gain */
gain += gainInc;
}
/* save phase and gain */
p->phase = phase;
p->gain = gainTarget;
/* save last output for feedback in next frame */
if (pLastOutput)
*pLastOutput = (EAS_I16) temp;
}
/*----------------------------------------------------------------------------
* FM_ConfigVoice()
*----------------------------------------------------------------------------
* Purpose:
* Receives parameters to start a new voice.
*
* Inputs:
* voiceNum - voice number to start
* vCfg - configuration data
* pMixBuffer - pointer to host supplied buffer
*
* Outputs:
*
* Side Effects:
*
* Notes:
* pFrameBuffer is not used in the test version, but is passed as a
* courtesy to split architecture implementations. It can be used as
* as pointer to the interprocessor communications buffer when the
* synthesis parameters are passed off to a DSP for synthesis.
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pFrameBuffer) pFrameBuffer not used in test version - see above */
void FM_ConfigVoice (EAS_I32 voiceNum, S_FM_VOICE_CONFIG *vCfg, EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
{
S_FM_ENG_VOICE *pVoice;
EAS_INT i;
/* establish pointer to voice data */
pVoice = &voices[voiceNum];
/* save data */
pVoice->feedback = vCfg->feedback;
pVoice->flags = vCfg->flags;
pVoice->voiceGain = vCfg->voiceGain;
/* initialize Z-1 terms */
pVoice->op1Out = 0;
pVoice->op3Out = 0;
/* initialize operators */
for (i = 0; i < 4; i++)
{
/* save operator data */
pVoice->oper[i].gain = vCfg->gain[i];
pVoice->oper[i].outputGain = vCfg->outputGain[i];
pVoice->oper[i].outputGain = vCfg->outputGain[i];
/* initalize operator */
pVoice->oper[i].phase = 0;
}
/* calculate pan */
#if NUM_OUTPUT_CHANNELS == 2
FM_CalculatePan(vCfg->pan, &pVoice->gainLeft, &pVoice->gainRight);
#endif
}
/*----------------------------------------------------------------------------
* FM_ProcessVoice()
*----------------------------------------------------------------------------
* Purpose:
* Synthesizes a buffer of samples based on calculated parameters.
*
* Inputs:
* nNumSamplesToAdd - number of samples to synthesize
* psEASData - pointer to overall EAS data structure
*
* Outputs:
*
* Side Effects:
*
* Notes:
* pOut is not used in the test version, but is passed as a
* courtesy to split architecture implementations. It can be used as
* as pointer to the interprocessor communications buffer when the
* synthesis parameters are passed off to a DSP for synthesis.
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pOut) pOut not used in test version - see above */
void FM_ProcessVoice (
EAS_I32 voiceNum,
S_FM_VOICE_FRAME *pFrame,
EAS_I32 numSamplesToAdd,
EAS_PCM *pTempBuffer,
EAS_PCM *pBuffer,
EAS_I32 *pMixBuffer,
EAS_FRAME_BUFFER_HANDLE pFrameBuffer)
{
S_FM_ENG_VOICE *p;
EAS_PCM *pOutBuf;
EAS_PCM *pMod;
EAS_BOOL mix;
EAS_U8 feedback1;
EAS_U8 feedback3;
EAS_U8 mode;
/* establish pointer to voice data */
p = &voices[voiceNum];
mode = p->flags & 0x07;
/* lookup feedback values */
feedback1 = fmScaleTable[p->feedback >> 4];
feedback3 = fmScaleTable[p->feedback & 0x0f];
/* operator 3 is on output bus in modes 0, 1, and 3 */
if ((mode == 0) || (mode == 1) || (mode == 3))
pOutBuf = pBuffer;
else
pOutBuf = pTempBuffer;
if (p->flags & FLAG_FM_ENG_VOICE_OP3_NOISE)
{
FM_NoiseOperator(
p->oper + 2,
numSamplesToAdd,
pOutBuf,
EAS_FALSE,
pFrame->gain[2],
feedback3,
&p->op3Out);
}
else
{
FM_Operator(
p->oper + 2,
numSamplesToAdd,
pOutBuf,
0,
EAS_FALSE,
pFrame->gain[2],
pFrame->pitch[2],
feedback3,
&p->op3Out);
}
/* operator 4 is on output bus in modes 0, 1, and 2 */
if (mode < 3)
pOutBuf = pBuffer;
else
pOutBuf = pTempBuffer;
/* operator 4 is modulated in modes 2, 4, and 5 */
if ((mode == 2) || (mode == 4) || (mode == 5))
pMod = pTempBuffer;
else
pMod = 0;
/* operator 4 is in mix mode in modes 0 and 1 */
mix = (mode < 2);
if (p->flags & FLAG_FM_ENG_VOICE_OP4_NOISE)
{
FM_NoiseOperator(
p->oper + 3,
numSamplesToAdd,
pOutBuf,
mix,
pFrame->gain[3],
0,
0);
}
else
{
FM_Operator(
p->oper + 3,
numSamplesToAdd,
pOutBuf,
pMod,
mix,
pFrame->gain[3],
pFrame->pitch[3],
0,
0);
}
/* operator 1 is on output bus in mode 0 */
if (mode == 0)
pOutBuf = pBuffer;
else
pOutBuf = pTempBuffer;
/* operator 1 is modulated in modes 3 and 4 */
if ((mode == 3) || (mode == 4))
pMod = pTempBuffer;
else
pMod = 0;
/* operator 1 is in mix mode in modes 0 and 5 */
mix = ((mode == 0) || (mode == 5));
if (p->flags & FLAG_FM_ENG_VOICE_OP1_NOISE)
{
FM_NoiseOperator(
p->oper,
numSamplesToAdd,
pOutBuf,
mix,
pFrame->gain[0],
feedback1,
&p->op1Out);
}
else
{
FM_Operator(
p->oper,
numSamplesToAdd,
pOutBuf,
pMod,
mix,
pFrame->gain[0],
pFrame->pitch[0],
feedback1,
&p->op1Out);
}
/* operator 2 is modulated in all modes except 0 */
if (mode != 0)
pMod = pTempBuffer;
else
pMod = 0;
/* operator 1 is in mix mode in modes 0 -3 */
mix = (mode < 4);
if (p->flags & FLAG_FM_ENG_VOICE_OP2_NOISE)
{
FM_NoiseOperator(
p->oper + 1,
numSamplesToAdd,
pBuffer,
mix,
pFrame->gain[1],
0,
0);
}
else
{
FM_Operator(
p->oper + 1,
numSamplesToAdd,
pBuffer,
pMod,
mix,
pFrame->gain[1],
pFrame->pitch[1],
0,
0);
}
/* mix voice output to synthesizer output buffer */
FM_SynthMixVoice(p, pFrame->voiceGain, numSamplesToAdd, pBuffer, pMixBuffer);
}
/*----------------------------------------------------------------------------
* FM_SynthMixVoice()
*----------------------------------------------------------------------------
* Purpose:
* Mixes the voice output buffer into the final mix using an anti-zipper
* filter.
*
* Inputs:
* nNumSamplesToAdd - number of samples to synthesize
* psEASData - pointer to overall EAS data structure
*
* Outputs:
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
void FM_SynthMixVoice(S_FM_ENG_VOICE *p, EAS_U16 nGainTarget, EAS_I32 numSamplesToAdd, EAS_PCM *pInputBuffer, EAS_I32 *pBuffer)
{
EAS_I32 nGain;
EAS_I32 nGainInc;
EAS_I32 nTemp;
/* restore previous gain */
/*lint -e{703} <use shift for performance> */
nGain = (EAS_I32) p->voiceGain << 16;
/* calculate gain increment */
/*lint -e{703} <use shift for performance> */
nGainInc = ((EAS_I32) nGainTarget - (EAS_I32) p->voiceGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
/* mix the output buffer */
while (numSamplesToAdd--)
{
/* output gain calculation */
nTemp = *pInputBuffer++;
/* sum to output buffer */
#if (NUM_OUTPUT_CHANNELS == 2)
/*lint -e{704} <use shift for performance> */
nTemp = ((EAS_I32) nTemp * (nGain >> 16)) >> FM_GAIN_SHIFT;
/*lint -e{704} <use shift for performance> */
{
EAS_I32 nTemp2;
nTemp = nTemp >> FM_STEREO_PRE_GAIN_SHIFT;
nTemp2 = (nTemp * p->gainLeft) >> FM_STEREO_POST_GAIN_SHIFT;
*pBuffer++ += nTemp2;
nTemp2 = (nTemp * p->gainRight) >> FM_STEREO_POST_GAIN_SHIFT;
*pBuffer++ += nTemp2;
}
#else
/*lint -e{704} <use shift for performance> */
nTemp = ((EAS_I32) nTemp * (nGain >> 16)) >> FM_MONO_GAIN_SHIFT;
*pBuffer++ += nTemp;
#endif
/* increment gain for anti-zipper filter */
nGain += nGainInc;
}
/* save gain */
p->voiceGain = nGainTarget;
}

View File

@@ -0,0 +1,121 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_fmengine.h
*
* Contents and purpose:
* Declarations, interfaces, and prototypes for FM synthesize low-level.
*
* 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: 664 $
* $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
*----------------------------------------------------------------------------
*/
/* sentinel */
#ifndef _FMENGINE_H
#define _FMENGINE_H
/* check for split architecture */
#if defined (EAS_SPLIT_HYBRID_SYNTH) || defined(EAS_SPLIT_FM_SYNTH)
#define FM_OFFBOARD
#endif
/* output level to mix buffer (3 = -24dB) */
#define FM_GAIN_SHIFT 3
#define FM_MONO_GAIN_SHIFT 9
/* voice output level for stereo 15 = +6dB */
#define FM_STEREO_PRE_GAIN_SHIFT 11
#define FM_STEREO_POST_GAIN_SHIFT 10
/* modulator input level shift (21 = -30dB) */
#define FM_MODULATOR_INPUT_SHIFT 21
/* feedback control level shift (7 = 0dB) */
#define FM_FEEDBACK_SHIFT 7
/* synth final output level */
#define SYNTH_POST_GAIN_SHIFT 14
/* LFO modulation to gain control */
#define FM_LFO_GAIN_SHIFT 12
/* sine table is always a power of 2 - saves cycles in inner loop */
#define SINE_TABLE_SIZE_IN_BITS 11
#define SINE_TABLE_SIZE 2048
/* operator structure for FM engine */
typedef struct
{
EAS_U32 phase; /* current waveform phase */
EAS_U16 gain; /* current internal gain */
EAS_U16 outputGain; /* current output gain */
} S_FM_ENG_OPER;
typedef struct
{
S_FM_ENG_OPER oper[4]; /* operator data */
EAS_I16 op1Out; /* op1 output for feedback loop */
EAS_I16 op3Out; /* op3 output for feedback loop */
EAS_U16 voiceGain; /* LFO + channel parameters */
#if (NUM_OUTPUT_CHANNELS == 2)
EAS_U16 gainLeft; /* left gain multiplier */
EAS_U16 gainRight; /* right gain multiplier */
#endif
EAS_U8 flags; /* mode bits and noise waveform flags */
EAS_U8 feedback; /* feedback for Op1 and Op3 */
} S_FM_ENG_VOICE;
typedef struct
{
EAS_U16 gain[4]; /* initial operator gain value */
EAS_U16 outputGain[4]; /* initial operator output gain value */
EAS_U16 voiceGain; /* initial voice gain */
EAS_U8 flags; /* mode bits and noise waveform flags */
EAS_U8 feedback; /* feedback for Op1 and Op3 */
#if (NUM_OUTPUT_CHANNELS == 2)
EAS_I8 pan; /* pan value +/-64 */
#endif
} S_FM_VOICE_CONFIG;
typedef struct
{
EAS_U16 gain[4]; /* new operator gain value */
EAS_I16 pitch[4]; /* new pitch value */
EAS_U16 voiceGain; /* new voice gain */
} S_FM_VOICE_FRAME;
/* bit definitions for S_FM_ENG_VOICE.flags */
#define FLAG_FM_ENG_VOICE_OP1_NOISE 0x10 /* operator 1 source is PRNG */
#define FLAG_FM_ENG_VOICE_OP2_NOISE 0x20 /* operator 2 source is PRNG */
#define FLAG_FM_ENG_VOICE_OP3_NOISE 0x40 /* operator 3 source is PRNG */
#define FLAG_FM_ENG_VOICE_OP4_NOISE 0x80 /* operator 4 source is PRNG */
#ifdef FM_OFFBOARD
extern EAS_BOOL FM_StartFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
extern EAS_BOOL FM_EndFrame (EAS_FRAME_BUFFER_HANDLE pFrameBuffe, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
#endif
/* FM engine prototypes */
extern void FM_ConfigVoice (EAS_I32 voiceNum, S_FM_VOICE_CONFIG *vCfg, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
extern void FM_ProcessVoice (EAS_I32 voiceNum, S_FM_VOICE_FRAME *pFrame, EAS_I32 numSamplesToAdd, EAS_PCM *pTempBuffer, EAS_PCM *pBuffer, EAS_I32 *pMixBuffer, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
#endif
/* #ifndef _FMENGINE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,910 @@
/*----------------------------------------------------------------------------
*
* File:
* fmsynth.c
*
* Contents and purpose:
* Implements the high-level FM synthesizer functions.
*
* 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: 795 $
* $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
*----------------------------------------------------------------------------
*/
// includes
#include "eas_host.h"
#include "eas_report.h"
#include "eas_data.h"
#include "eas_synth_protos.h"
#include "eas_audioconst.h"
#include "eas_fmengine.h"
#include "eas_math.h"
/* option sanity check */
#ifdef _REVERB
#error "No reverb for FM synthesizer"
#endif
#ifdef _CHORUS
#error "No chorus for FM synthesizer"
#endif
/*
* WARNING: These macros can cause unwanted side effects. Use them
* with care. For example, min(x++,y++) will cause either x or y to be
* incremented twice.
*/
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
/* pivot point for keyboard scalars */
#define EG_SCALE_PIVOT_POINT 64
#define KEY_SCALE_PIVOT_POINT 36
/* This number is the negative of the frequency of the note (in cents) of
* the sine wave played at unity. The number can be calculated as follows:
*
* MAGIC_NUMBER = 1200 * log(base2) (SINE_TABLE_SIZE * 8.175798916 / SAMPLE_RATE)
*
* 8.17578 is a reference to the frequency of MIDI note 0
*/
#if defined (_SAMPLE_RATE_8000)
#define MAGIC_NUMBER 1279
#elif defined (_SAMPLE_RATE_16000)
#define MAGIC_NUMBER 79
#elif defined (_SAMPLE_RATE_20000)
#define MAGIC_NUMBER -308
#elif defined (_SAMPLE_RATE_22050)
#define MAGIC_NUMBER -477
#elif defined (_SAMPLE_RATE_24000)
#define MAGIC_NUMBER -623
#elif defined (_SAMPLE_RATE_32000)
#define MAGIC_NUMBER -1121
#elif defined (_SAMPLE_RATE_44100)
#define MAGIC_NUMBER -1677
#elif defined (_SAMPLE_RATE_48000)
#define MAGIC_NUMBER -1823
#endif
/* externs */
extern const EAS_I16 fmControlTable[128];
extern const EAS_U16 fmRateTable[256];
extern const EAS_U16 fmAttackTable[16];
extern const EAS_U8 fmDecayTable[16];
extern const EAS_U8 fmReleaseTable[16];
extern const EAS_U8 fmScaleTable[16];
/* local prototypes */
/*lint -esym(715, pVoiceMgr) standard synthesizer interface - pVoiceMgr not used */
static EAS_RESULT FM_Initialize (S_VOICE_MGR *pVoiceMgr) { return EAS_SUCCESS; }
static EAS_RESULT FM_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
static EAS_BOOL FM_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
static void FM_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
static void FM_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
static void FM_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
static void FM_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
/*----------------------------------------------------------------------------
* Synthesizer interface
*----------------------------------------------------------------------------
*/
const S_SYNTH_INTERFACE fmSynth =
{
FM_Initialize,
FM_StartVoice,
FM_UpdateVoice,
FM_ReleaseVoice,
FM_MuteVoice,
FM_SustainPedal,
FM_UpdateChannel
};
#ifdef FM_OFFBOARD
const S_FRAME_INTERFACE fmFrameInterface =
{
FM_StartFrame,
FM_EndFrame
};
#endif
/*----------------------------------------------------------------------------
* inline functions
*----------------------------------------------------------------------------
*/
EAS_INLINE S_FM_VOICE *GetFMVoicePtr (S_VOICE_MGR *pVoiceMgr, EAS_INT voiceNum)
{
return &pVoiceMgr->fmVoices[voiceNum];
}
EAS_INLINE S_SYNTH_CHANNEL *GetChannelPtr (S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
{
return &pSynth->channels[pVoice->channel & 15];
}
EAS_INLINE const S_FM_REGION *GetFMRegionPtr (S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice)
{
#ifdef _SECONDARY_SYNTH
return &pSynth->pEAS->pFMRegions[pVoice->regionIndex & REGION_INDEX_MASK];
#else
return &pSynth->pEAS->pFMRegions[pVoice->regionIndex];
#endif
}
/*----------------------------------------------------------------------------
* FM_SynthIsOutputOperator
*----------------------------------------------------------------------------
* Purpose:
* Returns true if the operator is a direct output and not muted
*
* Inputs:
*
* Outputs:
* Returns boolean
*----------------------------------------------------------------------------
*/
static EAS_BOOL FM_SynthIsOutputOperator (const S_FM_REGION *pRegion, EAS_INT operIndex)
{
/* see if voice is muted */
if ((pRegion->oper[operIndex].gain & 0xfc) == 0)
return 0;
/* check based on mode */
switch (pRegion->region.keyGroupAndFlags & 7)
{
/* mode 0 - all operators are external */
case 0:
return EAS_TRUE;
/* mode 1 - operators 1-3 are external */
case 1:
if (operIndex != 0)
return EAS_TRUE;
break;
/* mode 2 - operators 1 & 3 are external */
case 2:
if ((operIndex == 1) || (operIndex == 3))
return EAS_TRUE;
break;
/* mode 2 - operators 1 & 2 are external */
case 3:
if ((operIndex == 1) || (operIndex == 2))
return EAS_TRUE;
break;
/* modes 4 & 5 - operator 1 is external */
case 4:
case 5:
if (operIndex == 1)
return EAS_TRUE;
break;
default:
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL,"Invalid voice mode: %d",
pRegion->region.keyGroupAndFlags & 7); */ }
}
return EAS_FALSE;
}
/*----------------------------------------------------------------------------
* FM_CalcEGRate()
*----------------------------------------------------------------------------
* Purpose:
*
* Inputs:
* nKeyNumber - MIDI note
* nLogRate - logarithmic scale rate from patch data
* nKeyScale - key scaling factor for this EG
*
* Outputs:
* 16-bit linear multiplier
*----------------------------------------------------------------------------
*/
static EAS_U16 FM_CalcEGRate (EAS_U8 nKeyNumber, EAS_U8 nLogRate, EAS_U8 nEGScale)
{
EAS_I32 temp;
/* incorporate key scaling on release rate */
temp = (EAS_I32) nLogRate << 7;
temp += ((EAS_I32) nKeyNumber - EG_SCALE_PIVOT_POINT) * (EAS_I32) nEGScale;
/* saturate */
temp = max(temp, 0);
temp = min(temp, 32767);
/* look up in rate table */
/*lint -e{704} use shift for performance */
return fmRateTable[temp >> 8];
}
/*----------------------------------------------------------------------------
* FM_ReleaseVoice()
*----------------------------------------------------------------------------
* Purpose:
* The selected voice is being released.
*
* Inputs:
* psEASData - pointer to S_EAS_DATA
* pVoice - pointer to voice to release
*
* Outputs:
* None
*----------------------------------------------------------------------------
*/
static void FM_ReleaseVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
{
EAS_INT operIndex;
const S_FM_REGION *pRegion;
S_FM_VOICE *pFMVoice;
/* check to see if voice responds to NOTE-OFF's */
pRegion = GetFMRegionPtr(pSynth, pVoice);
if (pRegion->region.keyGroupAndFlags & REGION_FLAG_ONE_SHOT)
return;
/* set all envelopes to release state */
pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
for (operIndex = 0; operIndex < 4; operIndex++)
{
pFMVoice->oper[operIndex].envState = eFMEnvelopeStateRelease;
/* incorporate key scaling on release rate */
pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
pVoice->note,
fmReleaseTable[pRegion->oper[operIndex].velocityRelease & 0x0f],
fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
} /* end for (operIndex = 0; operIndex < 4; operIndex++) */
}
/*----------------------------------------------------------------------------
* FM_MuteVoice()
*----------------------------------------------------------------------------
* Purpose:
* The selected voice is being muted.
*
* Inputs:
* pVoice - pointer to voice to release
*
* Outputs:
* None
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pSynth) standard interface, pVoiceMgr not used */
static void FM_MuteVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum)
{
S_FM_VOICE *pFMVoice;
/* clear deferred action flags */
pVoice->voiceFlags &=
~(VOICE_FLAG_DEFER_MIDI_NOTE_OFF |
VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF |
VOICE_FLAG_DEFER_MUTE);
/* set all envelopes to muted state */
pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
pFMVoice->oper[0].envState = eFMEnvelopeStateMuted;
pFMVoice->oper[1].envState = eFMEnvelopeStateMuted;
pFMVoice->oper[2].envState = eFMEnvelopeStateMuted;
pFMVoice->oper[3].envState = eFMEnvelopeStateMuted;
}
/*----------------------------------------------------------------------------
* FM_SustainPedal()
*----------------------------------------------------------------------------
* Purpose:
* The selected voice is held due to sustain pedal
*
* Inputs:
* pVoice - pointer to voice to sustain
*
* Outputs:
* None
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pChannel) standard interface, pVoiceMgr not used */
static void FM_SustainPedal (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum)
{
const S_FM_REGION *pRegion;
S_FM_VOICE *pFMVoice;
EAS_INT operIndex;
pRegion = GetFMRegionPtr(pSynth, pVoice);
pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
/* check to see if any envelopes are above the sustain level */
for (operIndex = 0; operIndex < 4; operIndex++)
{
/* if level control or envelope gain is zero, skip this envelope */
if (((pRegion->oper[operIndex].gain & 0xfc) == 0) ||
(pFMVoice->oper[operIndex].envGain == 0))
{
continue;
}
/* if the envelope gain is above the sustain level, we need to catch this voice */
if (pFMVoice->oper[operIndex].envGain >= ((EAS_U16) (pRegion->oper[operIndex].sustain & 0xfc) << 7))
{
/* reset envelope to decay state */
pFMVoice->oper[operIndex].envState = eFMEnvelopeStateDecay;
pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
pVoice->note,
fmDecayTable[pRegion->oper[operIndex].attackDecay & 0x0f],
fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
/* set voice to decay state */
pVoice->voiceState = eVoiceStatePlay;
/* set sustain flag */
pVoice->voiceFlags |= VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF;
}
} /* end for (operIndex = 0; operIndex < 4; operIndex++) */
}
/*----------------------------------------------------------------------------
* FM_StartVoice()
*----------------------------------------------------------------------------
* Purpose:
* Assign the region for the given instrument using the midi key number
* and the RPN2 (coarse tuning) value. By using RPN2 as part of the
* region selection process, we reduce the amount a given sample has
* to be transposed by selecting the closest recorded root instead.
*
* This routine is the second half of SynthAssignRegion().
* If the region was successfully found by SynthFindRegionIndex(),
* then assign the region's parameters to the voice.
*
* Setup and initialize the following voice parameters:
* m_nRegionIndex
*
* Inputs:
* pVoice - ptr to the voice we have assigned for this channel
* nRegionIndex - index of the region
* psEASData - pointer to overall EAS data structure
*
* Outputs:
* success - could find and assign the region for this voice's note otherwise
* failure - could not find nor assign the region for this voice's note
*
* Side Effects:
* psSynthObject->m_sVoice[].m_nRegionIndex is assigned
* psSynthObject->m_sVoice[] parameters are assigned
*----------------------------------------------------------------------------
*/
static EAS_RESULT FM_StartVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex)
{
S_FM_VOICE *pFMVoice;
S_SYNTH_CHANNEL *pChannel;
const S_FM_REGION *pRegion;
EAS_I32 temp;
EAS_INT operIndex;
/* establish pointers to data */
pVoice->regionIndex = regionIndex;
pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
pChannel = GetChannelPtr(pSynth, pVoice);
pRegion = GetFMRegionPtr(pSynth, pVoice);
/* update static channel parameters */
if (pChannel->channelFlags & CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS)
FM_UpdateChannel(pVoiceMgr, pSynth, pVoice->channel & 15);
/* init the LFO */
pFMVoice->lfoValue = 0;
pFMVoice->lfoPhase = 0;
pFMVoice->lfoDelay = (EAS_U16) (fmScaleTable[pRegion->lfoFreqDelay & 0x0f] >> 1);
#if (NUM_OUTPUT_CHANNELS == 2)
/* calculate pan gain values only if stereo output */
/* set up panning only at note start */
temp = (EAS_I32) pChannel->pan - 64;
temp += (EAS_I32) pRegion->pan;
if (temp < -64)
temp = -64;
if (temp > 64)
temp = 64;
pFMVoice->pan = (EAS_I8) temp;
#endif /* #if (NUM_OUTPUT_CHANNELS == 2) */
/* no samples have been synthesized for this note yet */
pVoice->voiceFlags = VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
/* initialize gain value for anti-zipper filter */
pFMVoice->voiceGain = (EAS_I16) EAS_LogToLinear16(pChannel->staticGain);
pFMVoice->voiceGain = (EAS_I16) FMUL_15x15(pFMVoice->voiceGain, pSynth->masterVolume);
/* initialize the operators */
for (operIndex = 0; operIndex < 4; operIndex++)
{
/* establish operator output gain level */
/*lint -e{701} <use shift for performance> */
pFMVoice->oper[operIndex].outputGain = EAS_LogToLinear16(((EAS_I16) (pRegion->oper[operIndex].gain & 0xfc) - 0xfc) << 7);
/* check for linear velocity flag */
/*lint -e{703} <use shift for performance> */
if (pRegion->oper[operIndex].flags & FM_OPER_FLAG_LINEAR_VELOCITY)
temp = (EAS_I32) (pVoice->velocity - 127) << 5;
else
temp = (EAS_I32) fmControlTable[pVoice->velocity];
/* scale velocity */
/*lint -e{704} use shift for performance */
temp = (temp * (EAS_I32)(pRegion->oper[operIndex].velocityRelease & 0xf0)) >> 7;
/* include key scalar */
temp -= ((EAS_I32) pVoice->note - KEY_SCALE_PIVOT_POINT) * (EAS_I32) fmScaleTable[pRegion->oper[operIndex].egKeyScale & 0x0f];
/* saturate */
temp = min(temp, 0);
temp = max(temp, -32768);
/* save static gain parameters */
pFMVoice->oper[operIndex].baseGain = (EAS_I16) EAS_LogToLinear16(temp);
/* incorporate key scaling on decay rate */
pFMVoice->oper[operIndex].envRate = FM_CalcEGRate(
pVoice->note,
fmDecayTable[pRegion->oper[operIndex].attackDecay & 0x0f],
fmScaleTable[pRegion->oper[operIndex].egKeyScale >> 4]);
/* if zero attack time, max out envelope and jump to decay state */
if ((pRegion->oper[operIndex].attackDecay & 0xf0) == 0xf0)
{
/* start out envelope at max */
pFMVoice->oper[operIndex].envGain = 0x7fff;
/* set envelope to decay state */
pFMVoice->oper[operIndex].envState = eFMEnvelopeStateDecay;
}
/* start envelope at zero and start in attack state */
else
{
pFMVoice->oper[operIndex].envGain = 0;
pFMVoice->oper[operIndex].envState = eFMEnvelopeStateAttack;
}
}
return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* FM_UpdateChannel()
*----------------------------------------------------------------------------
* Purpose:
* Calculate and assign static channel parameters
* These values only need to be updated if one of the controller values
* for this channel changes.
* Called when CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS flag is set.
*
* Inputs:
* nChannel - channel to update
* psEASData - pointer to overall EAS data structure
*
* Outputs:
*
* Side Effects:
* - the given channel's static gain and static pitch are updated
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pVoiceMgr) standard interface, pVoiceMgr not used */
static void FM_UpdateChannel (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel)
{
S_SYNTH_CHANNEL *pChannel;
EAS_I32 temp;
pChannel = &pSynth->channels[channel];
/* convert CC7 volume controller to log scale */
temp = fmControlTable[pChannel->volume];
/* incorporate CC11 expression controller */
temp += fmControlTable[pChannel->expression];
/* saturate */
pChannel->staticGain = (EAS_I16) max(temp,-32768);
/* calculate pitch bend */
/*lint -e{703} <avoid multiply for performance>*/
temp = (((EAS_I32)(pChannel->pitchBend) << 2) - 32768);
temp = FMUL_15x15(temp, pChannel->pitchBendSensitivity);
/* include "magic number" compensation for sample rate and lookup table size */
temp += MAGIC_NUMBER;
/* if this is not a drum channel, then add in the per-channel tuning */
if (!(pChannel->channelFlags & CHANNEL_FLAG_RHYTHM_CHANNEL))
temp += (pChannel->finePitch + (pChannel->coarsePitch * 100));
/* save static pitch */
pChannel->staticPitch = temp;
/* Calculate LFO modulation depth */
/* mod wheel to LFO depth */
temp = FMUL_15x15(DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS,
pChannel->modWheel << (NUM_EG1_FRAC_BITS -7));
/* channel pressure to LFO depth */
pChannel->lfoAmt = (EAS_I16) (temp +
FMUL_15x15(DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS,
pChannel->channelPressure << (NUM_EG1_FRAC_BITS -7)));
/* clear update flag */
pChannel->channelFlags &= ~CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS;
return;
}
/*----------------------------------------------------------------------------
* FM_UpdateLFO()
*----------------------------------------------------------------------------
* Purpose:
* Calculate the LFO for the given voice
*
* Inputs:
* pVoice - ptr to the voice whose LFO we want to update
* psEASData - pointer to overall EAS data structure - used for debug only
*
* Outputs:
*
* Side Effects:
* - updates LFO values for the given voice
*----------------------------------------------------------------------------
*/
static void FM_UpdateLFO (S_FM_VOICE *pFMVoice, const S_FM_REGION *pRegion)
{
/* increment the LFO phase if the delay time has elapsed */
if (!pFMVoice->lfoDelay)
{
/*lint -e{701} <use shift for performance> */
pFMVoice->lfoPhase = pFMVoice->lfoPhase + (EAS_U16) (-fmControlTable[((15 - (pRegion->lfoFreqDelay >> 4)) << 3) + 4]);
/* square wave LFO? */
if (pRegion->region.keyGroupAndFlags & REGION_FLAG_SQUARE_WAVE)
pFMVoice->lfoValue = (EAS_I16)(pFMVoice->lfoPhase & 0x8000 ? -32767 : 32767);
/* trick to get a triangle wave out of a sawtooth */
else
{
pFMVoice->lfoValue = (EAS_I16) (pFMVoice->lfoPhase << 1);
/*lint -e{502} <shortcut to turn sawtooth into sine wave> */
if ((pFMVoice->lfoPhase > 0x3fff) && (pFMVoice->lfoPhase < 0xC000))
pFMVoice->lfoValue = ~pFMVoice->lfoValue;
}
}
/* still in delay */
else
pFMVoice->lfoDelay--;
return;
}
/*----------------------------------------------------------------------------
* FM_UpdateEG()
*----------------------------------------------------------------------------
* Purpose:
* Calculate the synthesis parameters for an operator to be used during
* the next buffer
*
* Inputs:
* pVoice - pointer to the voice being updated
* psEASData - pointer to overall EAS data structure
*
* Outputs:
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
static EAS_BOOL FM_UpdateEG (S_SYNTH_VOICE *pVoice, S_OPERATOR *pOper, const S_FM_OPER *pOperData, EAS_BOOL oneShot)
{
EAS_U32 temp;
EAS_BOOL done;
/* set flag assuming the envelope is not done */
done = EAS_FALSE;
/* take appropriate action based on state */
switch (pOper->envState)
{
case eFMEnvelopeStateAttack:
/* the envelope is linear during the attack, so add the value */
temp = pOper->envGain + fmAttackTable[pOperData->attackDecay >> 4];
/* check for end of attack */
if (temp >= 0x7fff)
{
pOper->envGain = 0x7fff;
pOper->envState = eFMEnvelopeStateDecay;
}
else
pOper->envGain = (EAS_U16) temp;
break;
case eFMEnvelopeStateDecay:
/* decay is exponential, multiply by decay rate */
pOper->envGain = (EAS_U16) FMUL_15x15(pOper->envGain, pOper->envRate);
/* check for sustain level reached */
temp = (EAS_U32) (pOperData->sustain & 0xfc) << 7;
if (pOper->envGain <= (EAS_U16) temp)
{
/* if this is a one-shot patch, go directly to release phase */
if (oneShot)
{
pOper->envRate = FM_CalcEGRate(
pVoice->note,
fmReleaseTable[pOperData->velocityRelease & 0x0f],
fmScaleTable[pOperData->egKeyScale >> 4]);
pOper->envState = eFMEnvelopeStateRelease;
}
/* normal sustaining type */
else
{
pOper->envGain = (EAS_U16) temp;
pOper->envState = eFMEnvelopeStateSustain;
}
}
break;
case eFMEnvelopeStateSustain:
pOper->envGain = (EAS_U16)((EAS_U16)(pOperData->sustain & 0xfc) << 7);
break;
case eFMEnvelopeStateRelease:
/* release is exponential, multiply by release rate */
pOper->envGain = (EAS_U16) FMUL_15x15(pOper->envGain, pOper->envRate);
/* fully released */
if (pOper->envGain == 0)
{
pOper->envGain = 0;
pOper->envState = eFMEnvelopeStateMuted;
done = EAS_TRUE;
}
break;
case eFMEnvelopeStateMuted:
pOper->envGain = 0;
done = EAS_TRUE;
break;
default:
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_FATAL,"Invalid operator state: %d", pOper->envState); */ }
} /* end switch (pOper->m_eState) */
return done;
}
/*----------------------------------------------------------------------------
* FM_UpdateDynamic()
*----------------------------------------------------------------------------
* Purpose:
* Calculate the synthesis parameters for this voice that will be used to
* synthesize the next buffer
*
* Inputs:
* pVoice - pointer to the voice being updated
* psEASData - pointer to overall EAS data structure
*
* Outputs:
* Returns EAS_TRUE if voice will be fully ramped to zero at the end of
* the next synthesized buffer.
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
static EAS_BOOL FM_UpdateDynamic (S_SYNTH_VOICE *pVoice, S_FM_VOICE *pFMVoice, const S_FM_REGION *pRegion, S_SYNTH_CHANNEL *pChannel)
{
EAS_I32 temp;
EAS_I32 pitch;
EAS_I32 lfoPitch;
EAS_INT operIndex;
EAS_BOOL done;
/* increment LFO phase */
FM_UpdateLFO(pFMVoice, pRegion);
/* base pitch in cents */
pitch = pVoice->note * 100;
/* LFO amount includes LFO depth from programming + channel dynamics */
temp = (fmScaleTable[pRegion->vibTrem >> 4] >> 1) + pChannel->lfoAmt;
/* multiply by LFO output to get final pitch modulation */
lfoPitch = FMUL_15x15(pFMVoice->lfoValue, temp);
/* flag to indicate this voice is done */
done = EAS_TRUE;
/* iterate through operators to establish parameters */
for (operIndex = 0; operIndex < 4; operIndex++)
{
EAS_BOOL bTemp;
/* set base phase increment for each operator */
temp = pRegion->oper[operIndex].tuning +
pChannel->staticPitch;
/* add vibrato effect unless it is disabled for this operator */
if ((pRegion->oper[operIndex].flags & FM_OPER_FLAG_NO_VIBRATO) == 0)
temp += lfoPitch;
/* if note is monotonic, bias to MIDI note 60 */
if (pRegion->oper[operIndex].flags & FM_OPER_FLAG_MONOTONE)
temp += 6000;
else
temp += pitch;
pFMVoice->oper[operIndex].pitch = (EAS_I16) temp;
/* calculate envelope, returns true if done */
bTemp = FM_UpdateEG(pVoice, &pFMVoice->oper[operIndex], &pRegion->oper[operIndex], pRegion->region.keyGroupAndFlags & REGION_FLAG_ONE_SHOT);
/* check if all output envelopes have completed */
if (FM_SynthIsOutputOperator(pRegion, operIndex))
done = done && bTemp;
}
return done;
}
/*----------------------------------------------------------------------------
* FM_UpdateVoice()
*----------------------------------------------------------------------------
* Purpose:
* Synthesize a block of samples for the given voice.
*
* Inputs:
* psEASData - pointer to overall EAS data structure
*
* Outputs:
* number of samples actually written to buffer
*
* Side Effects:
* - samples are added to the presently free buffer
*
*----------------------------------------------------------------------------
*/
static EAS_BOOL FM_UpdateVoice (S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples)
{
S_SYNTH_CHANNEL *pChannel;
const S_FM_REGION *pRegion;
S_FM_VOICE *pFMVoice;
S_FM_VOICE_CONFIG vCfg;
S_FM_VOICE_FRAME vFrame;
EAS_I32 temp;
EAS_INT oper;
EAS_U16 voiceGainTarget;
EAS_BOOL done;
/* setup some pointers */
pChannel = GetChannelPtr(pSynth, pVoice);
pRegion = GetFMRegionPtr(pSynth, pVoice);
pFMVoice = GetFMVoicePtr(pVoiceMgr, voiceNum);
/* if the voice is just starting, get the voice configuration data */
if (pVoice->voiceFlags & VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET)
{
/* split architecture may limit the number of voice starts */
#ifdef MAX_VOICE_STARTS
if (pVoiceMgr->numVoiceStarts == MAX_VOICE_STARTS)
return EAS_FALSE;
pVoiceMgr->numVoiceStarts++;
#endif
/* get initial parameters */
vCfg.feedback = pRegion->feedback;
vCfg.voiceGain = (EAS_U16) pFMVoice->voiceGain;
#if (NUM_OUTPUT_CHANNELS == 2)
vCfg.pan = pFMVoice->pan;
#endif
/* get voice mode */
vCfg.flags = pRegion->region.keyGroupAndFlags & 7;
/* get operator parameters */
for (oper = 0; oper < 4; oper++)
{
/* calculate initial gain */
vCfg.gain[oper] = (EAS_U16) FMUL_15x15(pFMVoice->oper[oper].baseGain, pFMVoice->oper[oper].envGain);
vCfg.outputGain[oper] = pFMVoice->oper[oper].outputGain;
/* copy noise waveform flag */
if (pRegion->oper[oper].flags & FM_OPER_FLAG_NOISE)
vCfg.flags |= (EAS_U8) (FLAG_FM_ENG_VOICE_OP1_NOISE << oper);
}
#ifdef FM_OFFBOARD
FM_ConfigVoice(voiceNum, &vCfg, pVoiceMgr->pFrameBuffer);
#else
FM_ConfigVoice(voiceNum, &vCfg, NULL);
#endif
/* clear startup flag */
pVoice->voiceFlags &= ~VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET;
}
/* calculate new synthesis parameters */
done = FM_UpdateDynamic(pVoice, pFMVoice, pRegion, pChannel);
/* calculate LFO gain modulation */
/*lint -e{702} <use shift for performance> */
temp = ((fmScaleTable[pRegion->vibTrem & 0x0f] >> 1) * pFMVoice->lfoValue) >> FM_LFO_GAIN_SHIFT;
/* include channel gain */
temp += pChannel->staticGain;
/* -32768 or lower is infinite attenuation */
if (temp < -32767)
voiceGainTarget = 0;
/* translate to linear gain multiplier */
else
voiceGainTarget = EAS_LogToLinear16(temp);
/* include synth master volume */
voiceGainTarget = (EAS_U16) FMUL_15x15(voiceGainTarget, pSynth->masterVolume);
/* save target values for this frame */
vFrame.voiceGain = voiceGainTarget;
/* assume voice output is zero */
pVoice->gain = 0;
/* save operator targets for this frame */
for (oper = 0; oper < 4; oper++)
{
vFrame.gain[oper] = (EAS_U16) FMUL_15x15(pFMVoice->oper[oper].baseGain, pFMVoice->oper[oper].envGain);
vFrame.pitch[oper] = pFMVoice->oper[oper].pitch;
/* use the highest output envelope level as the gain for the voice stealing algorithm */
if (FM_SynthIsOutputOperator(pRegion, oper))
pVoice->gain = max(pVoice->gain, (EAS_I16) vFrame.gain[oper]);
}
/* consider voice gain multiplier in calculating gain for stealing algorithm */
pVoice->gain = (EAS_I16) FMUL_15x15(voiceGainTarget, pVoice->gain);
/* synthesize samples */
#ifdef FM_OFFBOARD
FM_ProcessVoice(voiceNum, &vFrame, numSamples, pVoiceMgr->operMixBuffer, pVoiceMgr->voiceBuffer, pMixBuffer, pVoiceMgr->pFrameBuffer);
#else
FM_ProcessVoice(voiceNum, &vFrame, numSamples, pVoiceMgr->operMixBuffer, pVoiceMgr->voiceBuffer, pMixBuffer, NULL);
#endif
return done;
}

View File

@@ -0,0 +1,81 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_fmsynth.h
*
* Contents and purpose:
* Implements the FM synthesizer functions.
*
* 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: 90 $
* $Date: 2006-07-11 20:18:13 -0700 (Tue, 11 Jul 2006) $
*----------------------------------------------------------------------------
*/
#ifndef fmsynthH
#define fmsynthH
#include "eas_data.h"
#if defined (_FM_SYNTH)
/* FM envelope state */
typedef enum {
eFMEnvelopeStateAttack = 0,
eFMEnvelopeStateDecay,
eFMEnvelopeStateSustain,
eFMEnvelopeStateRelease,
eFMEnvelopeStateMuted,
eFMEnvelopeStateInvalid /* should never be in this state! */
} E_FM_ENVELOPE_STATE;
/*------------------------------------
* S_OPERATOR data structure
*------------------------------------
*/
typedef struct s_operator_tag
{
EAS_I16 pitch; /* operator pitch in cents */
EAS_U16 envGain; /* envelope target */
EAS_I16 baseGain; /* patch gain (inc. vel & key scale) */
EAS_U16 outputGain; /* current output gain */
EAS_U16 envRate; /* calculated envelope rate */
EAS_U8 envState; /* envelope state */
EAS_U8 pad; /* pad to 16-bits */
} S_OPERATOR;
#endif
typedef struct s_fm_voice_tag
{
S_OPERATOR oper[4]; /* operator data */
EAS_I16 voiceGain; /* LFO + channel parameters */
EAS_U16 lfoPhase; /* LFO current phase */
EAS_I16 lfoValue; /* LFO current value */
EAS_U16 lfoDelay; /* keeps track of elapsed delay time */
EAS_I8 pan; /* stereo pan value (-64 to +64) */
EAS_I8 pad; /* reserved to maintain alignment */
} S_FM_VOICE;
#ifdef _FM_EDITOR
extern S_FM_REGION newPatch;
extern S_FM_REGION OriginalPatch;
#endif
extern EAS_U32 freqTable[];
#endif

View File

@@ -0,0 +1,368 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_fmtables.c
*
* Contents and purpose:
* Contains lookup tables for the FM synthesizer
*
*
* 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"
/* this table is needed by the DSP and the main processor */
const EAS_U8 fmScaleTable[16] =
{
0,8,16,24,32,40,48,56,64,72,80,96,128,160,192,255
};
/* these tables are needed on the main processor */
#ifndef _DSP_CODE
const EAS_I16 fmControlTable[128] =
{
-32768,-14313,-12265,-11067,-10217,-9558,-9019,-8563,
-8169,-7821,-7510,-7228,-6971,-6734,-6515,-6312,
-6121,-5942,-5773,-5613,-5462,-5317,-5180,-5049,
-4923,-4802,-4686,-4575,-4467,-4364,-4264,-4167,
-4073,-3982,-3894,-3808,-3725,-3644,-3565,-3488,
-3414,-3341,-3269,-3200,-3132,-3066,-3001,-2937,
-2875,-2814,-2754,-2696,-2638,-2582,-2527,-2473,
-2419,-2367,-2316,-2265,-2216,-2167,-2119,-2071,
-2025,-1979,-1934,-1889,-1846,-1803,-1760,-1718,
-1677,-1636,-1596,-1556,-1517,-1478,-1440,-1403,
-1366,-1329,-1293,-1257,-1221,-1186,-1152,-1118,
-1084,-1051,-1018,-985,-953,-921,-889,-858,
-827,-796,-766,-736,-706,-677,-648,-619,
-590,-562,-534,-506,-479,-452,-425,-398,
-371,-345,-319,-293,-268,-242,-217,-192,
-168,-143,-119,-95,-71,-47,-23,0
};
const EAS_U16 fmRateTable[128] =
{
32767,32764,32758,32747,32731,32712,32688,32659,
32627,32590,32548,32503,32453,32398,32340,32277,
32211,32140,32065,31985,31902,31815,31724,31628,
31529,31426,31319,31208,31094,30976,30854,30728,
30599,30466,30330,30191,30048,29902,29752,29599,
29443,29285,29123,28958,28790,28619,28445,28269,
28090,27909,27725,27538,27349,27158,26964,26769,
26571,26371,26169,25965,25760,25552,25343,25132,
24920,24706,24490,24274,24056,23836,23616,23394,
23172,22948,22724,22499,22273,22046,21819,21591,
21363,21135,20906,20676,20447,20217,19987,19758,
19528,19298,19069,18840,18610,18382,18153,17926,
17698,17471,17245,17020,16795,16571,16347,16125,
15903,15683,15463,15245,15027,14811,14596,14382,
14169,13957,13747,13538,13331,13125,12920,12717,
12516,12316,12117,11921,11725,11532,11340,0
};
const EAS_U16 fmAttackTable[15] =
{
27,54,109,327,655,1310,2730,4095,
4681,5461,6553,8191,10922,16383,32767
};
const EAS_U8 fmDecayTable[16] =
{
4,7,10,15,20,25,30,35,40,50,60,70,80,90,100,127
};
const EAS_U8 fmReleaseTable[16] =
{
10,15,20,25,30,35,40,45,50,60,70,80,90,100,113,127
};
#endif
/* this table is needed only on the DSP */
#if defined(_DSP_CODE) || !defined(_SPLIT_ARCHITECTURE)
//---------------------------------------------------------------------
// sineTable
//
// Contains sine lookup table
//---------------------------------------------------------------------
const EAS_I16 sineTable[2048] =
{
0,101,201,302,402,503,603,704,
804,905,1005,1106,1206,1307,1407,1507,
1608,1708,1809,1909,2009,2110,2210,2310,
2410,2511,2611,2711,2811,2911,3012,3112,
3212,3312,3412,3512,3612,3712,3811,3911,
4011,4111,4210,4310,4410,4509,4609,4708,
4808,4907,5007,5106,5205,5305,5404,5503,
5602,5701,5800,5899,5998,6096,6195,6294,
6393,6491,6590,6688,6786,6885,6983,7081,
7179,7277,7375,7473,7571,7669,7767,7864,
7962,8059,8157,8254,8351,8448,8545,8642,
8739,8836,8933,9030,9126,9223,9319,9416,
9512,9608,9704,9800,9896,9992,10087,10183,
10278,10374,10469,10564,10659,10754,10849,10944,
11039,11133,11228,11322,11417,11511,11605,11699,
11793,11886,11980,12074,12167,12260,12353,12446,
12539,12632,12725,12817,12910,13002,13094,13187,
13279,13370,13462,13554,13645,13736,13828,13919,
14010,14101,14191,14282,14372,14462,14553,14643,
14732,14822,14912,15001,15090,15180,15269,15358,
15446,15535,15623,15712,15800,15888,15976,16063,
16151,16238,16325,16413,16499,16586,16673,16759,
16846,16932,17018,17104,17189,17275,17360,17445,
17530,17615,17700,17784,17869,17953,18037,18121,
18204,18288,18371,18454,18537,18620,18703,18785,
18868,18950,19032,19113,19195,19276,19357,19438,
19519,19600,19680,19761,19841,19921,20000,20080,
20159,20238,20317,20396,20475,20553,20631,20709,
20787,20865,20942,21019,21096,21173,21250,21326,
21403,21479,21554,21630,21705,21781,21856,21930,
22005,22079,22154,22227,22301,22375,22448,22521,
22594,22667,22739,22812,22884,22956,23027,23099,
23170,23241,23311,23382,23452,23522,23592,23662,
23731,23801,23870,23938,24007,24075,24143,24211,
24279,24346,24413,24480,24547,24613,24680,24746,
24811,24877,24942,25007,25072,25137,25201,25265,
25329,25393,25456,25519,25582,25645,25708,25770,
25832,25893,25955,26016,26077,26138,26198,26259,
26319,26378,26438,26497,26556,26615,26674,26732,
26790,26848,26905,26962,27019,27076,27133,27189,
27245,27300,27356,27411,27466,27521,27575,27629,
27683,27737,27790,27843,27896,27949,28001,28053,
28105,28157,28208,28259,28310,28360,28411,28460,
28510,28560,28609,28658,28706,28755,28803,28850,
28898,28945,28992,29039,29085,29131,29177,29223,
29268,29313,29358,29403,29447,29491,29534,29578,
29621,29664,29706,29749,29791,29832,29874,29915,
29956,29997,30037,30077,30117,30156,30195,30234,
30273,30311,30349,30387,30424,30462,30498,30535,
30571,30607,30643,30679,30714,30749,30783,30818,
30852,30885,30919,30952,30985,31017,31050,31082,
31113,31145,31176,31206,31237,31267,31297,31327,
31356,31385,31414,31442,31470,31498,31526,31553,
31580,31607,31633,31659,31685,31710,31736,31760,
31785,31809,31833,31857,31880,31903,31926,31949,
31971,31993,32014,32036,32057,32077,32098,32118,
32137,32157,32176,32195,32213,32232,32250,32267,
32285,32302,32318,32335,32351,32367,32382,32397,
32412,32427,32441,32455,32469,32482,32495,32508,
32521,32533,32545,32556,32567,32578,32589,32599,
32609,32619,32628,32637,32646,32655,32663,32671,
32678,32685,32692,32699,32705,32711,32717,32722,
32728,32732,32737,32741,32745,32748,32752,32755,
32757,32759,32761,32763,32765,32766,32766,32767,
32767,32767,32766,32766,32765,32763,32761,32759,
32757,32755,32752,32748,32745,32741,32737,32732,
32728,32722,32717,32711,32705,32699,32692,32685,
32678,32671,32663,32655,32646,32637,32628,32619,
32609,32599,32589,32578,32567,32556,32545,32533,
32521,32508,32495,32482,32469,32455,32441,32427,
32412,32397,32382,32367,32351,32335,32318,32302,
32285,32267,32250,32232,32213,32195,32176,32157,
32137,32118,32098,32077,32057,32036,32014,31993,
31971,31949,31926,31903,31880,31857,31833,31809,
31785,31760,31736,31710,31685,31659,31633,31607,
31580,31553,31526,31498,31470,31442,31414,31385,
31356,31327,31297,31267,31237,31206,31176,31145,
31113,31082,31050,31017,30985,30952,30919,30885,
30852,30818,30783,30749,30714,30679,30643,30607,
30571,30535,30498,30462,30424,30387,30349,30311,
30273,30234,30195,30156,30117,30077,30037,29997,
29956,29915,29874,29832,29791,29749,29706,29664,
29621,29578,29534,29491,29447,29403,29358,29313,
29268,29223,29177,29131,29085,29039,28992,28945,
28898,28850,28803,28755,28706,28658,28609,28560,
28510,28460,28411,28360,28310,28259,28208,28157,
28105,28053,28001,27949,27896,27843,27790,27737,
27683,27629,27575,27521,27466,27411,27356,27300,
27245,27189,27133,27076,27019,26962,26905,26848,
26790,26732,26674,26615,26556,26497,26438,26378,
26319,26259,26198,26138,26077,26016,25955,25893,
25832,25770,25708,25645,25582,25519,25456,25393,
25329,25265,25201,25137,25072,25007,24942,24877,
24811,24746,24680,24613,24547,24480,24413,24346,
24279,24211,24143,24075,24007,23938,23870,23801,
23731,23662,23592,23522,23452,23382,23311,23241,
23170,23099,23027,22956,22884,22812,22739,22667,
22594,22521,22448,22375,22301,22227,22154,22079,
22005,21930,21856,21781,21705,21630,21554,21479,
21403,21326,21250,21173,21096,21019,20942,20865,
20787,20709,20631,20553,20475,20396,20317,20238,
20159,20080,20000,19921,19841,19761,19680,19600,
19519,19438,19357,19276,19195,19113,19032,18950,
18868,18785,18703,18620,18537,18454,18371,18288,
18204,18121,18037,17953,17869,17784,17700,17615,
17530,17445,17360,17275,17189,17104,17018,16932,
16846,16759,16673,16586,16499,16413,16325,16238,
16151,16063,15976,15888,15800,15712,15623,15535,
15446,15358,15269,15180,15090,15001,14912,14822,
14732,14643,14553,14462,14372,14282,14191,14101,
14010,13919,13828,13736,13645,13554,13462,13370,
13279,13187,13094,13002,12910,12817,12725,12632,
12539,12446,12353,12260,12167,12074,11980,11886,
11793,11699,11605,11511,11417,11322,11228,11133,
11039,10944,10849,10754,10659,10564,10469,10374,
10278,10183,10087,9992,9896,9800,9704,9608,
9512,9416,9319,9223,9126,9030,8933,8836,
8739,8642,8545,8448,8351,8254,8157,8059,
7962,7864,7767,7669,7571,7473,7375,7277,
7179,7081,6983,6885,6786,6688,6590,6491,
6393,6294,6195,6096,5998,5899,5800,5701,
5602,5503,5404,5305,5205,5106,5007,4907,
4808,4708,4609,4509,4410,4310,4210,4111,
4011,3911,3811,3712,3612,3512,3412,3312,
3212,3112,3012,2911,2811,2711,2611,2511,
2410,2310,2210,2110,2009,1909,1809,1708,
1608,1507,1407,1307,1206,1106,1005,905,
804,704,603,503,402,302,201,101,
0,-101,-201,-302,-402,-503,-603,-704,
-804,-905,-1005,-1106,-1206,-1307,-1407,-1507,
-1608,-1708,-1809,-1909,-2009,-2110,-2210,-2310,
-2410,-2511,-2611,-2711,-2811,-2911,-3012,-3112,
-3212,-3312,-3412,-3512,-3612,-3712,-3811,-3911,
-4011,-4111,-4210,-4310,-4410,-4509,-4609,-4708,
-4808,-4907,-5007,-5106,-5205,-5305,-5404,-5503,
-5602,-5701,-5800,-5899,-5998,-6096,-6195,-6294,
-6393,-6491,-6590,-6688,-6786,-6885,-6983,-7081,
-7179,-7277,-7375,-7473,-7571,-7669,-7767,-7864,
-7962,-8059,-8157,-8254,-8351,-8448,-8545,-8642,
-8739,-8836,-8933,-9030,-9126,-9223,-9319,-9416,
-9512,-9608,-9704,-9800,-9896,-9992,-10087,-10183,
-10278,-10374,-10469,-10564,-10659,-10754,-10849,-10944,
-11039,-11133,-11228,-11322,-11417,-11511,-11605,-11699,
-11793,-11886,-11980,-12074,-12167,-12260,-12353,-12446,
-12539,-12632,-12725,-12817,-12910,-13002,-13094,-13187,
-13279,-13370,-13462,-13554,-13645,-13736,-13828,-13919,
-14010,-14101,-14191,-14282,-14372,-14462,-14553,-14643,
-14732,-14822,-14912,-15001,-15090,-15180,-15269,-15358,
-15446,-15535,-15623,-15712,-15800,-15888,-15976,-16063,
-16151,-16238,-16325,-16413,-16499,-16586,-16673,-16759,
-16846,-16932,-17018,-17104,-17189,-17275,-17360,-17445,
-17530,-17615,-17700,-17784,-17869,-17953,-18037,-18121,
-18204,-18288,-18371,-18454,-18537,-18620,-18703,-18785,
-18868,-18950,-19032,-19113,-19195,-19276,-19357,-19438,
-19519,-19600,-19680,-19761,-19841,-19921,-20000,-20080,
-20159,-20238,-20317,-20396,-20475,-20553,-20631,-20709,
-20787,-20865,-20942,-21019,-21096,-21173,-21250,-21326,
-21403,-21479,-21554,-21630,-21705,-21781,-21856,-21930,
-22005,-22079,-22154,-22227,-22301,-22375,-22448,-22521,
-22594,-22667,-22739,-22812,-22884,-22956,-23027,-23099,
-23170,-23241,-23311,-23382,-23452,-23522,-23592,-23662,
-23731,-23801,-23870,-23938,-24007,-24075,-24143,-24211,
-24279,-24346,-24413,-24480,-24547,-24613,-24680,-24746,
-24811,-24877,-24942,-25007,-25072,-25137,-25201,-25265,
-25329,-25393,-25456,-25519,-25582,-25645,-25708,-25770,
-25832,-25893,-25955,-26016,-26077,-26138,-26198,-26259,
-26319,-26378,-26438,-26497,-26556,-26615,-26674,-26732,
-26790,-26848,-26905,-26962,-27019,-27076,-27133,-27189,
-27245,-27300,-27356,-27411,-27466,-27521,-27575,-27629,
-27683,-27737,-27790,-27843,-27896,-27949,-28001,-28053,
-28105,-28157,-28208,-28259,-28310,-28360,-28411,-28460,
-28510,-28560,-28609,-28658,-28706,-28755,-28803,-28850,
-28898,-28945,-28992,-29039,-29085,-29131,-29177,-29223,
-29268,-29313,-29358,-29403,-29447,-29491,-29534,-29578,
-29621,-29664,-29706,-29749,-29791,-29832,-29874,-29915,
-29956,-29997,-30037,-30077,-30117,-30156,-30195,-30234,
-30273,-30311,-30349,-30387,-30424,-30462,-30498,-30535,
-30571,-30607,-30643,-30679,-30714,-30749,-30783,-30818,
-30852,-30885,-30919,-30952,-30985,-31017,-31050,-31082,
-31113,-31145,-31176,-31206,-31237,-31267,-31297,-31327,
-31356,-31385,-31414,-31442,-31470,-31498,-31526,-31553,
-31580,-31607,-31633,-31659,-31685,-31710,-31736,-31760,
-31785,-31809,-31833,-31857,-31880,-31903,-31926,-31949,
-31971,-31993,-32014,-32036,-32057,-32077,-32098,-32118,
-32137,-32157,-32176,-32195,-32213,-32232,-32250,-32267,
-32285,-32302,-32318,-32335,-32351,-32367,-32382,-32397,
-32412,-32427,-32441,-32455,-32469,-32482,-32495,-32508,
-32521,-32533,-32545,-32556,-32567,-32578,-32589,-32599,
-32609,-32619,-32628,-32637,-32646,-32655,-32663,-32671,
-32678,-32685,-32692,-32699,-32705,-32711,-32717,-32722,
-32728,-32732,-32737,-32741,-32745,-32748,-32752,-32755,
-32757,-32759,-32761,-32763,-32765,-32766,-32766,-32767,
-32767,-32767,-32766,-32766,-32765,-32763,-32761,-32759,
-32757,-32755,-32752,-32748,-32745,-32741,-32737,-32732,
-32728,-32722,-32717,-32711,-32705,-32699,-32692,-32685,
-32678,-32671,-32663,-32655,-32646,-32637,-32628,-32619,
-32609,-32599,-32589,-32578,-32567,-32556,-32545,-32533,
-32521,-32508,-32495,-32482,-32469,-32455,-32441,-32427,
-32412,-32397,-32382,-32367,-32351,-32335,-32318,-32302,
-32285,-32267,-32250,-32232,-32213,-32195,-32176,-32157,
-32137,-32118,-32098,-32077,-32057,-32036,-32014,-31993,
-31971,-31949,-31926,-31903,-31880,-31857,-31833,-31809,
-31785,-31760,-31736,-31710,-31685,-31659,-31633,-31607,
-31580,-31553,-31526,-31498,-31470,-31442,-31414,-31385,
-31356,-31327,-31297,-31267,-31237,-31206,-31176,-31145,
-31113,-31082,-31050,-31017,-30985,-30952,-30919,-30885,
-30852,-30818,-30783,-30749,-30714,-30679,-30643,-30607,
-30571,-30535,-30498,-30462,-30424,-30387,-30349,-30311,
-30273,-30234,-30195,-30156,-30117,-30077,-30037,-29997,
-29956,-29915,-29874,-29832,-29791,-29749,-29706,-29664,
-29621,-29578,-29534,-29491,-29447,-29403,-29358,-29313,
-29268,-29223,-29177,-29131,-29085,-29039,-28992,-28945,
-28898,-28850,-28803,-28755,-28706,-28658,-28609,-28560,
-28510,-28460,-28411,-28360,-28310,-28259,-28208,-28157,
-28105,-28053,-28001,-27949,-27896,-27843,-27790,-27737,
-27683,-27629,-27575,-27521,-27466,-27411,-27356,-27300,
-27245,-27189,-27133,-27076,-27019,-26962,-26905,-26848,
-26790,-26732,-26674,-26615,-26556,-26497,-26438,-26378,
-26319,-26259,-26198,-26138,-26077,-26016,-25955,-25893,
-25832,-25770,-25708,-25645,-25582,-25519,-25456,-25393,
-25329,-25265,-25201,-25137,-25072,-25007,-24942,-24877,
-24811,-24746,-24680,-24613,-24547,-24480,-24413,-24346,
-24279,-24211,-24143,-24075,-24007,-23938,-23870,-23801,
-23731,-23662,-23592,-23522,-23452,-23382,-23311,-23241,
-23170,-23099,-23027,-22956,-22884,-22812,-22739,-22667,
-22594,-22521,-22448,-22375,-22301,-22227,-22154,-22079,
-22005,-21930,-21856,-21781,-21705,-21630,-21554,-21479,
-21403,-21326,-21250,-21173,-21096,-21019,-20942,-20865,
-20787,-20709,-20631,-20553,-20475,-20396,-20317,-20238,
-20159,-20080,-20000,-19921,-19841,-19761,-19680,-19600,
-19519,-19438,-19357,-19276,-19195,-19113,-19032,-18950,
-18868,-18785,-18703,-18620,-18537,-18454,-18371,-18288,
-18204,-18121,-18037,-17953,-17869,-17784,-17700,-17615,
-17530,-17445,-17360,-17275,-17189,-17104,-17018,-16932,
-16846,-16759,-16673,-16586,-16499,-16413,-16325,-16238,
-16151,-16063,-15976,-15888,-15800,-15712,-15623,-15535,
-15446,-15358,-15269,-15180,-15090,-15001,-14912,-14822,
-14732,-14643,-14553,-14462,-14372,-14282,-14191,-14101,
-14010,-13919,-13828,-13736,-13645,-13554,-13462,-13370,
-13279,-13187,-13094,-13002,-12910,-12817,-12725,-12632,
-12539,-12446,-12353,-12260,-12167,-12074,-11980,-11886,
-11793,-11699,-11605,-11511,-11417,-11322,-11228,-11133,
-11039,-10944,-10849,-10754,-10659,-10564,-10469,-10374,
-10278,-10183,-10087,-9992,-9896,-9800,-9704,-9608,
-9512,-9416,-9319,-9223,-9126,-9030,-8933,-8836,
-8739,-8642,-8545,-8448,-8351,-8254,-8157,-8059,
-7962,-7864,-7767,-7669,-7571,-7473,-7375,-7277,
-7179,-7081,-6983,-6885,-6786,-6688,-6590,-6491,
-6393,-6294,-6195,-6096,-5998,-5899,-5800,-5701,
-5602,-5503,-5404,-5305,-5205,-5106,-5007,-4907,
-4808,-4708,-4609,-4509,-4410,-4310,-4210,-4111,
-4011,-3911,-3811,-3712,-3612,-3512,-3412,-3312,
-3212,-3112,-3012,-2911,-2811,-2711,-2611,-2511,
-2410,-2310,-2210,-2110,-2009,-1909,-1809,-1708,
-1608,-1507,-1407,-1307,-1206,-1106,-1005,-905,
-804,-704,-603,-503,-402,-302,-201,-101
};
#endif

View File

@@ -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
};

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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];

View File

@@ -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

View File

@@ -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 */

File diff suppressed because it is too large Load Diff

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,359 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_pcm.h
*
* Contents and purpose:
* External function prototypes for eas_pcm.c module
*
*
* 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) $
*----------------------------------------------------------------------------
*/
#ifndef _EAS_PCM_H
#define _EAS_PCM_H
/* default gain setting - roughly unity gain */
#define PCM_DEFAULT_GAIN_SETTING 0x6000
typedef struct s_pcm_state_tag *EAS_PCM_HANDLE;
typedef void (*EAS_PCM_CALLBACK) (EAS_DATA_HANDLE pEASData, EAS_VOID_PTR cbInstData, EAS_PCM_HANDLE pcmHandle, EAS_STATE state);
/* parameters for EAS_PEOpenStream */
typedef struct s_pcm_open_params_tag
{
EAS_FILE_HANDLE fileHandle;
EAS_I32 decoder;
EAS_U32 sampleRate;
EAS_I32 size;
EAS_U32 loopStart;
EAS_U32 loopSamples;
EAS_I32 blockSize;
EAS_U32 flags;
EAS_U32 envData;
EAS_I16 volume;
EAS_PCM_CALLBACK pCallbackFunc;
EAS_VOID_PTR cbInstData;
} S_PCM_OPEN_PARAMS;
/*----------------------------------------------------------------------------
* EAS_PEInit()
*----------------------------------------------------------------------------
* Purpose:
* Initializes the PCM engine
*
* Inputs:
*
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PEInit (EAS_DATA_HANDLE pEASData);
/*----------------------------------------------------------------------------
* EAS_PEShutdown()
*----------------------------------------------------------------------------
* Purpose:
* Shuts down the PCM engine
*
* Inputs:
*
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PEShutdown (EAS_DATA_HANDLE pEASData);
/*----------------------------------------------------------------------------
* EAS_PEOpenStream()
*----------------------------------------------------------------------------
* Purpose:
* Starts up a PCM playback
*
* Inputs:
*
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PEOpenStream (EAS_DATA_HANDLE pEASData, S_PCM_OPEN_PARAMS *pParams, EAS_PCM_HANDLE *pHandle);
/*----------------------------------------------------------------------------
* EAS_PEContinueStream()
*----------------------------------------------------------------------------
* Purpose:
* Continues a PCM stream
*
* Inputs:
*
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PEContinueStream (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_I32 size);
/*----------------------------------------------------------------------------
* EAS_PEGetFileHandle()
*----------------------------------------------------------------------------
* Purpose:
* Returns the file handle of a stream
*
* Inputs:
*
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PEGetFileHandle (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_FILE_HANDLE *pFileHandle);
/*----------------------------------------------------------------------------
* EAS_PERender()
*----------------------------------------------------------------------------
* Purpose:
* Render a buffer of PCM audio
*
* Inputs:
*
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PERender (EAS_DATA_HANDLE pEASData, EAS_I32 numSamples);
/*----------------------------------------------------------------------------
* EAS_PEUpdateParams()
*----------------------------------------------------------------------------
* Purpose:
* Update the pitch and volume parameters using MIDI controls
*
* Inputs:
*
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PEUpdateParams (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch, EAS_I16 gainLeft, EAS_I16 gainRight);
/*----------------------------------------------------------------------------
* 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 (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I32 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 (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 volume);
/*----------------------------------------------------------------------------
* 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 (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE pState, EAS_I16 pitch);
/*----------------------------------------------------------------------------
* 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.
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PEState (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle, EAS_STATE *pState);
/*----------------------------------------------------------------------------
* 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 (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
/*----------------------------------------------------------------------------
* EAS_PEReset()
*----------------------------------------------------------------------------
* 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 (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
/*----------------------------------------------------------------------------
* EAS_PEPause()
*----------------------------------------------------------------------------
* Purpose:
* Mute and pause 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:
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PEPause (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
/*----------------------------------------------------------------------------
* 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:
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PEResume (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
/*----------------------------------------------------------------------------
* 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:
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PERelease (EAS_DATA_HANDLE pEASData, EAS_PCM_HANDLE handle);
#endif /* end _EAS_PCM_H */

View File

@@ -0,0 +1,35 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_pcmdata.c
*
* Contents and purpose:
* Contains the static data for the PCM engine.
*
* 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_data.h"
/* static data allocation */
S_PCM_STATE eas_PCMData[MAX_PCM_STREAMS];

View File

@@ -0,0 +1,157 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_pcmdata.h
*
* Contents and purpose:
* Data declarations for the PCM engine
*
*
* 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) $
*----------------------------------------------------------------------------
*/
#ifndef _EAS_PCMDATA_H
#define _EAS_PCMDATA_H
/* sets the maximum number of simultaneous PCM streams */
#ifndef MAX_PCM_STREAMS
#define MAX_PCM_STREAMS 16
#define PCM_STREAM_THRESHOLD (MAX_PCM_STREAMS - 4)
#endif
/* coefficents for high-pass filter in ADPCM */
#define INTEGRATOR_COEFFICIENT 100 /* coefficient for leaky integrator */
/* additional flags in S_PCM_STATE.flags used internal to module */
#define PCM_FLAGS_EMPTY 0x01000000 /* unsigned format */
/*----------------------------------------------------------------------------
* S_PCM_STATE
*
* Retains state information for PCM streams.
*----------------------------------------------------------------------------
*/
typedef struct s_decoder_state_tag
{
EAS_I32 output; /* last output for DC offset filter */
EAS_I32 acc; /* accumulator for DC offset filter */
EAS_I32 step; /* current ADPCM step size */
EAS_PCM x1; /* current generated sample */
EAS_PCM x0; /* previous generated sample */
} S_DECODER_STATE;
typedef enum
{
PCM_ENV_START = 0,
PCM_ENV_ATTACK,
PCM_ENV_DECAY,
PCM_ENV_SUSTAIN,
PCM_ENV_RELEASE,
PCM_ENV_END
} E_PCM_ENV_STATE;
typedef struct s_pcm_state_tag
{
#ifdef _CHECKED_BUILD
EAS_U32 handleCheck; /* signature check for checked build */
#endif
EAS_FILE_HANDLE fileHandle; /* pointer to input file */
EAS_PCM_CALLBACK pCallback; /* pointer to callback function */
EAS_VOID_PTR cbInstData; /* instance data for callback function */
struct s_decoder_interface_tag EAS_CONST * pDecoder; /* pointer to decoder interface */
EAS_STATE state; /* stream state */
EAS_I32 time; /* media time */
EAS_I32 startPos; /* start of PCM stream */
EAS_I32 loopLocation; /* file location where loop starts */
EAS_I32 byteCount; /* size of file */
EAS_U32 loopStart; /* loop start, offset in samples from startPos */
/* NOTE: For CMF, we use this to store total sample size */
EAS_U32 loopSamples; /* total loop length, in samples, 0 means no loop */
/* NOTE: For CMF, non-zero means looped */
EAS_U32 samplesInLoop; /* samples left in the loop to play back */
EAS_I32 samplesTilLoop; /* samples left to play until top of loop */
EAS_I32 bytesLeft; /* count of bytes left in stream */
EAS_I32 bytesLeftLoop; /* count of bytes left in stream, value at start of loop */
EAS_U32 phase; /* current phase for interpolator */
EAS_U32 basefreq; /* frequency multiplier */
EAS_U32 flags; /* stream flags */
EAS_U32 envData; /* envelope data (and LFO data) */
EAS_U32 envValue; /* current envelope value */
EAS_U32 envScale; /* current envelope scale */
EAS_U32 startOrder; /* start order index, first is 0, next is 1, etc. */
S_DECODER_STATE decoderL; /* left (mono) ADPCM state */
S_DECODER_STATE decoderR; /* right ADPCM state */
S_DECODER_STATE decoderLLoop; /* left (mono) ADPCM state, value at start of loop */
S_DECODER_STATE decoderRLoop; /* right ADPCM state, value at start of loop */
E_PCM_ENV_STATE envState; /* current envelope state */
EAS_I16 volume; /* volume for stream */
EAS_I16 pitch; /* relative pitch in cents - zero is unity playback */
EAS_I16 gainLeft; /* requested gain */
EAS_I16 gainRight; /* requested gain */
EAS_I16 currentGainLeft; /* current gain for anti-zipper filter */
EAS_I16 currentGainRight; /* current gain for anti-zipper filter */
EAS_U16 blockSize; /* block size for ADPCM decoder */
EAS_U16 blockCount; /* block counter for ADPCM decoder */
EAS_U16 sampleRate; /* input sample rate */
EAS_U8 srcByte; /* source byte */
EAS_U8 msBitCount; /* count keeps track of MS bits */
EAS_U8 msBitMask; /* mask keeps track of MS bits */
EAS_U8 msBitValue; /* value keeps track of MS bits */
EAS_U8 msBitCountLoop; /* count keeps track of MS bits, value at loop start */
EAS_U8 msBitMaskLoop; /* mask keeps track of MS bits, value at loop start */
EAS_U8 msBitValueLoop; /* value keeps track of MS bits, value at loop start */
EAS_BOOL8 hiNibble; /* indicates high/low nibble is next */
EAS_BOOL8 hiNibbleLoop; /* indicates high/low nibble is next, value loop start */
EAS_U8 rateShift; /* for playback rate greater than 1.0 */
} S_PCM_STATE;
/*----------------------------------------------------------------------------
* S_DECODER_INTERFACE
*
* Generic interface for audio decoders
*----------------------------------------------------------------------------
*/
typedef struct s_decoder_interface_tag
{
EAS_RESULT (* EAS_CONST pfInit)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
EAS_RESULT (* EAS_CONST pfDecodeSample)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
EAS_RESULT (* EAS_CONST pfLocate)(EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
} S_DECODER_INTERFACE;
/* header chunk for SMAF ADPCM */
#define TAG_YAMAHA_ADPCM 0x4d776100
#define TAG_MASK 0xffffff00
#define TAG_RIFF_FILE 0x52494646
#define TAG_WAVE_CHUNK 0x57415645
#define TAG_FMT_CHUNK 0x666d7420
/*----------------------------------------------------------------------------
* EAS_PESeek
*----------------------------------------------------------------------------
* Purpose:
* Locate to a particular byte in a PCM stream
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_PESeek (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 *pLocation);
#endif /* _EAS_PCMDATA_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_reverbdata.c
*
* Contents and purpose:
* Contains the static data allocation 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: 550 $
* $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
*----------------------------------------------------------------------------
*/
#include "eas_reverbdata.h"
S_REVERB_OBJECT eas_ReverbData;

View File

@@ -0,0 +1,486 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_reverbdata.h
*
* Contents and purpose:
* Contains the prototypes 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: 499 $
* $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
*----------------------------------------------------------------------------
*/
#ifndef _EAS_REVERBDATA_H
#define _EAS_REVERBDATA_H
#include "eas_types.h"
#include "eas_audioconst.h"
/*------------------------------------
* defines
*------------------------------------
*/
/*
CIRCULAR() calculates the array index using modulo arithmetic.
The "trick" is that modulo arithmetic is simplified by masking
the effective address where the mask is (2^n)-1. This only works
if the buffer size is a power of two.
*/
#define CIRCULAR(base,offset,size) (EAS_U32)( \
( \
((EAS_I32)(base)) + ((EAS_I32)(offset)) \
) \
& size \
)
/* reverb parameters are updated every 2^(REVERB_UPDATE_PERIOD_IN_BITS) samples */
#if defined (_SAMPLE_RATE_8000)
#define REVERB_UPDATE_PERIOD_IN_BITS 5
#define REVERB_BUFFER_SIZE_IN_SAMPLES 2048
#elif defined (_SAMPLE_RATE_16000)
#define REVERB_UPDATE_PERIOD_IN_BITS 6
#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
#elif defined (_SAMPLE_RATE_22050)
#define REVERB_UPDATE_PERIOD_IN_BITS 7
#define REVERB_BUFFER_SIZE_IN_SAMPLES 4096
#elif defined (_SAMPLE_RATE_32000)
#define REVERB_UPDATE_PERIOD_IN_BITS 7
#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
#elif defined (_SAMPLE_RATE_44100)
#define REVERB_UPDATE_PERIOD_IN_BITS 8
#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
#elif defined (_SAMPLE_RATE_48000)
#define REVERB_UPDATE_PERIOD_IN_BITS 8
#define REVERB_BUFFER_SIZE_IN_SAMPLES 8192
#endif
// Define a mask for circular addressing, so that array index
// can wraparound and stay in array boundary of 0, 1, ..., (buffer size -1)
// The buffer size MUST be a power of two
#define REVERB_BUFFER_MASK (REVERB_BUFFER_SIZE_IN_SAMPLES -1)
#define REVERB_MAX_ROOM_TYPE 4 // any room numbers larger than this are invalid
#define REVERB_MAX_NUM_REFLECTIONS 5 // max num reflections per channel
/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
#define REVERB_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << REVERB_UPDATE_PERIOD_IN_BITS)
/*
calculate the update counter by bitwise ANDING with this value to
generate a 2^n modulo value
*/
#define REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(REVERB_UPDATE_PERIOD_IN_SAMPLES -1)
/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SECONDS seconds */
#define REVERB_UPDATE_PERIOD_IN_SECONDS (REVERB_UPDATE_PERIOD_IN_SAMPLES / _OUTPUT_SAMPLE_RATE)
// xfade parameters
#define REVERB_XFADE_PERIOD_IN_SECONDS (100.0 / 1000.0) // xfade once every this many seconds
#define REVERB_XFADE_PERIOD_IN_SAMPLES (REVERB_XFADE_PERIOD_IN_SECONDS * _OUTPUT_SAMPLE_RATE)
#define REVERB_XFADE_PHASE_INCREMENT (EAS_I16)(65536 / ((EAS_I16)REVERB_XFADE_PERIOD_IN_SAMPLES/(EAS_I16)REVERB_UPDATE_PERIOD_IN_SAMPLES))
/**********/
/* the entire synth uses various flags in a bit field */
/* if flag is set, synth reset has been requested */
#define REVERB_FLAG_RESET_IS_REQUESTED 0x01 /* bit 0 */
#define MASK_REVERB_RESET_IS_REQUESTED 0x01
#define MASK_REVERB_RESET_IS_NOT_REQUESTED (EAS_U32)(~MASK_REVERB_RESET_IS_REQUESTED)
/*
by default, we always want to update ALL channel parameters
when we reset the synth (e.g., during GM ON)
*/
#define DEFAULT_REVERB_FLAGS 0x0
/* coefficients for generating sin, cos */
#define REVERB_PAN_G2 4294940151 /* -0.82842712474619 = 2 - 4/sqrt(2) */
/*
EAS_I32 nPanG1 = +1.0 for sin
EAS_I32 nPanG1 = -1.0 for cos
*/
#define REVERB_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
/*************************************************************/
// define the input injection points
#define GUARD 5 // safety guard of this many samples
#define MAX_AP_TIME (double) (20.0/1000.0) // delay time in milliseconds
#define MAX_DELAY_TIME (double) (65.0/1000.0) // delay time in milliseconds
#define MAX_AP_SAMPLES (int)(((double) MAX_AP_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
#define MAX_DELAY_SAMPLES (int)(((double) MAX_DELAY_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
#define AP0_IN 0
#define AP1_IN (AP0_IN + MAX_AP_SAMPLES + GUARD)
#define DELAY0_IN (AP1_IN + MAX_AP_SAMPLES + GUARD)
#define DELAY1_IN (DELAY0_IN + MAX_DELAY_SAMPLES + GUARD)
// Define the max offsets for the end points of each section
// i.e., we don't expect a given section's taps to go beyond
// the following limits
#define AP0_OUT (AP0_IN + MAX_AP_SAMPLES -1)
#define AP1_OUT (AP1_IN + MAX_AP_SAMPLES -1)
#define DELAY0_OUT (DELAY0_IN + MAX_DELAY_SAMPLES -1)
#define DELAY1_OUT (DELAY1_IN + MAX_DELAY_SAMPLES -1)
#define REVERB_DEFAULT_ROOM_NUMBER 1 // default preset number
#define DEFAULT_AP0_LENGTH (int)(((double) (17.0/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
#define DEFAULT_AP0_GAIN 19400
#define DEFAULT_AP1_LENGTH (int)(((double) (16.5/1000.0)) * ((double) _OUTPUT_SAMPLE_RATE))
#define DEFAULT_AP1_GAIN -19400
#define REVERB_DEFAULT_WET 32767
#define REVERB_DEFAULT_DRY 0
#define EAS_REVERB_WET_MAX 32767
#define EAS_REVERB_WET_MIN 0
#define EAS_REVERB_DRY_MAX 32767
#define EAS_REVERB_DRY_MIN 0
/* parameters for each allpass */
typedef struct
{
EAS_U16 m_zApOut; // delay offset for ap out
EAS_I16 m_nApGain; // gain for ap
EAS_U16 m_zApIn; // delay offset for ap in
} S_ALLPASS_OBJECT;
/* parameters for each allpass */
typedef struct
{
EAS_PCM m_zLpf; // actual state variable, not a length
EAS_I16 m_nLpfFwd; // lpf forward gain
EAS_I16 m_nLpfFbk; // lpf feedback gain
EAS_U16 m_zDelay[REVERB_MAX_NUM_REFLECTIONS]; // delay offset for ap out
EAS_I16 m_nGain[REVERB_MAX_NUM_REFLECTIONS]; // gain for ap
} S_EARLY_REFLECTION_OBJECT;
//demo
typedef struct
{
EAS_I16 m_nLpfFbk;
EAS_I16 m_nLpfFwd;
EAS_I16 m_nEarly;
EAS_I16 m_nWet;
EAS_I16 m_nDry;
EAS_I16 m_nEarlyL_LpfFbk;
EAS_I16 m_nEarlyL_LpfFwd;
EAS_I16 m_nEarlyL_Delay0; //8
EAS_I16 m_nEarlyL_Gain0;
EAS_I16 m_nEarlyL_Delay1;
EAS_I16 m_nEarlyL_Gain1;
EAS_I16 m_nEarlyL_Delay2;
EAS_I16 m_nEarlyL_Gain2;
EAS_I16 m_nEarlyL_Delay3;
EAS_I16 m_nEarlyL_Gain3;
EAS_I16 m_nEarlyL_Delay4;
EAS_I16 m_nEarlyL_Gain4;
EAS_I16 m_nEarlyR_Delay0; //18
EAS_I16 m_nEarlyR_Gain0;
EAS_I16 m_nEarlyR_Delay1;
EAS_I16 m_nEarlyR_Gain1;
EAS_I16 m_nEarlyR_Delay2;
EAS_I16 m_nEarlyR_Gain2;
EAS_I16 m_nEarlyR_Delay3;
EAS_I16 m_nEarlyR_Gain3;
EAS_I16 m_nEarlyR_Delay4;
EAS_I16 m_nEarlyR_Gain4;
EAS_U16 m_nMaxExcursion; //28
EAS_I16 m_nXfadeInterval;
EAS_I16 m_nAp0_ApGain; //30
EAS_I16 m_nAp0_ApOut;
EAS_I16 m_nAp1_ApGain;
EAS_I16 m_nAp1_ApOut;
EAS_I16 m_rfu4;
EAS_I16 m_rfu5;
EAS_I16 m_rfu6;
EAS_I16 m_rfu7;
EAS_I16 m_rfu8;
EAS_I16 m_rfu9;
EAS_I16 m_rfu10; //43
} S_REVERB_PRESET;
typedef struct
{
S_REVERB_PRESET m_sPreset[REVERB_MAX_ROOM_TYPE]; //array of presets
} S_REVERB_PRESET_BANK;
/* parameters for each reverb */
typedef struct
{
/* controls entire reverb playback volume */
/* to conserve memory, use the MSB and ignore the LSB */
EAS_U8 m_nMasterVolume;
/* update counter keeps track of when synth params need updating */
/* only needs to be as large as REVERB_UPDATE_PERIOD_IN_SAMPLES */
EAS_I16 m_nUpdateCounter;
EAS_U16 m_nMinSamplesToAdd; /* ComputeReverb() generates this many samples */
EAS_U8 m_nFlags; /* misc flags/bit fields */
EAS_PCM *m_pOutputBuffer;
EAS_PCM *m_pInputBuffer;
EAS_U16 m_nNumSamplesInOutputBuffer;
EAS_U16 m_nNumSamplesInInputBuffer;
EAS_U16 m_nNumInputSamplesRead; // if m_nNumInputSamplesRead >= NumSamplesInInputBuffer
// then get a new input buffer
EAS_PCM *m_pNextInputSample;
EAS_U16 m_nBaseIndex; // base index for circular buffer
// reverb delay line offsets, allpass parameters, etc:
EAS_PCM m_nRevOutFbkR; // combine feedback reverb right out with dry left in
S_ALLPASS_OBJECT m_sAp0; // allpass 0 (left channel)
EAS_U16 m_zD0In; // delay offset for delay line D0 in
EAS_PCM m_nRevOutFbkL; // combine feedback reverb left out with dry right in
S_ALLPASS_OBJECT m_sAp1; // allpass 1 (right channel)
EAS_U16 m_zD1In; // delay offset for delay line D1 in
// delay output taps, notice criss cross order
EAS_U16 m_zD0Self; // self feeds forward d0 --> d0
EAS_U16 m_zD1Cross; // cross feeds across d1 --> d0
EAS_PCM m_zLpf0; // actual state variable, not a length
EAS_U16 m_zD1Self; // self feeds forward d1 --> d1
EAS_U16 m_zD0Cross; // cross feeds across d0 --> d1
EAS_PCM m_zLpf1; // actual state variable, not a length
EAS_I16 m_nSin; // gain for self taps
EAS_I16 m_nCos; // gain for cross taps
EAS_I16 m_nSinIncrement; // increment for gain
EAS_I16 m_nCosIncrement; // increment for gain
EAS_I16 m_nLpfFwd; // lpf forward gain (includes scaling for mixer)
EAS_I16 m_nLpfFbk; // lpf feedback gain
EAS_U16 m_nXfadeInterval; // update/xfade after this many samples
EAS_U16 m_nXfadeCounter; // keep track of when to xfade
EAS_I16 m_nPhase; // -1 <= m_nPhase < 1
// but during sin,cos calculations
// use m_nPhase/2
EAS_I16 m_nPhaseIncrement; // add this to m_nPhase each frame
EAS_I16 m_nNoise; // random noise sample
EAS_U16 m_nMaxExcursion; // the taps can excurse +/- this amount
EAS_BOOL m_bUseNoise; // if EAS_TRUE, use noise as input signal
EAS_BOOL m_bBypass; // if EAS_TRUE, then bypass reverb and copy input to output
EAS_I16 m_nCurrentRoom; // preset number for current room
EAS_I16 m_nNextRoom; // preset number for next room
EAS_I16 m_nWet; // gain for wet (processed) signal
EAS_I16 m_nDry; // gain for dry (unprocessed) signal
EAS_I16 m_nEarly; // gain for early (widen) signal
S_EARLY_REFLECTION_OBJECT m_sEarlyL; // left channel early reflections
S_EARLY_REFLECTION_OBJECT m_sEarlyR; // right channel early reflections
EAS_PCM m_nDelayLine[REVERB_BUFFER_SIZE_IN_SAMPLES]; // one large delay line for all reverb elements
S_REVERB_PRESET pPreset;
S_REVERB_PRESET_BANK m_sPreset;
//EAS_I8 preset;
} S_REVERB_OBJECT;
/*------------------------------------
* prototypes
*------------------------------------
*/
/*----------------------------------------------------------------------------
* ReverbUpdateXfade
*----------------------------------------------------------------------------
* Purpose:
* Update the xfade parameters as required
*
* Inputs:
* nNumSamplesToAdd - number of samples to write to buffer
*
* Outputs:
*
*
* Side Effects:
* - xfade parameters will be changed
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd);
/*----------------------------------------------------------------------------
* ReverbCalculateNoise
*----------------------------------------------------------------------------
* Purpose:
* Calculate a noise sample and limit its value
*
* Inputs:
* nMaxExcursion - noise value is limited to this value
* pnNoise - return new noise sample in this (not limited)
*
* Outputs:
* new limited noise value
*
* Side Effects:
* - *pnNoise noise value is updated
*
*----------------------------------------------------------------------------
*/
static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise);
/*----------------------------------------------------------------------------
* ReverbCalculateSinCos
*----------------------------------------------------------------------------
* Purpose:
* Calculate a new sin and cosine value based on the given phase
*
* Inputs:
* nPhase - phase angle
* pnSin - input old value, output new value
* pnCos - input old value, output new value
*
* Outputs:
*
* Side Effects:
* - *pnSin, *pnCos are updated
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos);
/*----------------------------------------------------------------------------
* Reverb
*----------------------------------------------------------------------------
* Purpose:
* apply reverb to the given signal
*
* Inputs:
* nNu
* pnSin - input old value, output new value
* pnCos - input old value, output new value
*
* Outputs:
* number of samples actually reverberated
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT Reverb(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer);
/*----------------------------------------------------------------------------
* ReverbReadInPresets()
*----------------------------------------------------------------------------
* Purpose: sets global reverb preset bank to defaults
*
* Inputs:
*
* Outputs:
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT* pReverbData);
/*----------------------------------------------------------------------------
* ReverbUpdateRoom
*----------------------------------------------------------------------------
* Purpose:
* Update the room's preset parameters as required
*
* Inputs:
*
* Outputs:
*
*
* Side Effects:
* - reverb paramters (fbk, fwd, etc) will be changed
* - m_nCurrentRoom := m_nNextRoom
*----------------------------------------------------------------------------
*/
static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT* pReverbData);
#endif /* #ifndef _EAS_REVERBDATA_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_rtttldata.c
*
* Contents and purpose:
* RTTTL File Parser data module for static memory models
*
* 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_rtttldata.h"
/*----------------------------------------------------------------------------
*
* eas_RTTTLData
*
* Static memory allocation for RTTTL parser
*----------------------------------------------------------------------------
*/
S_RTTTL_DATA eas_RTTTLData;

View File

@@ -0,0 +1,70 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_rtttldata.h
*
* Contents and purpose:
* SMF File Parser
*
* This file contains data declarations for the RTTTL 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_RTTTLDATA_H
#define EAS_RTTTLDATA_H
#include "eas_data.h"
/* maximum line size as specified in iMelody V1.2 spec */
#define MAX_LINE_SIZE 75
/*----------------------------------------------------------------------------
*
* S_RTTTL_DATA
*
* This structure contains the state data for the iMelody parser
*----------------------------------------------------------------------------
*/
typedef struct
{
EAS_FILE_HANDLE fileHandle; /* file handle */
S_SYNTH *pSynth; /* synthesizer handle */
S_METADATA_CB metadata; /* metadata callback */
EAS_I32 fileOffset; /* offset to start of data */
EAS_I32 time; /* current time in 256ths of a msec */
EAS_I32 tick; /* length of 32nd note in 256th of a msec */
EAS_I32 restTicks; /* ticks to rest after current note */
EAS_I32 repeatOffset; /* file offset to start of repeat section */
EAS_U8 repeatCount; /* repeat counter */
EAS_I8 dataByte; /* storage for characters that are "put back" */
EAS_U8 state; /* current state EAS_STATE_XXXX */
EAS_I8 style; /* from STYLE */
EAS_U8 note; /* MIDI note number */
EAS_U8 octave; /* decault octave prefix */
EAS_I8 duration; /* default note duration */
} S_RTTTL_DATA;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_smf.h
*
* Contents and purpose:
* SMF Type 0 and 1 File 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_SMF_H
#define _EAS_SMF_H
/* prototypes for private interface to SMF parser */
EAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
EAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
EAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
EAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
EAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
EAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
EAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
EAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
EAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
EAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
EAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
EAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData);
#endif /* end _EAS_SMF_H */

View File

@@ -0,0 +1,66 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_smfdata.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: 778 $
* $Date: 2007-07-23 16:45:17 -0700 (Mon, 23 Jul 2007) $
*----------------------------------------------------------------------------
*/
#include "eas_miditypes.h"
#include "eas_smfdata.h"
/*----------------------------------------------------------------------------
*
* S_SMF_STREAM
*
* Static memory allocation for SMF parser
*----------------------------------------------------------------------------
*/
static S_SMF_STREAM eas_SMFStreams[MAX_SMF_STREAMS];
/*----------------------------------------------------------------------------
*
* eas_SMFData
*
* Static memory allocation for SMF parser
*----------------------------------------------------------------------------
*/
S_SMF_DATA eas_SMFData =
{
eas_SMFStreams, /* pointer to individual streams in file */
0, /* pointer to next stream with event */
0, /* pointer to synth */
0, /* file handle */
{ 0, 0, 0, 0}, /* metadata callback */
0, /* file offset */
0, /* current time in milliseconds/256 */
0, /* actual number of streams */
0, /* current MIDI tick to msec conversion */
0, /* ticks per quarter note */
0, /* current state EAS_STATE_XXXX */
0 /* flags */
};

View File

@@ -0,0 +1,66 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_smfdata.h
*
* 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: 686 $
* $Date: 2007-05-03 14:10:54 -0700 (Thu, 03 May 2007) $
*----------------------------------------------------------------------------
*/
#ifndef _EAS_SMF_DATA_H
#define _EAS_SMF_DATA_H
#ifndef MAX_SMF_STREAMS
#define MAX_SMF_STREAMS 17
#endif
/* offsets in to the SMF file */
#define SMF_OFS_HEADER_SIZE 4
#define SMF_OFS_FILE_TYPE 8
#define SMF_OFS_NUM_TRACKS 10
/* size of chunk info (chunk ID + chunk size) */
#define SMF_CHUNK_INFO_SIZE 8
/* 'MTrk' track chunk ID */
#define SMF_CHUNK_TYPE_TRACK 0x4d54726bL
/* some useful meta-events */
#define SMF_META_TEXT 0x01
#define SMF_META_COPYRIGHT 0x02
#define SMF_META_SEQTRK_NAME 0x03
#define SMF_META_LYRIC 0x05
#define SMF_META_END_OF_TRACK 0x2f
#define SMF_META_TEMPO 0x51
#define SMF_META_TIME_SIGNATURE 0x58
/* default timebase (120BPM) */
#define SMF_DEFAULT_TIMEBASE 500000L
/* value for pSMFStream->ticks to signify end of track */
#define SMF_END_OF_TRACK 0xffffffff
#endif

View File

@@ -0,0 +1,406 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_sndlib.h
*
* Contents and purpose:
* Declarations for the sound library
*
* 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: 550 $
* $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
*----------------------------------------------------------------------------
*/
#ifndef _EAS_SNDLIB_H
#define _EAS_SNDLIB_H
#include "eas_types.h"
#include "eas_synthcfg.h"
#ifdef _WT_SYNTH
#include "eas_wtengine.h"
#endif
/*----------------------------------------------------------------------------
* This is bit of a hack to allow us to keep the same structure
* declarations for the DLS parser. Normally, the data is located
* in read-only memory, but for DLS, we store the data in RW
* memory.
*----------------------------------------------------------------------------
*/
#ifndef SCNST
#define SCNST const
#endif
/*----------------------------------------------------------------------------
* sample size
*----------------------------------------------------------------------------
*/
#ifdef _16_BIT_SAMPLES
typedef EAS_I16 EAS_SAMPLE;
#else
typedef EAS_I8 EAS_SAMPLE;
#endif
/*----------------------------------------------------------------------------
* EAS Library ID - quick check for valid library and version
*----------------------------------------------------------------------------
*/
#define _EAS_LIBRARY_VERSION 0x01534145
#define NUM_PROGRAMS_IN_BANK 128
#define INVALID_REGION_INDEX 0xffff
/* this bit in region index indicates that region is for secondary synth */
#define FLAG_RGN_IDX_FM_SYNTH 0x8000
#define FLAG_RGN_IDX_DLS_SYNTH 0x4000
#define REGION_INDEX_MASK 0x3fff
/*----------------------------------------------------------------------------
* Generic region data structure
*
* This must be the first element in each region structure
*----------------------------------------------------------------------------
*/
typedef struct s_region_tag
{
EAS_U16 keyGroupAndFlags;
EAS_U8 rangeLow;
EAS_U8 rangeHigh;
} S_REGION;
/*
* Bit fields for m_nKeyGroupAndFlags
* Bits 0-2 are mode bits in FM synth
* Bits 8-11 are the key group
*/
#define REGION_FLAG_IS_LOOPED 0x01
#define REGION_FLAG_USE_WAVE_GENERATOR 0x02
#define REGION_FLAG_USE_ADPCM 0x04
#define REGION_FLAG_ONE_SHOT 0x08
#define REGION_FLAG_SQUARE_WAVE 0x10
#define REGION_FLAG_OFF_CHIP 0x20
#define REGION_FLAG_NON_SELF_EXCLUSIVE 0x40
#define REGION_FLAG_LAST_REGION 0x8000
/*----------------------------------------------------------------------------
* Envelope data structure
*----------------------------------------------------------------------------
*/
typedef struct s_envelope_tag
{
EAS_I16 attackTime;
EAS_I16 decayTime;
EAS_I16 sustainLevel;
EAS_I16 releaseTime;
} S_ENVELOPE;
/*----------------------------------------------------------------------------
* DLS envelope data structure
*----------------------------------------------------------------------------
*/
typedef struct s_dls_envelope_tag
{
EAS_I16 delayTime;
EAS_I16 attackTime;
EAS_I16 holdTime;
EAS_I16 decayTime;
EAS_I16 sustainLevel;
EAS_I16 releaseTime;
EAS_I16 velToAttack;
EAS_I16 keyNumToDecay;
EAS_I16 keyNumToHold;
} S_DLS_ENVELOPE;
/*----------------------------------------------------------------------------
* LFO data structure
*----------------------------------------------------------------------------
*/
typedef struct s_lfo_params_tag
{
EAS_I16 lfoFreq;
EAS_I16 lfoDelay;
} S_LFO_PARAMS;
/*----------------------------------------------------------------------------
* Articulation data structure
*----------------------------------------------------------------------------
*/
typedef struct s_articulation_tag
{
S_ENVELOPE eg1;
S_ENVELOPE eg2;
EAS_I16 lfoToPitch;
EAS_I16 lfoDelay;
EAS_I16 lfoFreq;
EAS_I16 eg2ToPitch;
EAS_I16 eg2ToFc;
EAS_I16 filterCutoff;
EAS_I8 lfoToGain;
EAS_U8 filterQ;
EAS_I8 pan;
} S_ARTICULATION;
/*----------------------------------------------------------------------------
* DLS articulation data structure
*----------------------------------------------------------------------------
*/
typedef struct s_dls_articulation_tag
{
S_LFO_PARAMS modLFO;
S_LFO_PARAMS vibLFO;
S_DLS_ENVELOPE eg1;
S_DLS_ENVELOPE eg2;
EAS_I16 eg1ShutdownTime;
EAS_I16 filterCutoff;
EAS_I16 modLFOToFc;
EAS_I16 modLFOCC1ToFc;
EAS_I16 modLFOChanPressToFc;
EAS_I16 eg2ToFc;
EAS_I16 velToFc;
EAS_I16 keyNumToFc;
EAS_I16 modLFOToGain;
EAS_I16 modLFOCC1ToGain;
EAS_I16 modLFOChanPressToGain;
EAS_I16 tuning;
EAS_I16 keyNumToPitch;
EAS_I16 vibLFOToPitch;
EAS_I16 vibLFOCC1ToPitch;
EAS_I16 vibLFOChanPressToPitch;
EAS_I16 modLFOToPitch;
EAS_I16 modLFOCC1ToPitch;
EAS_I16 modLFOChanPressToPitch;
EAS_I16 eg2ToPitch;
/* pad to 4-byte boundary */
EAS_U16 pad;
EAS_I8 pan;
EAS_U8 filterQandFlags;
#ifdef _REVERB
EAS_I16 reverbSend;
EAS_I16 cc91ToReverbSend;
#endif
#ifdef _CHORUS
EAS_I16 chorusSend;
EAS_I16 cc93ToChorusSend;
#endif
} S_DLS_ARTICULATION;
/* flags in filterQandFlags
* NOTE: Q is stored in bottom 5 bits
*/
#define FLAG_DLS_VELOCITY_SENSITIVE 0x80
#define FILTER_Q_MASK 0x1f
/*----------------------------------------------------------------------------
* Wavetable region data structure
*----------------------------------------------------------------------------
*/
typedef struct s_wt_region_tag
{
S_REGION region;
EAS_I16 tuning;
EAS_I16 gain;
EAS_U32 loopStart;
EAS_U32 loopEnd;
EAS_U16 waveIndex;
EAS_U16 artIndex;
} S_WT_REGION;
/*----------------------------------------------------------------------------
* DLS region data structure
*----------------------------------------------------------------------------
*/
typedef struct s_dls_region_tag
{
S_WT_REGION wtRegion;
EAS_U8 velLow;
EAS_U8 velHigh;
} S_DLS_REGION;
/*----------------------------------------------------------------------------
* FM synthesizer data structures
*----------------------------------------------------------------------------
*/
typedef struct s_fm_oper_tag
{
EAS_I16 tuning;
EAS_U8 attackDecay;
EAS_U8 velocityRelease;
EAS_U8 egKeyScale;
EAS_U8 sustain;
EAS_U8 gain;
EAS_U8 flags;
} S_FM_OPER;
/* defines for S_FM_OPER.m_nFlags */
#define FM_OPER_FLAG_MONOTONE 0x01
#define FM_OPER_FLAG_NO_VIBRATO 0x02
#define FM_OPER_FLAG_NOISE 0x04
#define FM_OPER_FLAG_LINEAR_VELOCITY 0x08
/* NOTE: The first two structure elements are common with S_WT_REGION
* and we will rely on that in the voice management code and must
* remain there unless the voice management code is revisited.
*/
typedef struct s_fm_region_tag
{
S_REGION region;
EAS_U8 vibTrem;
EAS_U8 lfoFreqDelay;
EAS_U8 feedback;
EAS_I8 pan;
S_FM_OPER oper[4];
} S_FM_REGION;
/*----------------------------------------------------------------------------
* Common data structures
*----------------------------------------------------------------------------
*/
/*----------------------------------------------------------------------------
* Program data structure
* Used for individual programs not stored as a complete bank.
*----------------------------------------------------------------------------
*/
typedef struct s_program_tag
{
EAS_U32 locale;
EAS_U16 regionIndex;
} S_PROGRAM;
/*----------------------------------------------------------------------------
* Bank data structure
*
* A bank always consists of 128 programs. If a bank is less than 128
* programs, it should be stored as a spare matrix in the pPrograms
* array.
*
* bankNum: MSB/LSB of MIDI bank select controller
* regionIndex: Index of first region in program
*----------------------------------------------------------------------------
*/
typedef struct s_bank_tag
{
EAS_U16 locale;
EAS_U16 regionIndex[NUM_PROGRAMS_IN_BANK];
} S_BANK;
/* defines for libFormat field
* bits 0-17 are the sample rate
* bit 18 is true if wavetable is present
* bit 19 is true if FM is present
* bit 20 is true if filter is enabled
* bit 21 is sample depth (0 = 8-bits, 1 = 16-bits)
* bits 22-31 are reserved
*/
#define LIBFORMAT_SAMPLE_RATE_MASK 0x0003ffff
#define LIB_FORMAT_TYPE_MASK 0x000c0000
#define LIB_FORMAT_WAVETABLE 0x00000000
#define LIB_FORMAT_FM 0x00040000
#define LIB_FORMAT_HYBRID 0x00080000
#define LIB_FORMAT_FILTER_ENABLED 0x00100000
#define LIB_FORMAT_16_BIT_SAMPLES 0x00200000
#ifdef DLS_SYNTHESIZER
/*----------------------------------------------------------------------------
* DLS data structure
*
* pDLSPrograms pointer to array of DLS programs
* pDLSRegions pointer to array of DLS regions
* pDLSArticulations pointer to array of DLS articulations
* pSampleLen pointer to array of sample lengths
* ppSamples pointer to array of sample pointers
* numDLSPrograms number of DLS programs
* numDLSRegions number of DLS regions
* numDLSArticulations number of DLS articulations
* numDLSSamples number of DLS samples
*----------------------------------------------------------------------------
*/
typedef struct s_eas_dls_tag
{
S_PROGRAM *pDLSPrograms;
S_DLS_REGION *pDLSRegions;
S_DLS_ARTICULATION *pDLSArticulations;
EAS_U32 *pDLSSampleLen;
EAS_U32 *pDLSSampleOffsets;
EAS_SAMPLE *pDLSSamples;
EAS_U16 numDLSPrograms;
EAS_U16 numDLSRegions;
EAS_U16 numDLSArticulations;
EAS_U16 numDLSSamples;
EAS_U8 refCount;
} S_DLS;
#endif
/*----------------------------------------------------------------------------
* Sound library data structure
*
* pBanks pointer to array of banks
* pPrograms pointer to array of programs
* pWTRegions pointer to array of wavetable regions
* pFMRegions pointer to array of FM regions
* pArticulations pointer to array of articulations
* pSampleLen pointer to array of sample lengths
* ppSamples pointer to array of sample pointers
* numBanks number of banks
* numPrograms number of individual program
* numRegions number of regions
* numArticulations number of articulations
* numSamples number of samples
*----------------------------------------------------------------------------
*/
typedef struct s_eas_sndlib_tag
{
SCNST EAS_U32 identifier;
SCNST EAS_U32 libAttr;
SCNST S_BANK *pBanks;
SCNST S_PROGRAM *pPrograms;
SCNST S_WT_REGION *pWTRegions;
SCNST S_ARTICULATION *pArticulations;
SCNST EAS_U32 *pSampleLen;
SCNST EAS_U32 *pSampleOffsets;
SCNST EAS_SAMPLE *pSamples;
SCNST S_FM_REGION *pFMRegions;
SCNST EAS_U16 numBanks;
SCNST EAS_U16 numPrograms;
SCNST EAS_U16 numWTRegions;
SCNST EAS_U16 numArticulations;
SCNST EAS_U16 numSamples;
SCNST EAS_U16 numFMRegions;
} S_EAS;
#endif

View File

@@ -0,0 +1,395 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_synth.h
*
* Contents and purpose:
* Declarations, interfaces, and prototypes for synth.
*
* Copyright Sonic Network Inc. 2004, 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: 718 $
* $Date: 2007-06-08 16:43:16 -0700 (Fri, 08 Jun 2007) $
*----------------------------------------------------------------------------
*/
#ifndef _EAS_SYNTH_H
#define _EAS_SYNTH_H
#include "eas_types.h"
#include "eas_sndlib.h"
#ifdef _WT_SYNTH
#include "eas_wtsynth.h"
#endif
#ifdef _FM_SYNTH
#include "eas_fmsynth.h"
#endif
#ifndef NUM_OUTPUT_CHANNELS
#define NUM_OUTPUT_CHANNELS 2
#endif
#ifndef MAX_SYNTH_VOICES
#define MAX_SYNTH_VOICES 64
#endif
#ifndef MAX_VIRTUAL_SYNTHESIZERS
#define MAX_VIRTUAL_SYNTHESIZERS 4
#endif
/* defines */
#ifndef NUM_PRIMARY_VOICES
#define NUM_PRIMARY_VOICES MAX_SYNTH_VOICES
#elif !defined(NUM_SECONDARY_VOICES)
#define NUM_SECONDARY_VOICES (MAX_SYNTH_VOICES - NUM_PRIMARY_VOICES)
#endif
#if defined(EAS_WT_SYNTH)
#define NUM_WT_VOICES MAX_SYNTH_VOICES
/* FM on MCU */
#elif defined(EAS_FM_SYNTH)
#define NUM_FM_VOICES MAX_SYNTH_VOICES
/* wavetable drums on MCU, wavetable melodic on DSP */
#elif defined(EAS_SPLIT_WT_SYNTH)
#define NUM_WT_VOICES MAX_SYNTH_VOICES
/* wavetable drums and FM melodic on MCU */
#elif defined(EAS_HYBRID_SYNTH)
#define NUM_WT_VOICES NUM_PRIMARY_VOICES
#define NUM_FM_VOICES NUM_SECONDARY_VOICES
/* wavetable drums on MCU, FM melodic on DSP */
#elif defined(EAS_SPLIT_HYBRID_SYNTH)
#define NUM_WT_VOICES NUM_PRIMARY_VOICES
#define NUM_FM_VOICES NUM_SECONDARY_VOICES
/* FM synth on DSP */
#elif defined(EAS_SPLIT_FM_SYNTH)
#define NUM_FM_VOICES MAX_SYNTH_VOICES
#else
#error "Unrecognized architecture option"
#endif
#define NUM_SYNTH_CHANNELS 16
#define DEFAULT_SYNTH_VOICES MAX_SYNTH_VOICES
/* use the following values to specify unassigned channels or voices */
#define UNASSIGNED_SYNTH_CHANNEL NUM_SYNTH_CHANNELS
#define UNASSIGNED_SYNTH_VOICE MAX_SYNTH_VOICES
/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
#define SYNTH_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << SYNTH_UPDATE_PERIOD_IN_BITS)
/* stealing weighting factors */
#define NOTE_AGE_STEAL_WEIGHT 1
#define NOTE_GAIN_STEAL_WEIGHT 4
#define CHANNEL_POLY_STEAL_WEIGHT 12
#define CHANNEL_PRIORITY_STEAL_WEIGHT 2
#define NOTE_MATCH_PENALTY 128
#define SYNTH_PRIORITY_WEIGHT 8
/* default synth master volume */
#define DEFAULT_SYNTH_MASTER_VOLUME 0x7fff
#define DEFAULT_SYNTH_PRIORITY 5
/* default tuning values */
#define DEFAULT_PITCH_BEND_SENSITIVITY 200 /* 2 semitones */
#define DEFAULT_FINE_PITCH 0 /* 0 cents */
#define DEFAULT_COARSE_PITCH 0 /* 0 semitones */
/* default drum channel is 10, but is internally 9 due to unit offset */
#define DEFAULT_DRUM_CHANNEL 9
/* drum channel can simultaneously play this many voices at most */
#define DEFAULT_CHANNEL_POLYPHONY_LIMIT 2
/* default instrument is acoustic piano */
#define DEFAULT_MELODY_BANK_MSB 0x79
#define DEFAULT_RHYTHM_BANK_MSB 0x78
#define DEFAULT_MELODY_BANK_NUMBER (DEFAULT_MELODY_BANK_MSB << 8)
#define DEFAULT_RHYTHM_BANK_NUMBER (DEFAULT_RHYTHM_BANK_MSB << 8)
#define DEFAULT_SYNTH_PROGRAM_NUMBER 0
#define DEFAULT_PITCH_BEND 0x2000 /* 0x2000 == (0x40 << 7) | 0x00 */
#define DEFAULT_MOD_WHEEL 0
#define DEFAULT_CHANNEL_VOLUME 0x64
#define DEFAULT_PAN 0x40 /* decimal 64, center */
#ifdef _REVERB
#define DEFAULT_REVERB_SEND 40 /* some reverb */
#endif
#ifdef _CHORUS
#define DEFAULT_CHORUS_SEND 0 /* no chorus */
#endif
#define DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY 0 /* EAS synth uses a different default */
#define DEFAULT_FILTER_RESONANCE 0
#define DEFAULT_EXPRESSION 0x7F
#define DEFAULT_CHANNEL_PRESSURE 0
#define DEFAULT_REGISTERED_PARAM 0x3FFF
#define DEFAULT_CHANNEL_STATIC_GAIN 0
#define DEFAULT_CHANNEL_STATIC_PITCH 0
#define DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS 50
#define DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS 50
#define DEFAULT_KEY_NUMBER 0x69
#define DEFAULT_VELOCITY 0x64
#define DEFAULT_REGION_INDEX 0
#define DEFAULT_ARTICULATION_INDEX 0
#define DEFAULT_VOICE_GAIN 0
#define DEFAULT_AGE 0
#define DEFAULT_SP_MIDI_PRIORITY 16
/* filter defines */
#define DEFAULT_FILTER_ZERO 0
#define FILTER_CUTOFF_MAX_PITCH_CENTS 1919
#define FILTER_CUTOFF_MIN_PITCH_CENTS -4467
#define A5_PITCH_OFFSET_IN_CENTS 6900
/*------------------------------------
* S_SYNTH_CHANNEL data structure
*------------------------------------
*/
/* S_SYNTH_CHANNEL.m_nFlags */
#define CHANNEL_FLAG_SUSTAIN_PEDAL 0x01
#define CHANNEL_FLAG_MUTE 0x02
#define CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS 0x04
#define CHANNEL_FLAG_RHYTHM_CHANNEL 0x08
#define CHANNEL_FLAG_EXTERNAL_AUDIO 0x10
#define DEFAULT_CHANNEL_FLAGS 0
/* macros for extracting virtual synth and channel numbers */
#define GET_VSYNTH(a) ((a) >> 4)
#define GET_CHANNEL(a) ((a) & 15)
typedef struct s_synth_channel_tag
{
/* use static channel parameters to reduce MIPs */
/* parameters shared by multiple voices assigned to same channel */
EAS_I32 staticPitch; /* (pitch bend * pitch sens) + fine pitch */
EAS_I16 staticGain; /* (CC7 * CC11 * master vol)^2 */
EAS_U16 regionIndex; /* index of first region in program */
EAS_U16 bankNum; /* play programs from this bank */
EAS_I16 pitchBend; /* pitch wheel value */
EAS_I16 pitchBendSensitivity;
EAS_I16 registeredParam; /* currently selected registered param */
#if defined(_FM_SYNTH)
EAS_I16 lfoAmt; /* amount of LFO to apply to voice */
#endif
EAS_U8 programNum; /* play this instrument number */
EAS_U8 modWheel; /* CC1 */
EAS_U8 volume; /* CC7 */
EAS_U8 pan; /* CC10 */
EAS_U8 expression; /* CC11 */
/* the following parameters are controlled by RPNs */
EAS_I8 finePitch;
EAS_I8 coarsePitch;
EAS_U8 channelPressure; /* applied to all voices on a given channel */
EAS_U8 channelFlags; /* bit field channelFlags for */
/* CC64, SP-MIDI channel masking */
EAS_U8 pool; /* SPMIDI channel voice pool */
EAS_U8 mip; /* SPMIDI MIP setting */
#ifdef _REVERB
EAS_U8 reverbSend; /* CC91 */
#endif
#ifdef _CHORUS
EAS_U8 chorusSend; /* CC93 */
#endif
} S_SYNTH_CHANNEL;
/*------------------------------------
* S_SYNTH_VOICE data structure
*------------------------------------
*/
/* S_SYNTH_VOICE.m_nFlags */
#define VOICE_FLAG_UPDATE_VOICE_PARAMETERS 0x01
#define VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF 0x02
#define VOICE_FLAG_DEFER_MIDI_NOTE_OFF 0x04
#define VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET 0x08
#define VOICE_FLAG_DEFER_MUTE 0x40
#define DEFAULT_VOICE_FLAGS 0
/* S_SYNTH_VOICE.m_eState */
typedef enum {
eVoiceStateFree = 0,
eVoiceStateStart,
eVoiceStatePlay,
eVoiceStateRelease,
eVoiceStateMuting,
eVoiceStateStolen,
eVoiceStateInvalid /* should never be in this state! */
} E_VOICE_STATE;
#define DEFAULT_VOICE_STATE eVoiceStateFree
typedef struct s_synth_voice_tag
{
/* These parameters are common to both wavetable and FM
* synthesizers. The voice manager should only access this data.
* Any other data should be manipulated by the code that is
* specific to that synthesizer and reflected back through the
* common state data available here.
*/
EAS_U16 regionIndex; /* index to wave and playback params */
EAS_I16 gain; /* current gain */
EAS_U16 age; /* large value means old note */
EAS_U16 nextRegionIndex; /* index to wave and playback params */
EAS_U8 voiceState; /* current voice state */
EAS_U8 voiceFlags; /* misc flags/bit fields */
EAS_U8 channel; /* this voice plays on this synth channel */
EAS_U8 note; /* 12 <= key number <= 108 */
EAS_U8 velocity; /* 0 <= velocity <= 127 */
EAS_U8 nextChannel; /* play stolen voice on this channel */
EAS_U8 nextNote; /* 12 <= key number <= 108 */
EAS_U8 nextVelocity; /* 0 <= velocity <= 127 */
} S_SYNTH_VOICE;
/*------------------------------------
* S_SYNTH data structure
*
* One instance for each MIDI stream
*------------------------------------
*/
/* S_SYNTH.m_nFlags */
#define SYNTH_FLAG_RESET_IS_REQUESTED 0x01
#define SYNTH_FLAG_SP_MIDI_ON 0x02
#define SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS 0x04
#define SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING 0x08
#define DEFAULT_SYNTH_FLAGS SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS
typedef struct s_synth_tag
{
struct s_eas_data_tag *pEASData;
const S_EAS *pEAS;
#ifdef DLS_SYNTHESIZER
S_DLS *pDLS;
#endif
#ifdef EXTERNAL_AUDIO
EAS_EXT_PRG_CHG_FUNC cbProgChgFunc;
EAS_EXT_EVENT_FUNC cbEventFunc;
EAS_VOID_PTR *pExtAudioInstData;
#endif
S_SYNTH_CHANNEL channels[NUM_SYNTH_CHANNELS];
EAS_I32 totalNoteCount;
EAS_U16 maxPolyphony;
EAS_U16 numActiveVoices;
EAS_U16 masterVolume;
EAS_U8 channelsByPriority[NUM_SYNTH_CHANNELS];
EAS_U8 poolCount[NUM_SYNTH_CHANNELS];
EAS_U8 poolAlloc[NUM_SYNTH_CHANNELS];
EAS_U8 synthFlags;
EAS_I8 globalTranspose;
EAS_U8 vSynthNum;
EAS_U8 refCount;
EAS_U8 priority;
} S_SYNTH;
/*------------------------------------
* S_VOICE_MGR data structure
*
* One instance for each EAS library instance
*------------------------------------
*/
typedef struct s_voice_mgr_tag
{
S_SYNTH *pSynth[MAX_VIRTUAL_SYNTHESIZERS];
EAS_PCM voiceBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
#ifdef _FM_SYNTH
EAS_PCM operMixBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
S_FM_VOICE fmVoices[NUM_FM_VOICES];
#endif
#ifdef _WT_SYNTH
S_WT_VOICE wtVoices[NUM_WT_VOICES];
#endif
#ifdef _REVERB
EAS_PCM reverbSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
#endif
#ifdef _CHORUS
EAS_PCM chorusSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
#endif
S_SYNTH_VOICE voices[MAX_SYNTH_VOICES];
EAS_SNDLIB_HANDLE pGlobalEAS;
#ifdef DLS_SYNTHESIZER
S_DLS *pGlobalDLS;
#endif
#ifdef _SPLIT_ARCHITECTURE
EAS_FRAME_BUFFER_HANDLE pFrameBuffer;
#endif
#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
EAS_U16 maxPolyphonyPrimary;
EAS_U16 maxPolyphonySecondary;
#endif
EAS_I32 workload;
EAS_I32 maxWorkLoad;
EAS_U16 activeVoices;
EAS_U16 maxPolyphony;
EAS_U16 age;
/* limits the number of voice starts in a frame for split architecture */
#ifdef MAX_VOICE_STARTS
EAS_U16 numVoiceStarts;
#endif
} S_VOICE_MGR;
#endif /* #ifdef _EAS_SYNTH_H */

View File

@@ -0,0 +1,60 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_synth_protos.h
*
* Contents and purpose:
* Declarations, interfaces, and prototypes for synth.
*
* 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) $
*----------------------------------------------------------------------------
*/
#ifndef _EAS_SYNTH_PROTOS_H
#define _EAS_SYNTH_PROTOS_H
/* includes */
#include "eas_data.h"
#include "eas_sndlib.h"
#ifdef _SPLIT_ARCHITECTURE
typedef struct s_frame_interface_tag
{
EAS_BOOL (* EAS_CONST pfStartFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
EAS_BOOL (* EAS_CONST pfEndFrame)(EAS_FRAME_BUFFER_HANDLE pFrameBuffer, EAS_I32 *pMixBuffer, EAS_I16 masterGain);
} S_FRAME_INTERFACE;
#endif
/* generic synthesizer interface */
typedef struct
{
EAS_RESULT (* EAS_CONST pfInitialize)(S_VOICE_MGR *pVoiceMgr);
EAS_RESULT (* EAS_CONST pfStartVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_U16 regionIndex);
EAS_BOOL (* EAS_CONST pfUpdateVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum, EAS_I32 *pMixBuffer, EAS_I32 numSamples);
void (* EAS_CONST pfReleaseVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
void (* EAS_CONST pfMuteVoice)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, EAS_I32 voiceNum);
void (* EAS_CONST pfSustainPedal)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, S_SYNTH_VOICE *pVoice, S_SYNTH_CHANNEL *pChannel, EAS_I32 voiceNum);
void (* EAS_CONST pfUpdateChannel)(S_VOICE_MGR *pVoiceMgr, S_SYNTH *pSynth, EAS_U8 channel);
} S_SYNTH_INTERFACE;
#endif

View File

@@ -0,0 +1,70 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_synthcfg.h
*
* Contents and purpose:
* Defines for various synth configurations
*
* Copyright Sonic Network Inc. 2004, 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: 664 $
* $Date: 2007-04-25 13:11:22 -0700 (Wed, 25 Apr 2007) $
*----------------------------------------------------------------------------
*/
#ifndef _EAS_SYNTHCFG_H
#define _EAS_SYNTHCFG_H
#if defined(EAS_WT_SYNTH)
#define _WT_SYNTH
/* FM on MCU */
#elif defined(EAS_FM_SYNTH)
#define _FM_SYNTH
/* wavetable drums and FM melodic on MCU */
#elif defined(EAS_HYBRID_SYNTH)
#define _WT_SYNTH
#define _FM_SYNTH
#define _SECONDARY_SYNTH
#define _HYBRID_SYNTH
/* wavetable drums on MCU, wavetable melodic on DSP */
#elif defined(EAS_SPLIT_WT_SYNTH)
#define _WT_SYNTH
#define _SPLIT_ARCHITECTURE
/* wavetable drums on MCU, FM melodic on DSP */
#elif defined(EAS_SPLIT_HYBRID_SYNTH)
#define _WT_SYNTH
#define _FM_SYNTH
#define _SECONDARY_SYNTH
#define _SPLIT_ARCHITECTURE
#define _HYBRID_SYNTH
/* FM synth on DSP */
#elif defined(EAS_SPLIT_FM_SYNTH)
#define _FM_SYNTH
#define _SPLIT_ARCHITECTURE
#else
#error "Unrecognized architecture option"
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,867 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_wavefile.c
*
* Contents and purpose:
* This file implements the wave file 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: 852 $
* $Date: 2007-09-04 11:43:49 -0700 (Tue, 04 Sep 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_wavefile.h"
/* lint is choking on the ARM math.h file, so we declare the log10 function here */
extern double log10(double x);
/* increase gain to compensate for loss in mixer */
#define WAVE_GAIN_OFFSET 6
/* constant for 1200 / log10(2.0) */
#define PITCH_CENTS_CONVERSION 3986.313714
/*----------------------------------------------------------------------------
* WAVE file defines
*----------------------------------------------------------------------------
*/
/* RIFF chunks */
#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_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_LIST CHUNK_TYPE('L','I','S','T')
#define CHUNK_INFO CHUNK_TYPE('I','N','F','O')
#define CHUNK_INAM CHUNK_TYPE('I','N','A','M')
#define CHUNK_ICOP CHUNK_TYPE('I','C','O','P')
#define CHUNK_IART CHUNK_TYPE('I','A','R','T')
/* wave file format identifiers */
#define WAVE_FORMAT_PCM 0x0001
#define WAVE_FORMAT_IMA_ADPCM 0x0011
/* file size for streamed file */
#define FILE_SIZE_STREAMING 0x80000000
/*----------------------------------------------------------------------------
* prototypes
*----------------------------------------------------------------------------
*/
static EAS_RESULT WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset);
static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
static EAS_RESULT WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
static EAS_RESULT WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate);
static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData);
static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength);
#ifdef MMAPI_SUPPORT
static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 size);
#endif
/*----------------------------------------------------------------------------
*
* EAS_Wave_Parser
*
* This structure contains the functional interface for the Wave file parser
*----------------------------------------------------------------------------
*/
const S_FILE_PARSER_INTERFACE EAS_Wave_Parser =
{
WaveCheckFileType,
WavePrepare,
NULL,
NULL,
WaveState,
WaveClose,
WaveReset,
WavePause,
WaveResume,
WaveLocate,
WaveSetData,
WaveGetData,
WaveGetMetaData
};
/*----------------------------------------------------------------------------
* WaveCheckFileType()
*----------------------------------------------------------------------------
* 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 WaveCheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *pHandle, EAS_I32 offset)
{
S_WAVE_STATE *pWaveData;
/* zero the memory to insure complete initialization */
*pHandle = NULL;
/* read the file header */
if (WaveParseHeader(pEASData, fileHandle, NULL) == EAS_SUCCESS)
{
/* check for static memory allocation */
if (pEASData->staticMemoryModel)
pWaveData = EAS_CMEnumData(EAS_CM_WAVE_DATA);
else
pWaveData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_WAVE_STATE));
if (!pWaveData)
return EAS_ERROR_MALLOC_FAILED;
EAS_HWMemSet(pWaveData, 0, sizeof(S_WAVE_STATE));
/* return a pointer to the instance data */
pWaveData->fileHandle = fileHandle;
pWaveData->fileOffset = offset;
*pHandle = pWaveData;
}
return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* WavePrepare()
*----------------------------------------------------------------------------
* Purpose:
* Prepare to parse the file.
*
* Inputs:
* pEASData - pointer to overall EAS data structure
* handle - pointer to file handle
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT WavePrepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
{
S_WAVE_STATE *pWaveData;
EAS_RESULT result;
/* validate parser state */
pWaveData = (S_WAVE_STATE*) pInstData;
if (pWaveData->streamHandle != NULL)
return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
/* back to start of file */
pWaveData->time = 0;
if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->fileOffset)) != EAS_SUCCESS)
return result;
/* parse the file header */
if ((result = WaveParseHeader(pEASData, pWaveData->fileHandle, pWaveData)) != EAS_SUCCESS)
return result;
return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* WaveState()
*----------------------------------------------------------------------------
* 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.
*----------------------------------------------------------------------------
*/
static EAS_RESULT WaveState (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState)
{
S_WAVE_STATE *pWaveData;
/* return current state */
pWaveData = (S_WAVE_STATE*) pInstData;
if (pWaveData->streamHandle)
return EAS_PEState(pEASData, pWaveData->streamHandle, pState);
/* if no stream handle, and time is not zero, we are done */
if (pWaveData->time > 0)
*pState = EAS_STATE_STOPPED;
else
*pState = EAS_STATE_OPEN;
return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* WaveClose()
*----------------------------------------------------------------------------
* 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 WaveClose (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
{
S_WAVE_STATE *pWaveData;
EAS_RESULT result;
pWaveData = (S_WAVE_STATE*) pInstData;
/* close the stream */
if (pWaveData->streamHandle)
{
if ((result = EAS_PEClose(pEASData, pWaveData->streamHandle)) != EAS_SUCCESS)
return result;
pWaveData->streamHandle = NULL;
}
/* if using dynamic memory, free it */
if (!pEASData->staticMemoryModel)
{
#ifdef MMAPI_SUPPORT
/* need to free the fmt chunk */
if (pWaveData->fmtChunk != NULL)
EAS_HWFree(pEASData->hwInstData, pWaveData->fmtChunk);
#endif
/* free the instance data */
EAS_HWFree(pEASData->hwInstData, pWaveData);
}
return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* WaveReset()
*----------------------------------------------------------------------------
* 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 WaveReset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
{
EAS_PCM_HANDLE streamHandle;
/* reset to first byte of data in the stream */
streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
if (streamHandle)
return EAS_PEReset(pEASData, streamHandle);
return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
}
/*----------------------------------------------------------------------------
* WaveLocate()
*----------------------------------------------------------------------------
* Purpose:
* Rewind/fast-forward in file.
*
* Inputs:
* pEASData - pointer to overall EAS data structure
* handle - pointer to file handle
* time - time (in msecs)
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pParserLocate) reserved for future use */
static EAS_RESULT WaveLocate (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 time, EAS_BOOL *pParserLocate)
{
EAS_PCM_HANDLE streamHandle;
/* reset to first byte of data in the stream */
streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
if (streamHandle)
return EAS_PELocate(pEASData, streamHandle, time);
return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
}
/*----------------------------------------------------------------------------
* WavePause()
*----------------------------------------------------------------------------
* 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_WAVE_STATE for this stream
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pEASData) reserved for future use */
static EAS_RESULT WavePause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
{
EAS_PCM_HANDLE streamHandle;
/* pause the stream */
streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
if (streamHandle)
return EAS_PEPause(pEASData, streamHandle);
return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
}
/*----------------------------------------------------------------------------
* WaveResume()
*----------------------------------------------------------------------------
* 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_WAVE_STATE for this stream
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pEASData) reserved for future use */
static EAS_RESULT WaveResume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
{
EAS_PCM_HANDLE streamHandle;
/* resume the stream */
streamHandle = ((S_WAVE_STATE*)pInstData)->streamHandle;
if (streamHandle)
return EAS_PEResume(pEASData, streamHandle);
return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
}
/*----------------------------------------------------------------------------
* WaveSetData()
*----------------------------------------------------------------------------
* Purpose:
*
* Inputs:
* pEASData - pointer to EAS library instance data
* handle - pointer to S_WAVE_STATE for this stream
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT WaveSetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
{
S_WAVE_STATE *pWaveData = (S_WAVE_STATE*) pInstData;
switch (param)
{
/* set metadata callback */
case PARSER_DATA_METADATA_CB:
EAS_HWMemCpy(&pWaveData->metadata, (void*) value, sizeof(S_METADATA_CB));
return EAS_SUCCESS;
case PARSER_DATA_PLAYBACK_RATE:
value = (EAS_I32) (PITCH_CENTS_CONVERSION * log10((double) value / (double) (1 << 28)));
return EAS_PEUpdatePitch(pEASData, pWaveData->streamHandle, (EAS_I16) value);
case PARSER_DATA_VOLUME:
return EAS_PEUpdateVolume(pEASData, pWaveData->streamHandle, (EAS_I16) value);
default:
return EAS_ERROR_INVALID_PARAMETER;
}
}
/*----------------------------------------------------------------------------
* WaveGetData()
*----------------------------------------------------------------------------
* Purpose:
*
* Inputs:
* pEASData - pointer to EAS library instance data
* handle - pointer to S_WAVE_STATE for this stream
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
/*lint -esym(715, pEASData) reserved for future use */
static EAS_RESULT WaveGetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
{
S_WAVE_STATE *pWaveData;
pWaveData = (S_WAVE_STATE*) pInstData;
switch (param)
{
/* return file type as WAVE */
case PARSER_DATA_FILE_TYPE:
*pValue = pWaveData->fileType;
break;
#ifdef MMAPI_SUPPORT
/* return pointer to 'fmt' chunk */
case PARSER_DATA_FORMAT:
*pValue = (EAS_I32) pWaveData->fmtChunk;
break;
#endif
case PARSER_DATA_GAIN_OFFSET:
*pValue = WAVE_GAIN_OFFSET;
break;
default:
return EAS_ERROR_INVALID_PARAMETER;
}
return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
* WaveParseHeader()
*----------------------------------------------------------------------------
* Purpose:
* Parse the WAVE file header.
*
* Inputs:
* pEASData - pointer to EAS library instance data
* handle - pointer to S_WAVE_STATE for this stream
*
* Outputs:
*
*
* Side Effects:
*
*----------------------------------------------------------------------------
*/
static EAS_RESULT WaveParseHeader (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData)
{
S_PCM_OPEN_PARAMS params;
EAS_RESULT result;
EAS_U32 tag;
EAS_U32 fileSize;
EAS_U32 size;
EAS_I32 pos;
EAS_I32 audioOffset;
EAS_U16 usTemp;
EAS_BOOL parseDone;
EAS_U32 avgBytesPerSec;
/* init some data (and keep lint happy) */
params.sampleRate = 0;
params.size = 0;
audioOffset = 0;
params.decoder = 0;
params.blockSize = 0;
params.pCallbackFunc = NULL;
params.cbInstData = NULL;
params.loopSamples = 0;
params.fileHandle = fileHandle;
params.volume = 0x7fff;
params.envData = 0;
avgBytesPerSec = 8000;
/* check for 'RIFF' tag */
if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
return result;
if (tag != CHUNK_RIFF)
return EAS_ERROR_UNRECOGNIZED_FORMAT;
/* get size */
if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &fileSize, EAS_FALSE)) != EAS_FALSE)
return result;
/* check for 'WAVE' tag */
if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
return result;
if (tag != CHUNK_WAVE)
return EAS_ERROR_UNRECOGNIZED_FORMAT;
/* this is enough to say we recognize the file */
if (pWaveData == NULL)
return EAS_SUCCESS;
/* check for streaming mode */
pWaveData->flags = 0;
pWaveData->mediaLength = -1;
pWaveData->infoChunkPos = -1;
pWaveData->infoChunkSize = -1;
if (fileSize== FILE_SIZE_STREAMING)
{
pWaveData->flags |= PCM_FLAGS_STREAMING;
fileSize = 0x7fffffff;
}
/* find out where we're at */
if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
return result;
fileSize -= 4;
parseDone = EAS_FALSE;
for (;;)
{
/* get tag and size for next chunk */
if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
return result;
if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
return result;
/* process chunk */
pos += 8;
switch (tag)
{
case CHUNK_FMT:
#ifdef MMAPI_SUPPORT
if ((result = SaveFmtChunk(pEASData, fileHandle, pWaveData, (EAS_I32) size)) != EAS_SUCCESS)
return result;
#endif
/* get audio format */
if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
return result;
if (usTemp == WAVE_FORMAT_PCM)
{
params.decoder = EAS_DECODER_PCM;
pWaveData->fileType = EAS_FILE_WAVE_PCM;
}
else if (usTemp == WAVE_FORMAT_IMA_ADPCM)
{
params.decoder = EAS_DECODER_IMA_ADPCM;
pWaveData->fileType = EAS_FILE_WAVE_IMA_ADPCM;
}
else
return EAS_ERROR_UNRECOGNIZED_FORMAT;
/* get number of channels */
if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
return result;
if (usTemp == 2)
pWaveData->flags |= PCM_FLAGS_STEREO;
else if (usTemp != 1)
return EAS_ERROR_UNRECOGNIZED_FORMAT;
/* get sample rate */
if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &params.sampleRate, EAS_FALSE)) != EAS_FALSE)
return result;
/* get stream rate */
if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &avgBytesPerSec, EAS_FALSE)) != EAS_FALSE)
return result;
/* get block alignment */
if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
return result;
params.blockSize = usTemp;
/* get bits per sample */
if ((result = EAS_HWGetWord(pEASData->hwInstData, fileHandle, &usTemp, EAS_FALSE)) != EAS_FALSE)
return result;
/* PCM, must be 8 or 16 bit samples */
if (params.decoder == EAS_DECODER_PCM)
{
if (usTemp == 8)
pWaveData->flags |= PCM_FLAGS_8_BIT | PCM_FLAGS_UNSIGNED;
else if (usTemp != 16)
return EAS_ERROR_UNRECOGNIZED_FORMAT;
}
/* for IMA ADPCM, we only support mono 4-bit ADPCM */
else
{
if ((usTemp != 4) || (pWaveData->flags & PCM_FLAGS_STEREO))
return EAS_ERROR_UNRECOGNIZED_FORMAT;
}
break;
case CHUNK_DATA:
audioOffset = pos;
if (pWaveData->flags & PCM_FLAGS_STREAMING)
{
params.size = 0x7fffffff;
parseDone = EAS_TRUE;
}
else
{
params.size = (EAS_I32) size;
params.loopStart = size;
/* use more accurate method if possible */
if (size <= (0x7fffffff / 1000))
pWaveData->mediaLength = (EAS_I32) ((size * 1000) / avgBytesPerSec);
else
pWaveData->mediaLength = (EAS_I32) (size / (avgBytesPerSec / 1000));
}
break;
case CHUNK_LIST:
/* get the list type */
if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
return result;
if (tag == CHUNK_INFO)
{
pWaveData->infoChunkPos = pos + 4;
pWaveData->infoChunkSize = (EAS_I32) size - 4;
}
break;
default:
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
(char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
break;
}
if (parseDone)
break;
/* subtract header size */
fileSize -= 8;
/* account for zero-padding on odd length chunks */
if (size & 1)
size++;
/* this check works for files with odd length last chunk and no zero-pad */
if (size >= fileSize)
{
if (size > fileSize)
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: '%c%c%c%c' chunk size exceeds length of file or is not zero-padded\n",
(char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
break;
}
/* subtract size of data chunk (including any zero-pad) */
fileSize -= size;
/* seek to next chunk */
pos += (EAS_I32) size;
if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos)) != EAS_SUCCESS)
return result;
}
/* check for valid header */
if ((params.sampleRate == 0) || (params.size == 0))
return EAS_ERROR_UNRECOGNIZED_FORMAT;
/* save the pertinent information */
pWaveData->audioOffset = audioOffset;
params.flags = pWaveData->flags;
/* seek to data */
if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, audioOffset)) != EAS_SUCCESS)
return result;
/* open a stream in the PCM engine */
return EAS_PEOpenStream(pEASData, &params, &pWaveData->streamHandle);
}
/*----------------------------------------------------------------------------
* WaveGetMetaData()
*----------------------------------------------------------------------------
* Purpose:
* Process the INFO chunk and return metadata to host
*----------------------------------------------------------------------------
*/
static EAS_RESULT WaveGetMetaData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pMediaLength)
{
S_WAVE_STATE *pWaveData;
EAS_RESULT result;
EAS_I32 pos;
EAS_U32 size;
EAS_I32 infoSize;
EAS_U32 tag;
EAS_I32 restorePos;
E_EAS_METADATA_TYPE metaType;
EAS_I32 metaLen;
/* get current position so we can restore it */
pWaveData = (S_WAVE_STATE*) pInstData;
/* return media length */
*pMediaLength = pWaveData->mediaLength;
/* did we encounter an INFO chunk? */
if (pWaveData->infoChunkPos < 0)
return EAS_SUCCESS;
if ((result = EAS_HWFilePos(pEASData->hwInstData, pWaveData->fileHandle, &restorePos)) != EAS_SUCCESS)
return result;
/* offset to start of first chunk in INFO chunk */
pos = pWaveData->infoChunkPos;
infoSize = pWaveData->infoChunkSize;
/* read all the chunks in the INFO chunk */
for (;;)
{
/* seek to next chunk */
if ((result = EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, pos)) != EAS_SUCCESS)
return result;
/* get tag and size for next chunk */
if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &tag, EAS_TRUE)) != EAS_FALSE)
return result;
if ((result = EAS_HWGetDWord(pEASData->hwInstData, pWaveData->fileHandle, &size, EAS_FALSE)) != EAS_FALSE)
return result;
/* process chunk */
pos += 8;
metaType = EAS_METADATA_UNKNOWN;
switch (tag)
{
case CHUNK_INAM:
metaType = EAS_METADATA_TITLE;
break;
case CHUNK_IART:
metaType = EAS_METADATA_AUTHOR;
break;
case CHUNK_ICOP:
metaType = EAS_METADATA_COPYRIGHT;
break;
default:
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "WaveParseHeader: %c%c%c%c chunk - %d byte(s) ignored\n",
(char) (tag >> 24), (char) (tag >> 16), (char) (tag >> 8), (char) tag, size); */ }
break;
}
/* process known metadata */
if (metaType != EAS_METADATA_UNKNOWN)
{
metaLen = pWaveData->metadata.bufferSize - 1;
if (metaLen > (EAS_I32) size)
metaLen = (EAS_I32) size;
if ((result = EAS_HWReadFile(pEASData->hwInstData, pWaveData->fileHandle, pWaveData->metadata.buffer, metaLen, &metaLen)) != EAS_SUCCESS)
return result;
pWaveData->metadata.buffer[metaLen] = 0;
pWaveData->metadata.callback(metaType, pWaveData->metadata.buffer, pWaveData->metadata.pUserData);
}
/* subtract this block */
if (size & 1)
size++;
infoSize -= (EAS_I32) size + 8;
if (infoSize == 0)
break;
pos += (EAS_I32) size;
}
/* restore original position */
return EAS_HWFileSeek(pEASData->hwInstData, pWaveData->fileHandle, restorePos);
}
#ifdef MMAPI_SUPPORT
/*----------------------------------------------------------------------------
* SaveFmtChunk()
*----------------------------------------------------------------------------
* Purpose:
* Save the fmt chunk for the MMAPI library
*----------------------------------------------------------------------------
*/
static EAS_RESULT SaveFmtChunk (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, S_WAVE_STATE *pWaveData, EAS_I32 fmtSize)
{
EAS_RESULT result;
EAS_I32 pos;
EAS_I32 count;
/* save current file position */
if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &pos)) != EAS_SUCCESS)
return result;
/* allocate a chunk of memory */
pWaveData->fmtChunk = EAS_HWMalloc(pEASData->hwInstData, fmtSize);
if (!pWaveData->fmtChunk)
return EAS_ERROR_MALLOC_FAILED;
/* read the fmt chunk into memory */
if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, pWaveData->fmtChunk, fmtSize, &count)) != EAS_SUCCESS)
return result;
if (count != fmtSize)
return EAS_ERROR_FILE_READ_FAILED;
/* restore file position */
return EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pos);
}
#endif

View File

@@ -0,0 +1,63 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_wavefile.h
*
* Contents and purpose:
* Static data block for wave file 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: 439 $
* $Date: 2006-10-26 11:53:18 -0700 (Thu, 26 Oct 2006) $
*----------------------------------------------------------------------------
*/
#ifndef _EAS_WAVEFILE_H
#define _EAS_WAVEFILE_H
#include "eas_data.h"
#include "eas_pcm.h"
/*----------------------------------------------------------------------------
*
* S_WAVE_STATE
*
* This structure contains the WAVE file parser state information
*----------------------------------------------------------------------------
*/
typedef struct s_wave_state_tag
{
EAS_FILE_HANDLE fileHandle;
EAS_PCM_HANDLE streamHandle;
S_METADATA_CB metadata;
EAS_U32 time;
EAS_I32 fileOffset;
EAS_I32 audioOffset;
EAS_I32 mediaLength;
EAS_U32 audioSize;
EAS_U32 flags;
EAS_I16 fileType;
#ifdef MMAPI_SUPPORT
EAS_VOID_PTR fmtChunk;
#endif
EAS_I32 infoChunkPos;
EAS_I32 infoChunkSize;
} S_WAVE_STATE;
#endif

View File

@@ -0,0 +1,33 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_wavefiledata.c
*
* Contents and purpose:
* Static data block for wave file 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_wavefile.h"
S_WAVE_STATE eas_WaveData;

View File

@@ -0,0 +1,66 @@
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_fmengine.c \
lib_src/eas_fmsynth.c \
lib_src/eas_fmtables.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_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_wavefile.c \
lib_src/eas_wavefiledata.c \
lib_src/eas_wtengine.c \
lib_src/eas_wtsynth.c \
lib_src/hybrid_22khz_mcu.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
LOCAL_CFLAGS+= -O2 -D UNIFIED_DEBUG_MESSAGES -D EAS_HYBRID_SYNTH \
-D _IMELODY_PARSER -D _RTTTL_PARSER -D _OTA_PARSER \
-D _WAVE_PARSER -D _REVERB_ENABLED \
-D _CHORUS_ENABLED -D NUM_OUTPUT_CHANNELS=2 \
-D _SAMPLE_RATE_22050 -D MAX_SYNTH_VOICES=32 \
-D NUM_PRIMARY_VOICES=8 \
-D _8_BIT_SAMPLES -D _FILTER_ENABLED -D _IMELODY_PARSER \
-D _IMA_DECODER
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
include $(BUILD_SHARED_LIBRARY)

View File

@@ -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_HYBRID_SYNTH -D _IMELODY_PARSER -D _RTTTL_PARSER -D _OTA_PARSER -D _WAVE_PARSER -D _REVERB_ENABLED -D _CHORUS_ENABLED $<
%.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-hybrid-22k: $(OBJS)
$(LD) -o $@ $(OBJS) libarm-hybrid-22k.a -lm

File diff suppressed because it is too large Load Diff

View File

@@ -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_0cbd200ab054487f9ece7d3c8852e426_
#define _GUID_0cbd200ab054487f9ece7d3c8852e426_
#define _BUILD_VERSION_ "0cbd200a-b054-487f-9ece-7d3c8852e426"
#define _BUILD_TIME_ 0x4743b9dc
#endif /* _GUID_0cbd200ab054487f9ece7d3c8852e426_ */

View File

@@ -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

View File

@@ -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];
}

View File

@@ -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 */

View File

@@ -0,0 +1,44 @@
/* Auto-generated from source file: eas_chorusdata.c */
/* Auto-generated from source file: eas_imelodydata.c */
/* 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_voicemgt.c */
/* Auto-generated from source file: eas_ota.c */
/* Auto-generated from source file: eas_mixbuf.c */
/* Auto-generated from source file: eas_rtttl.c */
/* Auto-generated from source file: eas_reverb.c */
/* Auto-generated from source file: eas_fmsynth.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_fmengine.c */
/* Auto-generated from source file: eas_smfdata.c */
/* Auto-generated from source file: eas_fmtables.c */
/* Auto-generated from source file: eas_imelody.c */
/* Auto-generated from source file: eas_public.c */
/* Auto-generated from source file: eas_rtttldata.c */
/* Auto-generated from source file: eas_reverbdata.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_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" },
/* 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" },

View File

@@ -0,0 +1,83 @@
/*----------------------------------------------------------------------------
*
* 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);
/* 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 */

View File

@@ -0,0 +1,660 @@
/*----------------------------------------------------------------------------
*
* File:
* eas_hostmm.c
*
* Contents and purpose:
* This file contains the host wrapper functions for stdio, stdlib, etc.
* This is a sample version that maps the requested files to an
* allocated memory block and uses in-memory pointers to replace
* file system calls. The file locator (EAS_FILE_LOCATOR) handle passed
* HWOpenFile is the same one that is passed to EAS_OpenFile. If your
* system stores data in fixed locations (such as flash) instead of
* using a file system, you can use the locator handle to point to
* your memory. You will need a way of knowing the length of the
* data stored at that location in order to respond correctly in the
* HW_FileLength function.
*
* 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 base memory pointer, the file read pointer, and
* the dup flag, which when sets, indicates that the file handle has
* been duplicated. If your system uses in-memory resources, you
* can eliminate the duplicate handle logic, and simply copy the
* base memory pointer and file read pointer to the duplicate handle.
*
* 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>
#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;
EAS_U8 *buffer;
} EAS_HW_FILE;
typedef struct eas_hw_inst_data_tag
{
EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
} EAS_HW_INST_DATA;
/*----------------------------------------------------------------------------
* EAS_HWInit
*
* Initialize host wrapper interface
*
*----------------------------------------------------------------------------
*/
EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
{
/* 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));
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)
{
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)
{
return memcpy(dest, src, (size_t) amount);
}
/*----------------------------------------------------------------------------
*
* EAS_HWMemSet
*
* Set memory wrapper
*
*----------------------------------------------------------------------------
*/
void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
{
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)
{
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;
FILE *ioFile;
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->buffer == NULL)
{
/* open the file */
if ((ioFile = fopen(locator,"rb")) == NULL)
return EAS_ERROR_FILE_OPEN_FAILED;
/* determine the file size */
if (fseek(ioFile, 0L, SEEK_END) != 0)
return EAS_ERROR_FILE_LENGTH;
if ((file->fileSize = ftell(ioFile)) == -1L)
return EAS_ERROR_FILE_LENGTH;
if (fseek(ioFile, 0L, SEEK_SET) != 0)
return EAS_ERROR_FILE_LENGTH;
/* allocate a buffer */
file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
if (file->buffer == NULL)
{
fclose(ioFile);
return EAS_ERROR_MALLOC_FAILED;
}
/* read the file into memory */
temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
/* close the file - don't need it any more */
fclose(ioFile);
/* check for error reading file */
if (temp != 1)
return EAS_ERROR_FILE_READ_FAILED;
/* 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->buffer == NULL)
return EAS_ERROR_INVALID_HANDLE;
/* calculate the bytes to read */
count = file->fileSize - file->filePos;
if (n < count)
count = n;
/* copy the data to the requested location, and advance the pointer */
if (count)
EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], 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)
{
/* make sure we have a valid handle */
if (file->buffer == NULL)
return EAS_ERROR_INVALID_HANDLE;
/* check for end of file */
if (file->filePos >= file->fileSize)
{
*((EAS_U8*) p) = 0;
return EAS_EOF;
}
/* get a character from the buffer */
*((EAS_U8*) p) = file->buffer[file->filePos++];
return EAS_SUCCESS;
}
/*----------------------------------------------------------------------------
*
* EAS_HWGetWord
*
* Returns the current location in the 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->buffer == NULL)
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->buffer == NULL)
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->buffer == NULL)
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->buffer == NULL)
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->buffer == NULL)
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->buffer == NULL)
{
/* copy info from the handle to be duplicated */
dupFile->filePos = file->filePos;
dupFile->fileSize = file->fileSize;
dupFile->buffer = file->buffer;
/* 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->buffer == NULL)
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->buffer == file1->buffer))
{
/* is there more than one duplicate? */
if (dupFile != NULL)
{
/* clear this entry and return */
file1->buffer = NULL;
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->buffer = NULL;
return EAS_SUCCESS;
}
/* no duplicates -free the buffer */
EAS_HWFree(hwInstData, file1->buffer);
/* clear this entry and return */
file1->buffer = NULL;
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;
}

View File

@@ -0,0 +1,461 @@
/*----------------------------------------------------------------------------
*
* 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;
/* 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 */
if ((reportResult = EAS_OpenFile(easData, filename, &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 */

View File

@@ -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 */

Some files were not shown because too many files have changed in this diff Show More