mirror of
https://github.com/id-Software/DOOM-IOS2.git
synced 2026-03-20 08:59:35 +01:00
Initial Commit
This commit is contained in:
134
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/ARM-E_filter_gnu.s
Executable file
134
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/ARM-E_filter_gnu.s
Executable file
@@ -0,0 +1,134 @@
|
||||
@***********************************************************
|
||||
@ Function: WT_VoiceFilter
|
||||
@ Processor: ARM
|
||||
@ Description:
|
||||
@ Implements a 2-pole low-pass filter with resonanance
|
||||
@
|
||||
@ Usage:
|
||||
@ void WT_VoiceFilter(
|
||||
@ S_FILTER CONTROL *pFilter,
|
||||
@ S_WT_FRAME *pWTFrame);
|
||||
@
|
||||
@ Copyright 2005 Sonic Network, Inc.
|
||||
@****************************************************************
|
||||
@ Revision Control:
|
||||
@ $Revision: 496 $
|
||||
@ $Date: 2006-12-11 14:33:26 -0800 (Mon, 11 Dec 2006) $
|
||||
@****************************************************************
|
||||
@
|
||||
@ where:
|
||||
@ S_FILTER_CONTROL *pFilter
|
||||
@ PASSED IN: r0
|
||||
@
|
||||
@ S_WT_FRAME *pWTFrame
|
||||
@ PASSED IN: r1
|
||||
@****************************************************************
|
||||
|
||||
.include "ARM_synth_constants_gnu.inc"
|
||||
|
||||
.arm
|
||||
.text
|
||||
|
||||
|
||||
.global WT_VoiceFilter
|
||||
|
||||
|
||||
@ Register usage
|
||||
@ --------------
|
||||
pFilter .req r0
|
||||
pWTFrame .req r1
|
||||
pBuffer .req r2
|
||||
numSamples .req r3
|
||||
|
||||
z1 .req r4
|
||||
z2 .req r5
|
||||
b1 .req r6
|
||||
b2 .req r7
|
||||
K .req r8
|
||||
|
||||
tmp0 .req r1 @ reuse register
|
||||
tmp1 .req r9
|
||||
tmp2 .req r10
|
||||
|
||||
|
||||
@SaveRegs RLIST {r4-r10, lr}
|
||||
@RestoreRegs RLIST {r4-r10, pc}
|
||||
|
||||
|
||||
.func WT_VoiceFilter
|
||||
WT_VoiceFilter:
|
||||
|
||||
STMFD sp!, {r4-r10, lr}
|
||||
|
||||
@
|
||||
@ Setup passed parameters in their destination registers
|
||||
@----------------------------------------------------------------
|
||||
|
||||
LDR pBuffer, [pWTFrame, #m_pAudioBuffer]
|
||||
LDR numSamples, [pWTFrame, #m_numSamples]
|
||||
|
||||
@load state variables from pFilter structure
|
||||
LDRSH z1, [pFilter, #m_z1]
|
||||
LDRSH z2, [pFilter, #m_z2]
|
||||
|
||||
@load coefficients from pWTFrame structure
|
||||
LDR K, [pWTFrame, #m_k]
|
||||
LDR b1, [pWTFrame, #m_b1]
|
||||
LDR b2, [pWTFrame, #m_b2]
|
||||
|
||||
RSB b1, b1, #0 @ b1 = -b1
|
||||
RSB b2, b2, #0 @ b2 = -b2
|
||||
MOV b2, b2, ASR #1 @ b2 = b2 >> 1
|
||||
MOV K, K, ASR #1 @ K = K >> 1
|
||||
|
||||
@
|
||||
@ Start processing
|
||||
@----------------------------------------------------------------
|
||||
|
||||
LDRSH tmp0, [pBuffer] @ fetch sample
|
||||
|
||||
FilterLoop:
|
||||
SMULBB tmp2, z1, b1 @ tmp2 = z1 * -b1
|
||||
SMLABB tmp2, z2, b2, tmp2 @ tmp2 = (-b1 * z1) + (-b2 * z2)
|
||||
|
||||
MOV z2, z1 @ delay line
|
||||
|
||||
SMLABB tmp0, tmp0, K, tmp2 @ tmp1 = (K * x[n]) + (-b1 * z1) + (-b2 * z2)
|
||||
|
||||
LDRSH tmp1, [pBuffer, #NEXT_OUTPUT_PCM] @ fetch next sample
|
||||
|
||||
MOV z1, tmp0, ASR #14 @ shift result to low word
|
||||
STRH z1, [pBuffer], #NEXT_OUTPUT_PCM @ write back to buffer
|
||||
|
||||
SMULBB tmp2, z1, b1 @ tmp2 = z1 * -b1
|
||||
|
||||
SUBS numSamples, numSamples, #2 @ unroll loop once
|
||||
|
||||
SMLABB tmp2, z2, b2, tmp2 @ tmp2 = (-b1 * z1) + (-b2 * z2)
|
||||
|
||||
SMLABB tmp1, tmp1, K, tmp2 @ tmp1 = (K * x[n]) + (-b1 * z1) + (-b2 * z2)
|
||||
|
||||
MOV z2, z1 @ delay line
|
||||
|
||||
MOV z1, tmp1, ASR #14 @ shift result to low word
|
||||
|
||||
LDRGTSH tmp0, [pBuffer, #NEXT_OUTPUT_PCM] @ fetch next sample
|
||||
|
||||
STRH z1, [pBuffer], #NEXT_OUTPUT_PCM @ write back to buffer
|
||||
|
||||
BGT FilterLoop
|
||||
@ save z terms
|
||||
@----------------------------------------------------------------
|
||||
|
||||
STRH z1, [pFilter, #m_z1]
|
||||
STRH z2, [pFilter, #m_z2]
|
||||
|
||||
@ Return to calling function
|
||||
@----------------------------------------------------------------
|
||||
|
||||
LDMFD sp!,{r4-r10, lr}
|
||||
BX lr
|
||||
|
||||
.endfunc
|
||||
.end
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
@***********************************************************
|
||||
@ Function: WT_Interpolate
|
||||
@ Processor: ARM-E
|
||||
@ Description: the main synthesis function when fetching
|
||||
@ wavetable samples.
|
||||
@ C-callable.
|
||||
@
|
||||
@ Usage:
|
||||
@ void WT_Interpolate(
|
||||
@ S_WT_VOICE *pWTVoice,
|
||||
@ S_WT_FRAME *pWTFrame);
|
||||
@
|
||||
@ Copyright Sonic Network Inc. 2004
|
||||
@****************************************************************
|
||||
@ Revision Control:
|
||||
@ $Revision: 496 $
|
||||
@ $Date: 2006-12-11 14:33:26 -0800 (Mon, 11 Dec 2006) $
|
||||
@****************************************************************
|
||||
@
|
||||
@ where:
|
||||
@ S_WT_VOICE *pWTVoice
|
||||
@ PASSED IN: r0
|
||||
@
|
||||
@ S_WT_FRAME *pWTFrame;
|
||||
@ PASSED IN: r1
|
||||
@****************************************************************
|
||||
|
||||
.include "ARM_synth_constants_gnu.inc"
|
||||
|
||||
.arm
|
||||
.text
|
||||
|
||||
.global WT_Interpolate
|
||||
|
||||
|
||||
@ Register usage
|
||||
@ --------------
|
||||
pWTVoice .req r0
|
||||
pWTFrame .req r1
|
||||
|
||||
numSamples .req r2
|
||||
phaseIncrement .req r3
|
||||
pOutputBuffer .req r4
|
||||
|
||||
tmp0 .req r1 @reuse register
|
||||
tmp1 .req r5
|
||||
tmp2 .req r6
|
||||
|
||||
pLoopEnd .req r7
|
||||
pLoopStart .req r8
|
||||
|
||||
pPhaseAccum .req r9
|
||||
phaseFrac .req r10
|
||||
phaseFracMask .req r11
|
||||
|
||||
@SaveRegs RLIST {r4-r11,lr}
|
||||
@RestoreRegs RLIST {r4-r11,pc}
|
||||
|
||||
.func WT_Interpolate
|
||||
WT_Interpolate:
|
||||
|
||||
STMFD sp!,{r4-r11,lr}
|
||||
|
||||
@
|
||||
@ Fetch parameters from structures
|
||||
@----------------------------------------------------------------
|
||||
|
||||
LDR pOutputBuffer, [pWTFrame, #m_pAudioBuffer]
|
||||
LDR numSamples, [pWTFrame, #m_numSamples]
|
||||
|
||||
LDR phaseIncrement, [pWTFrame, #m_phaseIncrement]
|
||||
LDR pPhaseAccum, [pWTVoice, #m_pPhaseAccum]
|
||||
LDR phaseFrac, [pWTVoice, #m_phaseFrac]
|
||||
LDR phaseFracMask,=PHASE_FRAC_MASK
|
||||
|
||||
LDR pLoopStart, [pWTVoice, #m_pLoopStart]
|
||||
LDR pLoopEnd, [pWTVoice, #m_pLoopEnd]
|
||||
ADD pLoopEnd, pLoopEnd, #1 @ need loop end to equal last sample + 1
|
||||
|
||||
InterpolationLoop:
|
||||
SUBS tmp0, pPhaseAccum, pLoopEnd @ check for loop end
|
||||
ADDGE pPhaseAccum, pLoopStart, tmp0 @ loop back to start
|
||||
|
||||
.ifdef SAMPLES_8_BIT
|
||||
LDRSB tmp0, [pPhaseAccum] @ tmp0 = x0
|
||||
LDRSB tmp1, [pPhaseAccum, #1] @ tmp1 = x1
|
||||
.else
|
||||
LDRSH tmp0, [pPhaseAccum] @ tmp0 = x0
|
||||
LDRSH tmp1, [pPhaseAccum, #2] @ tmp1 = x1
|
||||
.endif
|
||||
|
||||
ADD tmp2, phaseIncrement, phaseFrac @ increment pointer here to avoid pipeline stall
|
||||
|
||||
SUB tmp1, tmp1, tmp0 @ tmp1 = x1 - x0
|
||||
SMULBB tmp1, phaseFrac, tmp1 @ tmp1 = phaseFrac * tmp2
|
||||
|
||||
@ This section performs a gain adjustment of -12dB for 16-bit samples
|
||||
@ or +36dB for 8-bit samples. For a high quality synthesizer, the output
|
||||
@ can be set to full scale, however if the filter is used, it can overflow
|
||||
@ with certain coefficients and signal sources. In this case, either a
|
||||
@ saturation operation should take in the filter before scaling back to
|
||||
@ 16 bits or the signal path should be increased to 18 bits or more.
|
||||
|
||||
.ifdef SAMPLES_8_BIT
|
||||
MOV tmp0, tmp0, LSL #6 @ boost 8-bit signal by 36dB
|
||||
.else
|
||||
MOV tmp0, tmp0, ASR #2 @ reduce 16-bit signal by 12dB
|
||||
.endif
|
||||
|
||||
ADD tmp1, tmp0, tmp1, ASR #(NUM_EG1_FRAC_BITS-6) @ tmp1 = tmp0 + (tmp1 >> (15-6))
|
||||
@ = x0 + f * (x1 - x0) == interpolated result
|
||||
|
||||
STRH tmp1, [pOutputBuffer], #NEXT_OUTPUT_PCM @ *pOutputBuffer++ = interpolated result
|
||||
|
||||
@ carry overflow from fraction to integer portion
|
||||
ADD pPhaseAccum, pPhaseAccum, tmp2, LSR #(NUM_PHASE_FRAC_BITS - NEXT_INPUT_PCM_SHIFT)
|
||||
AND phaseFrac, tmp2, phaseFracMask @ nphaseFrac = frac part
|
||||
|
||||
SUBS numSamples, numSamples, #1
|
||||
BGT InterpolationLoop
|
||||
|
||||
@ update and store phase
|
||||
STR pPhaseAccum, [pWTVoice, #m_pPhaseAccum]
|
||||
STR phaseFrac, [pWTVoice, #m_phaseFrac]
|
||||
|
||||
LDMFD sp!,{r4-r11,lr}
|
||||
BX lr
|
||||
|
||||
.endfunc
|
||||
.end
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
@***********************************************************
|
||||
@ Function: WT_InterpolateNoLoop
|
||||
@ Processor: ARM-E
|
||||
@ Description: the main synthesis function when fetching
|
||||
@ wavetable samples.
|
||||
@ C-callable.
|
||||
@
|
||||
@ Usage:
|
||||
@ void WT_InterpolateNoLoop(
|
||||
@ S_WT_VOICE *pWTVoice,
|
||||
@ S_WT_FRAME *pWTFrame);
|
||||
@
|
||||
@ Copyright Sonic Network Inc. 2004
|
||||
@****************************************************************
|
||||
@ Revision Control:
|
||||
@ $Revision: 496 $
|
||||
@ $Date: 2006-12-11 14:33:26 -0800 (Mon, 11 Dec 2006) $
|
||||
@****************************************************************
|
||||
@
|
||||
@ where:
|
||||
@ S_WT_VOICE *pWTVoice
|
||||
@ PASSED IN: r0
|
||||
@
|
||||
@ S_WT_FRAME *pWTFrame;
|
||||
@ PASSED IN: r1
|
||||
@****************************************************************
|
||||
|
||||
.include "ARM_synth_constants_gnu.inc"
|
||||
|
||||
.arm
|
||||
.text
|
||||
|
||||
|
||||
.global WT_InterpolateNoLoop
|
||||
|
||||
|
||||
@ Register usage
|
||||
@ --------------
|
||||
pWTVoice .req r0
|
||||
pWTFrame .req r1
|
||||
pOutputBuffer .req r2
|
||||
numSamples .req r3
|
||||
|
||||
phaseIncrement .req r4
|
||||
pPhaseAccum .req r5
|
||||
phaseFrac .req r6
|
||||
phaseFracMask .req r7
|
||||
|
||||
tmp0 .req r1 @ reuse register
|
||||
tmp1 .req r8
|
||||
tmp2 .req r9
|
||||
|
||||
|
||||
@SaveRegs RLIST {r4-r9,lr}
|
||||
@RestoreRegs RLIST {r4-r9,pc}
|
||||
|
||||
.func WT_InterpolateNoLoop
|
||||
WT_InterpolateNoLoop:
|
||||
|
||||
STMFD sp!, {r4-r9,lr}
|
||||
|
||||
@
|
||||
@ Fetch parameters from structures
|
||||
@----------------------------------------------------------------
|
||||
|
||||
LDR pOutputBuffer, [pWTFrame, #m_pAudioBuffer]
|
||||
LDR numSamples, [pWTFrame, #m_numSamples]
|
||||
|
||||
LDR phaseIncrement, [pWTFrame, #m_phaseIncrement]
|
||||
LDR pPhaseAccum, [pWTVoice, #m_pPhaseAccum]
|
||||
LDR phaseFrac, [pWTVoice, #m_phaseFrac]
|
||||
LDR phaseFracMask,=PHASE_FRAC_MASK
|
||||
|
||||
InterpolationLoop:
|
||||
|
||||
.ifdef SAMPLES_8_BIT
|
||||
LDRSB tmp0, [pPhaseAccum] @ tmp0 = x0
|
||||
LDRSB tmp1, [pPhaseAccum, #1] @ tmp1 = x1
|
||||
.else
|
||||
LDRSH tmp0, [pPhaseAccum] @ tmp0 = x0
|
||||
LDRSH tmp1, [pPhaseAccum, #2] @ tmp1 = x1
|
||||
.endif
|
||||
|
||||
ADD tmp2, phaseIncrement, phaseFrac @ increment pointer here to avoid pipeline stall
|
||||
|
||||
SUB tmp1, tmp1, tmp0 @ tmp1 = x1 - x0
|
||||
SMULBB tmp1, phaseFrac, tmp1 @ tmp1 = phaseFrac * tmp2
|
||||
|
||||
@ This section performs a gain adjustment of -12dB for 16-bit samples
|
||||
@ or +36dB for 8-bit samples. For a high quality synthesizer, the output
|
||||
@ can be set to full scale, however if the filter is used, it can overflow
|
||||
@ with certain coefficients and signal sources. In this case, either a
|
||||
@ saturation operation should take in the filter before scaling back to
|
||||
@ 16 bits or the signal path should be increased to 18 bits or more.
|
||||
|
||||
.ifdef SAMPLES_8_BIT
|
||||
MOV tmp0, tmp0, LSL #6 @ boost 8-bit signal by 36dB
|
||||
.else
|
||||
MOV tmp0, tmp0, ASR #2 @ reduce 16-bit signal by 12dB
|
||||
.endif
|
||||
|
||||
ADD tmp1, tmp0, tmp1, ASR #(NUM_EG1_FRAC_BITS-6) @ tmp1 = tmp0 + (tmp1 >> (15-6))
|
||||
@ = x0 + f * (x1 - x0) == interpolated result
|
||||
|
||||
STRH tmp1, [pOutputBuffer], #NEXT_OUTPUT_PCM @ *pOutputBuffer++ = interpolated result
|
||||
|
||||
@ carry overflow from fraction to integer portion
|
||||
ADD pPhaseAccum, pPhaseAccum, tmp2, LSR #(NUM_PHASE_FRAC_BITS - NEXT_INPUT_PCM_SHIFT)
|
||||
AND phaseFrac, tmp2, phaseFracMask @ nphaseFrac = frac part
|
||||
|
||||
SUBS numSamples, numSamples, #1
|
||||
BGT InterpolationLoop
|
||||
|
||||
@ Clean up and store any changes that were caused during the loop
|
||||
@----------------------------------------------------------------
|
||||
|
||||
@ update and store phase
|
||||
STR pPhaseAccum, [pWTVoice, #m_pPhaseAccum]
|
||||
STR phaseFrac, [pWTVoice, #m_phaseFrac]
|
||||
|
||||
@
|
||||
@ Return to calling function
|
||||
@----------------------------------------------------------------
|
||||
|
||||
LDMFD sp!,{r4-r9,lr}
|
||||
BX lr
|
||||
|
||||
.endfunc
|
||||
.end
|
||||
|
||||
109
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/ARM-E_mastergain_gnu.s
Executable file
109
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/ARM-E_mastergain_gnu.s
Executable file
@@ -0,0 +1,109 @@
|
||||
@***********************************************************
|
||||
@ Function: SynthMasterGain
|
||||
@ Processor: ARM-E
|
||||
@ Description: Copies 32-bit synth output to 16-bit buffer
|
||||
@ with saturated gain control
|
||||
@ C-callable.
|
||||
@
|
||||
@ Usage:
|
||||
@ SynthMasterGain(
|
||||
@ pInputBuffer
|
||||
@ pOutputBuffer,
|
||||
@ nGain,
|
||||
@ nNumLoopSamples
|
||||
@ );
|
||||
@
|
||||
@ Copyright Sonic Network Inc. 2004
|
||||
@****************************************************************
|
||||
@ Revision Control:
|
||||
@ $Revision: 496 $
|
||||
@ $Date: 2006-12-11 14:33:26 -0800 (Mon, 11 Dec 2006) $
|
||||
@****************************************************************
|
||||
@
|
||||
@ where:
|
||||
@ long *pInputBuffer
|
||||
@ PASSED IN: r0
|
||||
@
|
||||
@ EAS_PCM *pOutputBuffer
|
||||
@ PASSED IN: r1
|
||||
@
|
||||
@ short nGain
|
||||
@ PASSED IN: r2
|
||||
@
|
||||
@ EAS_U16 nNumLoopSamples
|
||||
@ PASSED IN: r3
|
||||
@
|
||||
@****************************************************************
|
||||
|
||||
.include "ARM_synth_constants_gnu.inc"
|
||||
|
||||
.arm
|
||||
.text
|
||||
|
||||
.func SynthMasterGain
|
||||
SynthMasterGain:
|
||||
|
||||
.global SynthMasterGain @ allow other files to use this function
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ Stack frame
|
||||
@ -----------
|
||||
.equ RET_ADDR_SZ, 0 @return address
|
||||
.equ REG_SAVE_SZ, 0 @save-on-entry registers saved
|
||||
.equ FRAME_SZ, (8) @local variables
|
||||
.equ ARG_BLK_SZ, 0 @argument block
|
||||
|
||||
.equ PARAM_OFFSET, (ARG_BLK_SZ + FRAME_SZ + REG_SAVE_SZ + RET_ADDR_SZ)
|
||||
|
||||
@ Register usage
|
||||
@ --------------
|
||||
pnInputBuffer .req r0
|
||||
pnOutputBuffer .req r1
|
||||
nGain .req r2
|
||||
nNumLoopSamples .req r3
|
||||
|
||||
STMFD sp!,{r4-r6,r14} @Save any save-on-entry registers that are used
|
||||
|
||||
LDR r6, =0x7fff @constant for saturation tests
|
||||
|
||||
loop:
|
||||
LDR r4, [pnInputBuffer], #4 @fetch 1st output sample
|
||||
|
||||
LDR r5, [pnInputBuffer], #4 @fetch 2nd output sample
|
||||
|
||||
SMULWB r4, r4, nGain @output = gain * input
|
||||
|
||||
CMP r4, r6 @check for positive saturation
|
||||
MOVGT r4, r6 @saturate
|
||||
CMN r4, r6 @check for negative saturation
|
||||
MVNLT r4, r6 @saturate
|
||||
|
||||
SMULWB r5, r5, nGain @output = gain * input
|
||||
|
||||
STRH r4, [pnOutputBuffer], #NEXT_OUTPUT_PCM @save 1st output sample
|
||||
|
||||
CMP r5, r6 @check for positive saturation
|
||||
MOVGT r5, r6 @saturate
|
||||
CMN r5, r6 @check for negative saturation
|
||||
MVNLT r5, r6 @saturate
|
||||
STRH r5, [pnOutputBuffer], #NEXT_OUTPUT_PCM @save 2nd output sample
|
||||
|
||||
SUBS nNumLoopSamples, nNumLoopSamples, #2
|
||||
BGT loop
|
||||
|
||||
@
|
||||
@ Return to calling function
|
||||
@----------------------------------------------------------------
|
||||
|
||||
LDMFD sp!,{r4-r6, lr} @ return to calling function
|
||||
BX lr
|
||||
|
||||
@*****************************************************************************
|
||||
|
||||
.endfunc @ end of function/procedure
|
||||
|
||||
.end @ end of assembly code
|
||||
|
||||
166
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/ARM-E_voice_gain_gnu.s
Executable file
166
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/ARM-E_voice_gain_gnu.s
Executable file
@@ -0,0 +1,166 @@
|
||||
@***********************************************************
|
||||
@ Function: WT_VoiceGain
|
||||
@ Processor: ARM-E
|
||||
@ Description: the main synthesis function when fetching
|
||||
@ wavetable samples.
|
||||
@ C-callable.
|
||||
@
|
||||
@ Usage:
|
||||
@ Usage:
|
||||
@ WT_VoiceGain(
|
||||
@ S_WT_VOICE *pWTVoice,
|
||||
@ S_WT_FRAME *pWTFrame);
|
||||
@
|
||||
@ Copyright 2004, 2005 Sonic Network, Inc.
|
||||
@****************************************************************
|
||||
@ Revision Control:
|
||||
@ $Revision: 814 $
|
||||
@ $Date: 2007-08-02 10:34:53 -0700 (Thu, 02 Aug 2007) $
|
||||
@****************************************************************
|
||||
@
|
||||
@ where:
|
||||
@ S_WT_VOICE *psVoice
|
||||
@ PASSED IN: r0
|
||||
@
|
||||
@ S_WT_FRAME *pWTFrame
|
||||
@ PASSED IN: r1
|
||||
@****************************************************************
|
||||
|
||||
|
||||
|
||||
.include "ARM_synth_constants_gnu.inc"
|
||||
|
||||
.arm
|
||||
.text
|
||||
|
||||
.global WT_VoiceGain
|
||||
|
||||
@ Register usage
|
||||
@ --------------
|
||||
pWTVoice .req r0
|
||||
pWTFrame .req r1
|
||||
pInputBuffer .req r2
|
||||
pMixBuffer .req r3
|
||||
|
||||
tmp0 .req r4
|
||||
tmp1 .req r5
|
||||
tmp2 .req r1 @ reuse register
|
||||
tmp3 .req r6
|
||||
|
||||
numSamples .req r9
|
||||
|
||||
.if STEREO_OUTPUT
|
||||
gainIncLeft .req r7
|
||||
gainIncRight .req r8
|
||||
gainLeft .req r10
|
||||
gainRight .req r11
|
||||
.else
|
||||
gainIncrement .req r7
|
||||
gain .req r8
|
||||
.endif
|
||||
|
||||
|
||||
@ register context for local variables
|
||||
@SaveRegs RLIST {r4-r11,lr}
|
||||
@RestoreRegs RLIST {r4-r11,pc}
|
||||
|
||||
.func WT_VoiceGain
|
||||
WT_VoiceGain:
|
||||
|
||||
STMFD sp!, {r4-r11,lr}
|
||||
|
||||
LDR pInputBuffer, [pWTFrame, #m_pAudioBuffer]
|
||||
LDR pMixBuffer, [pWTFrame, #m_pMixBuffer]
|
||||
LDR numSamples, [pWTFrame, #m_numSamples]
|
||||
|
||||
@----------------------------------------------------------------
|
||||
@ Stereo version
|
||||
@----------------------------------------------------------------
|
||||
@ NOTE: instructions are reordered to reduce the effect of latency
|
||||
@ due to storage and computational dependencies.
|
||||
@----------------------------------------------------------------
|
||||
|
||||
.if STEREO_OUTPUT
|
||||
|
||||
LDR tmp0, [pWTFrame, #m_prevGain]
|
||||
LDR tmp1, [pWTFrame, #m_gainTarget]
|
||||
|
||||
LDRSH gainLeft, [pWTVoice, #m_gainLeft]
|
||||
LDRSH gainRight, [pWTVoice, #m_gainRight]
|
||||
|
||||
MOV gainIncLeft, gainLeft
|
||||
SMULBB gainLeft, tmp0, gainLeft
|
||||
|
||||
SMULBB gainIncLeft, tmp1, gainIncLeft
|
||||
SUB gainIncLeft, gainIncLeft, gainLeft
|
||||
MOV gainLeft, gainLeft, ASR #(NUM_MIXER_GUARD_BITS - 2)
|
||||
MOV gainIncLeft, gainIncLeft, ASR #(SYNTH_UPDATE_PERIOD_IN_BITS + NUM_MIXER_GUARD_BITS - 2)
|
||||
|
||||
MOV gainIncRight, gainRight
|
||||
SMULBB gainRight, tmp0, gainRight
|
||||
|
||||
SMULBB gainIncRight, tmp1, gainIncRight
|
||||
SUB gainIncRight, gainIncRight, gainRight
|
||||
MOV gainRight, gainRight, ASR #(NUM_MIXER_GUARD_BITS - 2)
|
||||
MOV gainIncRight, gainIncRight, ASR #(SYNTH_UPDATE_PERIOD_IN_BITS + NUM_MIXER_GUARD_BITS - 2)
|
||||
|
||||
LDRSH tmp0, [pInputBuffer], #2
|
||||
|
||||
StereoGainLoop:
|
||||
LDR tmp1, [pMixBuffer]
|
||||
|
||||
ADD gainLeft, gainLeft, gainIncLeft
|
||||
|
||||
SMLAWB tmp1, gainLeft, tmp0, tmp1
|
||||
|
||||
LDR tmp2, [pMixBuffer, #4]
|
||||
|
||||
ADD gainRight, gainRight, gainIncRight
|
||||
|
||||
STR tmp1, [pMixBuffer], #4
|
||||
|
||||
SMLAWB tmp2, gainRight, tmp0, tmp2
|
||||
|
||||
SUBS numSamples, numSamples, #1
|
||||
|
||||
LDRGTSH tmp0, [pInputBuffer], #2
|
||||
|
||||
STR tmp2, [pMixBuffer], #4
|
||||
|
||||
BGT StereoGainLoop
|
||||
|
||||
@----------------------------------------------------------------
|
||||
@ Mono version
|
||||
@----------------------------------------------------------------
|
||||
.else
|
||||
|
||||
LDR gain, [pWTFrame, #m_prevGain]
|
||||
MOV gain, gain, LSL #(NUM_MIXER_GUARD_BITS + 4)
|
||||
LDR gainIncrement, [pWTFrame, #m_gainTarget]
|
||||
MOV gainIncrement, gainIncrement, LSL #(NUM_MIXER_GUARD_BITS + 4)
|
||||
SUB gainIncrement, gainIncrement, gain
|
||||
MOV gainIncrement, gainIncrement, ASR #SYNTH_UPDATE_PERIOD_IN_BITS
|
||||
|
||||
MonoGainLoop:
|
||||
|
||||
LDRSH tmp0, [pInputBuffer], #NEXT_OUTPUT_PCM @ fetch voice output
|
||||
|
||||
LDR tmp1, [pMixBuffer] @ get left channel output sample
|
||||
ADD gain, gain, gainIncrement @ gain step to eliminate zipper noise
|
||||
SMULWB tmp0, gain, tmp0 @ sample * local gain
|
||||
|
||||
MOV tmp0, tmp0, ASR #1 @ add 6dB headroom
|
||||
ADD tmp1, tmp0, tmp1
|
||||
STR tmp1, [pMixBuffer], #4 @ save and bump pointer
|
||||
|
||||
SUBS numSamples, numSamples, #1
|
||||
BGT MonoGainLoop
|
||||
|
||||
.endif @end Mono version
|
||||
|
||||
LDMFD sp!,{r4-r11,lr}
|
||||
BX lr
|
||||
|
||||
.endfunc
|
||||
.end
|
||||
|
||||
153
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/ARM_synth_constants_gnu.inc
Executable file
153
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/ARM_synth_constants_gnu.inc
Executable file
@@ -0,0 +1,153 @@
|
||||
@***********************************************************
|
||||
@ File: ARM_synth_constants.inc
|
||||
@ Processor: ARM
|
||||
@ Description: Contains constants and defines, most of which
|
||||
@ are mirrored in synth.h
|
||||
@
|
||||
@ Copyright Sonic Network Inc. 2004
|
||||
@****************************************************************
|
||||
@ Revision Control:
|
||||
@ $Revision: 741 $
|
||||
@ $Date: 2007-06-22 16:39:21 -0700 (Fri, 22 Jun 2007) $
|
||||
@****************************************************************
|
||||
|
||||
|
||||
.ifdef SAMPLE_RATE_8000
|
||||
.equ SYNTH_UPDATE_PERIOD_IN_BITS, 5
|
||||
.equ BUFFER_SIZE_IN_MONO_SAMPLES, 32
|
||||
.endif
|
||||
|
||||
.ifdef SAMPLE_RATE_16000
|
||||
.equ SYNTH_UPDATE_PERIOD_IN_BITS, 6
|
||||
.equ BUFFER_SIZE_IN_MONO_SAMPLES, 64
|
||||
.endif
|
||||
|
||||
.ifdef SAMPLE_RATE_20000
|
||||
.equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
|
||||
.equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
|
||||
.endif
|
||||
|
||||
.ifdef SAMPLE_RATE_22050
|
||||
.equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
|
||||
.equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
|
||||
.endif
|
||||
|
||||
.ifdef SAMPLE_RATE_24000
|
||||
.equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
|
||||
.equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
|
||||
.endif
|
||||
|
||||
.ifdef SAMPLE_RATE_32000
|
||||
.equ SYNTH_UPDATE_PERIOD_IN_BITS, 7
|
||||
.equ BUFFER_SIZE_IN_MONO_SAMPLES, 128
|
||||
.endif
|
||||
|
||||
.ifdef SAMPLE_RATE_44100
|
||||
.equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
|
||||
.equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
|
||||
.endif
|
||||
|
||||
.ifdef SAMPLE_RATE_48000
|
||||
.equ SYNTH_UPDATE_PERIOD_IN_BITS, 8
|
||||
.equ BUFFER_SIZE_IN_MONO_SAMPLES, 256
|
||||
.endif
|
||||
|
||||
|
||||
@ if the OUTPUT PCM sample is 16-bits, then when using indexed addressing,
|
||||
@ the next sample is this many bytes away
|
||||
.equ NEXT_OUTPUT_PCM, 2
|
||||
|
||||
@****************************************************************************
|
||||
@/* macros for fractional phase accumulator */
|
||||
.equ NUM_PHASE_FRAC_BITS, 15
|
||||
|
||||
.equ PHASE_FRAC_MASK, 0x7FFF
|
||||
|
||||
@ shift for phase accumulator when fraction carries over
|
||||
.ifdef SAMPLES_8_BIT
|
||||
.equ NEXT_INPUT_PCM_SHIFT, 0
|
||||
.endif
|
||||
|
||||
.ifdef SAMPLES_16_BIT
|
||||
.equ NEXT_INPUT_PCM_SHIFT, 1
|
||||
.endif
|
||||
|
||||
@****************************************************************************
|
||||
.equ NUM_MIXER_GUARD_BITS, 4
|
||||
|
||||
@****************************************************************************
|
||||
@/* Envelope 1 (EG1) calculation macros */
|
||||
.equ NUM_EG1_FRAC_BITS, 15
|
||||
|
||||
@****************************************************************************
|
||||
|
||||
.equ NUM_ENHANCER_FILTER_COEF_FRAC_BITS, 5
|
||||
|
||||
@****************************************************************************
|
||||
|
||||
@
|
||||
@ I've temporarily given up on the idea of getting ADS/RV and gcc to
|
||||
@ handle a struct in a compatible fashion. Switching to old fashion EQU
|
||||
@
|
||||
|
||||
.if FILTER_ENABLED
|
||||
@**************************************
|
||||
@ typedef struct s_filter_tag
|
||||
.equ m_z1, 0
|
||||
.equ m_z2, 2
|
||||
.endif
|
||||
|
||||
@**************************************
|
||||
@ typedef struct s_wt_frame_tag
|
||||
.equ m_gainTarget, 0
|
||||
.equ m_phaseIncrement, 4
|
||||
|
||||
.if FILTER_ENABLED
|
||||
.equ m_k, 8
|
||||
.equ m_b1, 12
|
||||
.equ m_b2, 16
|
||||
.equ m_pAudioBuffer, 20
|
||||
.equ m_pMixBuffer, 24
|
||||
.equ m_numSamples, 28
|
||||
.equ m_prevGain, 32
|
||||
.else
|
||||
.equ m_pAudioBuffer, 8
|
||||
.equ m_pMixBuffer, 12
|
||||
.equ m_numSamples, 16
|
||||
.equ m_prevGain, 20
|
||||
.endif
|
||||
|
||||
|
||||
@**************************************
|
||||
@ typedef struct s_wt_voice_tag
|
||||
.equ m_pLoopEnd, 0 @ /* points to last PCM sample (not 1 beyond last) */
|
||||
.equ m_pLoopStart, 4 @ /* points to first sample at start of loop */
|
||||
.equ m_pPhaseAccum, 8 @ /* points to first sample at start of loop */
|
||||
.equ m_phaseFrac, 12 @ /* points to first sample at start of loop */
|
||||
|
||||
.if STEREO_OUTPUT
|
||||
.equ m_gainLeft, 16 @ /* current gain, left ch */
|
||||
.equ m_gainRight, 18 @ /* current gain, right ch */
|
||||
.endif
|
||||
|
||||
|
||||
@****************************************************************************
|
||||
@ enhancer
|
||||
.equ m_nEnhancerFeedForward1, 0
|
||||
.equ m_nEnhancerFeedback1, 1
|
||||
.equ m_nDriveCoef, 2
|
||||
.equ m_nEnhancerFeedback2, 3
|
||||
.equ m_nWet, 4
|
||||
.equ m_nDry, 5
|
||||
|
||||
.equ m_zF0L, 6 @ filter 1 zero state var, left
|
||||
.equ m_zF1L, 8 @ filter 1 pole state var, left
|
||||
.equ m_zF2L, 10 @ filter 2 zero state var, left
|
||||
.equ m_zF0R, 12 @ filter 1 zero state var, right
|
||||
.equ m_zF1R, 14 @ filter 1 pole state var, right
|
||||
.equ m_zF2R, 16 @ filter 2 zero state var, right
|
||||
|
||||
@****************************************************************************
|
||||
|
||||
|
||||
|
||||
25
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/arm-hybrid-22k_lib.mak
Executable file
25
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/arm-hybrid-22k_lib.mak
Executable 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=32 -D NUM_PRIMARY_VOICES=8 -D EAS_HYBRID_SYNTH -D _8_BIT_SAMPLES -D _FILTER_ENABLED -D _IMELODY_PARSER -D _RTTTL_PARSER -D _OTA_PARSER -D _WAVE_PARSER -D _REVERB_ENABLED -D _CHORUS_ENABLED -D _IMA_DECODER -D NATIVE_EAS_KERNEL $<
|
||||
|
||||
%.o: %.s
|
||||
$(AS) -o $@ -EL -mcpu=arm946e-s -mfpu=softfpa -I lib_src --defsym CHECK_STACK=0 --defsym REVERB=0 --defsym CHORUS=0 --defsym STEREO_OUTPUT=1 --defsym SAMPLE_RATE_22050=1 --defsym SAMPLES_8_BIT=1 --defsym FILTER_ENABLED=1 $<
|
||||
|
||||
OBJS = eas_mididata.o eas_pan.o eas_wavefiledata.o eas_wavefile.o eas_smfdata.o eas_imelody.o eas_math.o eas_fmengine.o ARM-E_filter_gnu.o eas_chorusdata.o eas_wtengine.o eas_ota.o eas_rtttldata.o eas_reverbdata.o eas_public.o ARM-E_interpolate_loop_gnu.o eas_rtttl.o eas_reverb.o ARM-E_voice_gain_gnu.o eas_fmsynth.o eas_midi.o eas_otadata.o eas_wtsynth.o eas_mixbuf.o eas_imaadpcm.o hybrid_22khz_mcu.o eas_smf.o eas_chorus.o eas_pcm.o eas_mixer.o eas_data.o eas_imelodydata.o eas_pcmdata.o eas_ima_tables.o eas_fmtables.o ARM-E_interpolate_noloop_gnu.o ARM-E_mastergain_gnu.o eas_voicemgt.o
|
||||
|
||||
arm-hybrid-22k.a: $(OBJS)
|
||||
$(AR) rc lib$@ $(OBJS)
|
||||
|
||||
97
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_audioconst.h
Executable file
97
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_audioconst.h
Executable 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 */
|
||||
|
||||
604
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_chorus.c
Executable file
604
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_chorus.c
Executable 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 */
|
||||
34
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_chorusdata.c
Executable file
34
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_chorusdata.c
Executable 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;
|
||||
|
||||
160
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_chorusdata.h
Executable file
160
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_chorusdata.h
Executable 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 */
|
||||
|
||||
|
||||
41
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_ctype.h
Executable file
41
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_ctype.h
Executable 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
|
||||
|
||||
37
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_data.c
Executable file
37
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_data.c
Executable 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;
|
||||
|
||||
131
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_data.h
Executable file
131
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_data.h
Executable 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
|
||||
|
||||
61
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_effects.h
Executable file
61
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_effects.h
Executable 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 */
|
||||
|
||||
785
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_fmengine.c
Executable file
785
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_fmengine.c
Executable 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;
|
||||
}
|
||||
|
||||
121
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_fmengine.h
Executable file
121
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_fmengine.h
Executable 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 */
|
||||
|
||||
910
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_fmsynth.c
Executable file
910
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_fmsynth.c
Executable 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;
|
||||
}
|
||||
|
||||
81
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_fmsynth.h
Executable file
81
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_fmsynth.h
Executable 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
|
||||
368
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_fmtables.c
Executable file
368
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_fmtables.c
Executable 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
|
||||
|
||||
54
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_ima_tables.c
Executable file
54
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_ima_tables.c
Executable 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
|
||||
};
|
||||
|
||||
368
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_imaadpcm.c
Executable file
368
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_imaadpcm.c
Executable 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;
|
||||
}
|
||||
|
||||
1738
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_imelody.c
Executable file
1738
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_imelody.c
Executable file
File diff suppressed because it is too large
Load Diff
43
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_imelodydata.c
Executable file
43
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_imelodydata.c
Executable 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;
|
||||
|
||||
73
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_imelodydata.h
Executable file
73
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_imelodydata.h
Executable 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
|
||||
|
||||
|
||||
168
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_math.c
Executable file
168
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_math.c
Executable 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);
|
||||
}
|
||||
|
||||
412
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_math.h
Executable file
412
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_math.h
Executable 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
|
||||
|
||||
569
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_midi.c
Executable file
569
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_midi.c
Executable 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 */
|
||||
|
||||
71
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_midi.h
Executable file
71
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_midi.h
Executable 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 */
|
||||
|
||||
64
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_midictrl.h
Executable file
64
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_midictrl.h
Executable 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 */
|
||||
34
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_mididata.c
Executable file
34
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_mididata.c
Executable 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;
|
||||
|
||||
138
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_miditypes.h
Executable file
138
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_miditypes.h
Executable 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 */
|
||||
|
||||
36
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_mixbuf.c
Executable file
36
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_mixbuf.c
Executable 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];
|
||||
|
||||
464
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_mixer.c
Executable file
464
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_mixer.c
Executable 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
|
||||
|
||||
137
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_mixer.h
Executable file
137
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_mixer.h
Executable 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 */
|
||||
|
||||
1077
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_ota.c
Executable file
1077
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_ota.c
Executable file
File diff suppressed because it is too large
Load Diff
41
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_otadata.c
Executable file
41
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_otadata.c
Executable 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;
|
||||
|
||||
81
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_otadata.h
Executable file
81
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_otadata.h
Executable 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
|
||||
|
||||
|
||||
98
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pan.c
Executable file
98
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pan.c
Executable 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;
|
||||
}
|
||||
|
||||
66
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pan.h
Executable file
66
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pan.h
Executable 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
|
||||
|
||||
98
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_parser.h
Executable file
98
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_parser.h
Executable 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 */
|
||||
1482
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pcm.c
Executable file
1482
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pcm.c
Executable file
File diff suppressed because it is too large
Load Diff
359
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pcm.h
Executable file
359
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pcm.h
Executable 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 */
|
||||
|
||||
35
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pcmdata.c
Executable file
35
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pcmdata.c
Executable 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];
|
||||
|
||||
|
||||
157
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pcmdata.h
Executable file
157
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_pcmdata.h
Executable 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 */
|
||||
|
||||
2597
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_public.c
Executable file
2597
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_public.c
Executable file
File diff suppressed because it is too large
Load Diff
1154
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_reverb.c
Executable file
1154
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_reverb.c
Executable file
File diff suppressed because it is too large
Load Diff
34
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_reverbdata.c
Executable file
34
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_reverbdata.c
Executable 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;
|
||||
|
||||
486
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_reverbdata.h
Executable file
486
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_reverbdata.h
Executable 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 */
|
||||
|
||||
|
||||
1197
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_rtttl.c
Executable file
1197
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_rtttl.c
Executable file
File diff suppressed because it is too large
Load Diff
41
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_rtttldata.c
Executable file
41
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_rtttldata.c
Executable 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;
|
||||
|
||||
70
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_rtttldata.h
Executable file
70
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_rtttldata.h
Executable 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
|
||||
|
||||
|
||||
1203
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_smf.c
Executable file
1203
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_smf.c
Executable file
File diff suppressed because it is too large
Load Diff
49
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_smf.h
Executable file
49
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_smf.h
Executable 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 */
|
||||
|
||||
|
||||
66
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_smfdata.c
Executable file
66
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_smfdata.c
Executable 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 */
|
||||
};
|
||||
|
||||
66
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_smfdata.h
Executable file
66
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_smfdata.h
Executable 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
|
||||
|
||||
406
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_sndlib.h
Executable file
406
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_sndlib.h
Executable 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
|
||||
|
||||
395
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_synth.h
Executable file
395
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_synth.h
Executable 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 */
|
||||
|
||||
|
||||
60
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_synth_protos.h
Executable file
60
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_synth_protos.h
Executable 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
|
||||
|
||||
|
||||
|
||||
70
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_synthcfg.h
Executable file
70
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_synthcfg.h
Executable 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
|
||||
|
||||
1086
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_vm_protos.h
Executable file
1086
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_vm_protos.h
Executable file
File diff suppressed because it is too large
Load Diff
3971
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_voicemgt.c
Executable file
3971
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_voicemgt.c
Executable file
File diff suppressed because it is too large
Load Diff
867
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wavefile.c
Executable file
867
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wavefile.c
Executable 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, ¶ms.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, ¶ms, &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
|
||||
|
||||
63
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wavefile.h
Executable file
63
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wavefile.h
Executable 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
|
||||
|
||||
33
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wavefiledata.c
Executable file
33
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wavefiledata.c
Executable 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;
|
||||
|
||||
82
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wt_IPC_frame.h
Executable file
82
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wt_IPC_frame.h
Executable file
@@ -0,0 +1,82 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* File:
|
||||
* eas_wt_IPC_frame.h
|
||||
*
|
||||
* Contents and purpose:
|
||||
* This module contains data definitions for the interprocessor
|
||||
* communications framework for a split-architecture synthesizer.
|
||||
*
|
||||
* This sample version writes IPC data to a file that can be used
|
||||
* as a test vector for the DSP simulator. For a real-time system
|
||||
* the file I/O is replaced with an IPC protocol in the hardware.
|
||||
*
|
||||
* Synchronization with the DSP is accomplished at the API level,
|
||||
* i.e. the host code should call EAS_Render when it is ready to
|
||||
* buffer another block of data for transmission to the DSP.
|
||||
*
|
||||
* 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: 818 $
|
||||
* $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _EAS_WT_IPC_FRAME_H
|
||||
#define _EAS_WT_IPC_FRAME_H
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* S_WT_FRAME
|
||||
*
|
||||
* This structure contains the common parameters that are updated
|
||||
*for each frame of audio.
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
typedef struct s_wt_frame_tag
|
||||
{
|
||||
EAS_I32 gainTarget;
|
||||
EAS_I32 phaseIncrement;
|
||||
|
||||
#if defined(_FILTER_ENABLED)
|
||||
EAS_I32 k;
|
||||
EAS_I32 b1;
|
||||
EAS_I32 b2;
|
||||
#endif
|
||||
} S_WT_FRAME;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* S_WT_CONFIG
|
||||
*
|
||||
* This structure contains state data for the wavetable engine
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
typedef struct s_wt_config_tag
|
||||
{
|
||||
EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */
|
||||
EAS_U32 loopStart; /* points to first sample at start of loop */
|
||||
EAS_U32 phaseAccum; /* current sample, integer portion of phase */
|
||||
|
||||
#if (NUM_OUTPUT_CHANNELS == 2)
|
||||
EAS_I16 gainLeft; /* left channel gain */
|
||||
EAS_I16 gainRight; /* right channel gain */
|
||||
#endif
|
||||
|
||||
EAS_I16 gain; /* current voice gain */
|
||||
} S_WT_CONFIG;
|
||||
|
||||
#endif
|
||||
|
||||
661
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wtengine.c
Executable file
661
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wtengine.c
Executable file
@@ -0,0 +1,661 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* File:
|
||||
* eas_wtengine.c
|
||||
*
|
||||
* Contents and purpose:
|
||||
* This file contains the critical synthesizer components that need to
|
||||
* be optimized for best performance.
|
||||
*
|
||||
* 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: 844 $
|
||||
* $Date: 2007-08-23 14:33:32 -0700 (Thu, 23 Aug 2007) $
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------
|
||||
* includes
|
||||
*------------------------------------
|
||||
*/
|
||||
#include "eas_types.h"
|
||||
#include "eas_math.h"
|
||||
#include "eas_audioconst.h"
|
||||
#include "eas_sndlib.h"
|
||||
#include "eas_wtengine.h"
|
||||
#include "eas_mixer.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* prototypes
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
extern void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
|
||||
extern void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
|
||||
|
||||
#if defined(_OPTIMIZED_MONO)
|
||||
extern void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
|
||||
#else
|
||||
extern void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
|
||||
extern void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
|
||||
#endif
|
||||
|
||||
#if defined(_FILTER_ENABLED)
|
||||
extern void WT_VoiceFilter (S_FILTER_CONTROL*pFilter, S_WT_INT_FRAME *pWTIntFrame);
|
||||
#endif
|
||||
|
||||
#if defined(_OPTIMIZED_MONO) || !defined(NATIVE_EAS_KERNEL)
|
||||
/*----------------------------------------------------------------------------
|
||||
* WT_VoiceGain
|
||||
*----------------------------------------------------------------------------
|
||||
* Purpose:
|
||||
* Output gain for individual voice
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
/*lint -esym(715, pWTVoice) reserved for future use */
|
||||
void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
|
||||
{
|
||||
EAS_I32 *pMixBuffer;
|
||||
EAS_PCM *pInputBuffer;
|
||||
EAS_I32 gain;
|
||||
EAS_I32 gainIncrement;
|
||||
EAS_I32 tmp0;
|
||||
EAS_I32 tmp1;
|
||||
EAS_I32 tmp2;
|
||||
EAS_I32 numSamples;
|
||||
|
||||
#if (NUM_OUTPUT_CHANNELS == 2)
|
||||
EAS_I32 gainLeft, gainRight;
|
||||
#endif
|
||||
|
||||
/* initialize some local variables */
|
||||
numSamples = pWTIntFrame->numSamples;
|
||||
pMixBuffer = pWTIntFrame->pMixBuffer;
|
||||
pInputBuffer = pWTIntFrame->pAudioBuffer;
|
||||
|
||||
/*lint -e{703} <avoid multiply for performance>*/
|
||||
gainIncrement = (pWTIntFrame->frame.gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
|
||||
if (gainIncrement < 0)
|
||||
gainIncrement++;
|
||||
/*lint -e{703} <avoid multiply for performance>*/
|
||||
gain = pWTIntFrame->prevGain << 16;
|
||||
|
||||
#if (NUM_OUTPUT_CHANNELS == 2)
|
||||
gainLeft = pWTVoice->gainLeft;
|
||||
gainRight = pWTVoice->gainRight;
|
||||
#endif
|
||||
|
||||
while (numSamples--) {
|
||||
|
||||
/* incremental gain step to prevent zipper noise */
|
||||
tmp0 = *pInputBuffer++;
|
||||
gain += gainIncrement;
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
tmp2 = gain >> 16;
|
||||
|
||||
/* scale sample by gain */
|
||||
tmp2 *= tmp0;
|
||||
|
||||
|
||||
/* stereo output */
|
||||
#if (NUM_OUTPUT_CHANNELS == 2)
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
tmp2 = tmp2 >> 14;
|
||||
|
||||
/* get the current sample in the final mix buffer */
|
||||
tmp1 = *pMixBuffer;
|
||||
|
||||
/* left channel */
|
||||
tmp0 = tmp2 * gainLeft;
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
|
||||
tmp1 += tmp0;
|
||||
*pMixBuffer++ = tmp1;
|
||||
|
||||
/* get the current sample in the final mix buffer */
|
||||
tmp1 = *pMixBuffer;
|
||||
|
||||
/* right channel */
|
||||
tmp0 = tmp2 * gainRight;
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
tmp0 = tmp0 >> NUM_MIXER_GUARD_BITS;
|
||||
tmp1 += tmp0;
|
||||
*pMixBuffer++ = tmp1;
|
||||
|
||||
/* mono output */
|
||||
#else
|
||||
|
||||
/* get the current sample in the final mix buffer */
|
||||
tmp1 = *pMixBuffer;
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
tmp2 = tmp2 >> (NUM_MIXER_GUARD_BITS - 1);
|
||||
tmp1 += tmp2;
|
||||
*pMixBuffer++ = tmp1;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NATIVE_EAS_KERNEL
|
||||
/*----------------------------------------------------------------------------
|
||||
* WT_Interpolate
|
||||
*----------------------------------------------------------------------------
|
||||
* Purpose:
|
||||
* Interpolation engine for wavetable synth
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
|
||||
{
|
||||
EAS_PCM *pOutputBuffer;
|
||||
EAS_I32 phaseInc;
|
||||
EAS_I32 phaseFrac;
|
||||
EAS_I32 acc0;
|
||||
const EAS_SAMPLE *pSamples;
|
||||
const EAS_SAMPLE *loopEnd;
|
||||
EAS_I32 samp1;
|
||||
EAS_I32 samp2;
|
||||
EAS_I32 numSamples;
|
||||
|
||||
/* initialize some local variables */
|
||||
numSamples = pWTIntFrame->numSamples;
|
||||
pOutputBuffer = pWTIntFrame->pAudioBuffer;
|
||||
|
||||
loopEnd = (const EAS_SAMPLE*) pWTVoice->loopEnd + 1;
|
||||
pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
|
||||
/*lint -e{713} truncation is OK */
|
||||
phaseFrac = pWTVoice->phaseFrac;
|
||||
phaseInc = pWTIntFrame->frame.phaseIncrement;
|
||||
|
||||
/* fetch adjacent samples */
|
||||
#if defined(_8_BIT_SAMPLES)
|
||||
/*lint -e{701} <avoid multiply for performance>*/
|
||||
samp1 = pSamples[0] << 8;
|
||||
/*lint -e{701} <avoid multiply for performance>*/
|
||||
samp2 = pSamples[1] << 8;
|
||||
#else
|
||||
samp1 = pSamples[0];
|
||||
samp2 = pSamples[1];
|
||||
#endif
|
||||
|
||||
while (numSamples--) {
|
||||
|
||||
/* linear interpolation */
|
||||
acc0 = samp2 - samp1;
|
||||
acc0 = acc0 * phaseFrac;
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
|
||||
|
||||
/* save new output sample in buffer */
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
*pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
|
||||
|
||||
/* increment phase */
|
||||
phaseFrac += phaseInc;
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
|
||||
|
||||
/* next sample */
|
||||
if (acc0 > 0) {
|
||||
|
||||
/* advance sample pointer */
|
||||
pSamples += acc0;
|
||||
phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
|
||||
|
||||
/* check for loop end */
|
||||
acc0 = (EAS_I32) (pSamples - loopEnd);
|
||||
if (acc0 >= 0)
|
||||
pSamples = (const EAS_SAMPLE*) pWTVoice->loopStart + acc0;
|
||||
|
||||
/* fetch new samples */
|
||||
#if defined(_8_BIT_SAMPLES)
|
||||
/*lint -e{701} <avoid multiply for performance>*/
|
||||
samp1 = pSamples[0] << 8;
|
||||
/*lint -e{701} <avoid multiply for performance>*/
|
||||
samp2 = pSamples[1] << 8;
|
||||
#else
|
||||
samp1 = pSamples[0];
|
||||
samp2 = pSamples[1];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* save pointer and phase */
|
||||
pWTVoice->phaseAccum = (EAS_U32) pSamples;
|
||||
pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NATIVE_EAS_KERNEL
|
||||
/*----------------------------------------------------------------------------
|
||||
* WT_InterpolateNoLoop
|
||||
*----------------------------------------------------------------------------
|
||||
* Purpose:
|
||||
* Interpolation engine for wavetable synth
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
|
||||
{
|
||||
EAS_PCM *pOutputBuffer;
|
||||
EAS_I32 phaseInc;
|
||||
EAS_I32 phaseFrac;
|
||||
EAS_I32 acc0;
|
||||
const EAS_SAMPLE *pSamples;
|
||||
EAS_I32 samp1;
|
||||
EAS_I32 samp2;
|
||||
EAS_I32 numSamples;
|
||||
|
||||
/* initialize some local variables */
|
||||
numSamples = pWTIntFrame->numSamples;
|
||||
pOutputBuffer = pWTIntFrame->pAudioBuffer;
|
||||
|
||||
phaseInc = pWTIntFrame->frame.phaseIncrement;
|
||||
pSamples = (const EAS_SAMPLE*) pWTVoice->phaseAccum;
|
||||
phaseFrac = (EAS_I32)pWTVoice->phaseFrac;
|
||||
|
||||
/* fetch adjacent samples */
|
||||
#if defined(_8_BIT_SAMPLES)
|
||||
/*lint -e{701} <avoid multiply for performance>*/
|
||||
samp1 = pSamples[0] << 8;
|
||||
/*lint -e{701} <avoid multiply for performance>*/
|
||||
samp2 = pSamples[1] << 8;
|
||||
#else
|
||||
samp1 = pSamples[0];
|
||||
samp2 = pSamples[1];
|
||||
#endif
|
||||
|
||||
while (numSamples--) {
|
||||
|
||||
|
||||
/* linear interpolation */
|
||||
acc0 = samp2 - samp1;
|
||||
acc0 = acc0 * phaseFrac;
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
acc0 = samp1 + (acc0 >> NUM_PHASE_FRAC_BITS);
|
||||
|
||||
/* save new output sample in buffer */
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
*pOutputBuffer++ = (EAS_I16)(acc0 >> 2);
|
||||
|
||||
/* increment phase */
|
||||
phaseFrac += phaseInc;
|
||||
/*lint -e{704} <avoid divide>*/
|
||||
acc0 = phaseFrac >> NUM_PHASE_FRAC_BITS;
|
||||
|
||||
/* next sample */
|
||||
if (acc0 > 0) {
|
||||
|
||||
/* advance sample pointer */
|
||||
pSamples += acc0;
|
||||
phaseFrac = (EAS_I32)((EAS_U32)phaseFrac & PHASE_FRAC_MASK);
|
||||
|
||||
/* fetch new samples */
|
||||
#if defined(_8_BIT_SAMPLES)
|
||||
/*lint -e{701} <avoid multiply for performance>*/
|
||||
samp1 = pSamples[0] << 8;
|
||||
/*lint -e{701} <avoid multiply for performance>*/
|
||||
samp2 = pSamples[1] << 8;
|
||||
#else
|
||||
samp1 = pSamples[0];
|
||||
samp2 = pSamples[1];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* save pointer and phase */
|
||||
pWTVoice->phaseAccum = (EAS_U32) pSamples;
|
||||
pWTVoice->phaseFrac = (EAS_U32) phaseFrac;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_FILTER_ENABLED) && !defined(NATIVE_EAS_KERNEL)
|
||||
/*----------------------------------------------------------------------------
|
||||
* WT_VoiceFilter
|
||||
*----------------------------------------------------------------------------
|
||||
* Purpose:
|
||||
* Implements a 2-pole filter
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
void WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame)
|
||||
{
|
||||
EAS_PCM *pAudioBuffer;
|
||||
EAS_I32 k;
|
||||
EAS_I32 b1;
|
||||
EAS_I32 b2;
|
||||
EAS_I32 z1;
|
||||
EAS_I32 z2;
|
||||
EAS_I32 acc0;
|
||||
EAS_I32 acc1;
|
||||
EAS_I32 numSamples;
|
||||
|
||||
/* initialize some local variables */
|
||||
numSamples = pWTIntFrame->numSamples;
|
||||
pAudioBuffer = pWTIntFrame->pAudioBuffer;
|
||||
|
||||
z1 = pFilter->z1;
|
||||
z2 = pFilter->z2;
|
||||
b1 = -pWTIntFrame->frame.b1;
|
||||
|
||||
/*lint -e{702} <avoid divide> */
|
||||
b2 = -pWTIntFrame->frame.b2 >> 1;
|
||||
|
||||
/*lint -e{702} <avoid divide> */
|
||||
k = pWTIntFrame->frame.k >> 1;
|
||||
|
||||
while (numSamples--)
|
||||
{
|
||||
|
||||
/* do filter calculations */
|
||||
acc0 = *pAudioBuffer;
|
||||
acc1 = z1 * b1;
|
||||
acc1 += z2 * b2;
|
||||
acc0 = acc1 + k * acc0;
|
||||
z2 = z1;
|
||||
|
||||
/*lint -e{702} <avoid divide> */
|
||||
z1 = acc0 >> 14;
|
||||
*pAudioBuffer++ = (EAS_I16) z1;
|
||||
}
|
||||
|
||||
/* save delay values */
|
||||
pFilter->z1 = (EAS_I16) z1;
|
||||
pFilter->z2 = (EAS_I16) z2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* WT_NoiseGenerator
|
||||
*----------------------------------------------------------------------------
|
||||
* Purpose:
|
||||
* Generate pseudo-white noise using PRNG and interpolation engine
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* Notes:
|
||||
* This output is scaled -12dB to prevent saturation in the filter. For a
|
||||
* high quality synthesizer, the output can be set to full scale, however
|
||||
* if the filter is used, it can overflow with certain coefficients. In this
|
||||
* case, either a saturation operation should take in the filter before
|
||||
* scaling back to 16 bits or the signal path should be increased to 18 bits
|
||||
* or more.
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
void WT_NoiseGenerator (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
|
||||
{
|
||||
EAS_PCM *pOutputBuffer;
|
||||
EAS_I32 phaseInc;
|
||||
EAS_I32 tmp0;
|
||||
EAS_I32 tmp1;
|
||||
EAS_I32 nInterpolatedSample;
|
||||
EAS_I32 numSamples;
|
||||
|
||||
/* initialize some local variables */
|
||||
numSamples = pWTIntFrame->numSamples;
|
||||
pOutputBuffer = pWTIntFrame->pAudioBuffer;
|
||||
phaseInc = pWTIntFrame->frame.phaseIncrement;
|
||||
|
||||
/* get last two samples generated */
|
||||
/*lint -e{704} <avoid divide for performance>*/
|
||||
tmp0 = (EAS_I32) (pWTVoice->phaseAccum) >> 18;
|
||||
/*lint -e{704} <avoid divide for performance>*/
|
||||
tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
|
||||
|
||||
/* generate a buffer of noise */
|
||||
while (numSamples--) {
|
||||
nInterpolatedSample = MULT_AUDIO_COEF( tmp0, (PHASE_ONE - pWTVoice->phaseFrac));
|
||||
nInterpolatedSample += MULT_AUDIO_COEF( tmp1, pWTVoice->phaseFrac);
|
||||
*pOutputBuffer++ = (EAS_PCM) nInterpolatedSample;
|
||||
|
||||
/* update PRNG */
|
||||
pWTVoice->phaseFrac += (EAS_U32) phaseInc;
|
||||
if (GET_PHASE_INT_PART(pWTVoice->phaseFrac)) {
|
||||
tmp0 = tmp1;
|
||||
pWTVoice->phaseAccum = pWTVoice->loopEnd;
|
||||
pWTVoice->loopEnd = (5 * pWTVoice->loopEnd + 1);
|
||||
tmp1 = (EAS_I32) (pWTVoice->loopEnd) >> 18;
|
||||
pWTVoice->phaseFrac = GET_PHASE_FRAC_PART(pWTVoice->phaseFrac);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _OPTIMIZED_MONO
|
||||
/*----------------------------------------------------------------------------
|
||||
* WT_ProcessVoice
|
||||
*----------------------------------------------------------------------------
|
||||
* Purpose:
|
||||
* This routine does the block processing for one voice. It is isolated
|
||||
* from the main synth code to allow for various implementation-specific
|
||||
* optimizations. It calls the interpolator, filter, and gain routines
|
||||
* appropriate for a particular configuration.
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* Notes:
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
|
||||
{
|
||||
|
||||
/* use noise generator */
|
||||
if (pWTVoice->loopStart == WT_NOISE_GENERATOR)
|
||||
WT_NoiseGenerator(pWTVoice, pWTIntFrame);
|
||||
|
||||
/* generate interpolated samples for looped waves */
|
||||
else if (pWTVoice->loopStart != pWTVoice->loopEnd)
|
||||
WT_Interpolate(pWTVoice, pWTIntFrame);
|
||||
|
||||
/* generate interpolated samples for unlooped waves */
|
||||
else
|
||||
{
|
||||
WT_InterpolateNoLoop(pWTVoice, pWTIntFrame);
|
||||
}
|
||||
|
||||
#ifdef _FILTER_ENABLED
|
||||
if (pWTIntFrame->frame.k != 0)
|
||||
WT_VoiceFilter(&pWTVoice->filter, pWTIntFrame);
|
||||
#endif
|
||||
|
||||
//2 TEST NEW MIXER FUNCTION
|
||||
#ifdef UNIFIED_MIXER
|
||||
{
|
||||
EAS_I32 gainLeft, gainIncLeft;
|
||||
|
||||
#if (NUM_OUTPUT_CHANNELS == 2)
|
||||
EAS_I32 gainRight, gainIncRight;
|
||||
#endif
|
||||
|
||||
gainLeft = (pWTIntFrame->prevGain * pWTVoice->gainLeft) << 1;
|
||||
gainIncLeft = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainLeft) << 1) - gainLeft) >> SYNTH_UPDATE_PERIOD_IN_BITS;
|
||||
|
||||
#if (NUM_OUTPUT_CHANNELS == 2)
|
||||
gainRight = (pWTIntFrame->prevGain * pWTVoice->gainRight) << 1;
|
||||
gainIncRight = (((pWTIntFrame->frame.gainTarget * pWTVoice->gainRight) << 1) - gainRight) >> SYNTH_UPDATE_PERIOD_IN_BITS;
|
||||
EAS_MixStream(
|
||||
pWTIntFrame->pAudioBuffer,
|
||||
pWTIntFrame->pMixBuffer,
|
||||
pWTIntFrame->numSamples,
|
||||
gainLeft,
|
||||
gainRight,
|
||||
gainIncLeft,
|
||||
gainIncRight,
|
||||
MIX_FLAGS_STEREO_OUTPUT);
|
||||
|
||||
#else
|
||||
EAS_MixStream(
|
||||
pWTIntFrame->pAudioBuffer,
|
||||
pWTIntFrame->pMixBuffer,
|
||||
pWTIntFrame->numSamples,
|
||||
gainLeft,
|
||||
0,
|
||||
gainIncLeft,
|
||||
0,
|
||||
0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
/* apply gain, and left and right gain */
|
||||
WT_VoiceGain(pWTVoice, pWTIntFrame);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_OPTIMIZED_MONO) && !defined(NATIVE_EAS_KERNEL)
|
||||
/*----------------------------------------------------------------------------
|
||||
* WT_InterpolateMono
|
||||
*----------------------------------------------------------------------------
|
||||
* Purpose:
|
||||
* A C version of the sample interpolation + gain routine, optimized for mono.
|
||||
* It's not pretty, but it matches the assembly code exactly.
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* Notes:
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
|
||||
{
|
||||
EAS_I32 *pMixBuffer;
|
||||
const EAS_I8 *pLoopEnd;
|
||||
const EAS_I8 *pCurrentPhaseInt;
|
||||
EAS_I32 numSamples;
|
||||
EAS_I32 gain;
|
||||
EAS_I32 gainIncrement;
|
||||
EAS_I32 currentPhaseFrac;
|
||||
EAS_I32 phaseInc;
|
||||
EAS_I32 tmp0;
|
||||
EAS_I32 tmp1;
|
||||
EAS_I32 tmp2;
|
||||
EAS_I8 *pLoopStart;
|
||||
|
||||
numSamples = pWTIntFrame->numSamples;
|
||||
pMixBuffer = pWTIntFrame->pMixBuffer;
|
||||
|
||||
/* calculate gain increment */
|
||||
gainIncrement = (pWTIntFrame->gainTarget - pWTIntFrame->prevGain) << (16 - SYNTH_UPDATE_PERIOD_IN_BITS);
|
||||
if (gainIncrement < 0)
|
||||
gainIncrement++;
|
||||
gain = pWTIntFrame->prevGain << 16;
|
||||
|
||||
pCurrentPhaseInt = pWTVoice->pPhaseAccum;
|
||||
currentPhaseFrac = pWTVoice->phaseFrac;
|
||||
phaseInc = pWTIntFrame->phaseIncrement;
|
||||
|
||||
pLoopStart = pWTVoice->pLoopStart;
|
||||
pLoopEnd = pWTVoice->pLoopEnd + 1;
|
||||
|
||||
InterpolationLoop:
|
||||
tmp0 = (EAS_I32)(pCurrentPhaseInt - pLoopEnd);
|
||||
if (tmp0 >= 0)
|
||||
pCurrentPhaseInt = pLoopStart + tmp0;
|
||||
|
||||
tmp0 = *pCurrentPhaseInt;
|
||||
tmp1 = *(pCurrentPhaseInt + 1);
|
||||
|
||||
tmp2 = phaseInc + currentPhaseFrac;
|
||||
|
||||
tmp1 = tmp1 - tmp0;
|
||||
tmp1 = tmp1 * currentPhaseFrac;
|
||||
|
||||
tmp1 = tmp0 + (tmp1 >> NUM_EG1_FRAC_BITS);
|
||||
|
||||
pCurrentPhaseInt += (tmp2 >> NUM_PHASE_FRAC_BITS);
|
||||
currentPhaseFrac = tmp2 & PHASE_FRAC_MASK;
|
||||
|
||||
gain += gainIncrement;
|
||||
tmp2 = (gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
|
||||
|
||||
tmp0 = *pMixBuffer;
|
||||
tmp2 = tmp1 * tmp2;
|
||||
tmp2 = (tmp2 >> 9);
|
||||
tmp0 = tmp2 + tmp0;
|
||||
*pMixBuffer++ = tmp0;
|
||||
|
||||
numSamples--;
|
||||
if (numSamples)
|
||||
goto InterpolationLoop;
|
||||
|
||||
pWTVoice->pPhaseAccum = pCurrentPhaseInt;
|
||||
pWTVoice->phaseFrac = currentPhaseFrac;
|
||||
/*lint -e{702} <avoid divide>*/
|
||||
pWTVoice->gain = (EAS_I16)(gain >> SYNTH_UPDATE_PERIOD_IN_BITS);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _OPTIMIZED_MONO
|
||||
/*----------------------------------------------------------------------------
|
||||
* WT_ProcessVoice
|
||||
*----------------------------------------------------------------------------
|
||||
* Purpose:
|
||||
* This routine does the block processing for one voice. It is isolated
|
||||
* from the main synth code to allow for various implementation-specific
|
||||
* optimizations. It calls the interpolator, filter, and gain routines
|
||||
* appropriate for a particular configuration.
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* Notes:
|
||||
* This special version works handles an optimized mono-only signal
|
||||
* without filters
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame)
|
||||
{
|
||||
|
||||
/* use noise generator */
|
||||
if (pWTVoice->loopStart== WT_NOISE_GENERATOR)
|
||||
{
|
||||
WT_NoiseGenerator(pWTVoice, pWTIntFrame);
|
||||
WT_VoiceGain(pWTVoice, pWTIntFrame);
|
||||
}
|
||||
|
||||
/* or generate interpolated samples */
|
||||
else
|
||||
{
|
||||
WT_InterpolateMono(pWTVoice, pWTIntFrame);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
171
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wtengine.h
Executable file
171
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wtengine.h
Executable file
@@ -0,0 +1,171 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* File:
|
||||
* eas_wtengine.h
|
||||
*
|
||||
* Contents and purpose:
|
||||
* This file defines the interface for wavetable synthesis engine
|
||||
*
|
||||
* 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: 818 $
|
||||
* $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _EAS_WTENGINE_H
|
||||
#define _EAS_WTENGINE_H
|
||||
|
||||
/* option sanity check */
|
||||
#if defined(_OPTIMIZED_MONO) && defined(_FILTER_ENABLED)
|
||||
#error "Incompatible build settings: _OPTIMIZED_MONO cannot be used with _FILTER_ENABLED"
|
||||
#endif
|
||||
|
||||
#if defined(_OPTIMIZED_MONO) && (NUM_OUTPUT_CHANNELS != 1)
|
||||
#error "Incompatible build settings: _OPTIMIZED_MONO can only be used with NUM_OUTPUT_CHANNELS = 1"
|
||||
#endif
|
||||
|
||||
#include "eas_wt_IPC_frame.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* defines
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
#define WT_NOISE_GENERATOR 0xffffffff
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* typedefs
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* S_WT_INT_FRAME
|
||||
*
|
||||
* This structure includes S_WT_FRAME plus the bus mixing
|
||||
* parameters for the internal voices.
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
typedef struct s_wt_int_frame_tag
|
||||
{
|
||||
S_WT_FRAME frame;
|
||||
EAS_PCM *pAudioBuffer;
|
||||
EAS_I32 *pMixBuffer;
|
||||
EAS_I32 numSamples;
|
||||
EAS_I32 prevGain;
|
||||
} S_WT_INT_FRAME;
|
||||
|
||||
#if defined(_FILTER_ENABLED)
|
||||
/*----------------------------------------------------------------------------
|
||||
* S_FILTER_CONTROL data structure
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
typedef struct s_filter_control_tag
|
||||
{
|
||||
EAS_I16 z1; /* 1 sample delay state variable */
|
||||
EAS_I16 z2; /* 2 sample delay state variable */
|
||||
} S_FILTER_CONTROL;
|
||||
#endif
|
||||
|
||||
/*------------------------------------
|
||||
* S_LFO_CONTROL data structure
|
||||
*------------------------------------
|
||||
*/
|
||||
typedef struct s_lfo_control_tag
|
||||
{
|
||||
EAS_I16 lfoValue; /* LFO current output value */
|
||||
EAS_I16 lfoPhase; /* LFO current phase */
|
||||
} S_LFO_CONTROL;
|
||||
|
||||
/* bit definitions for S_WT_VOICE:flags */
|
||||
#define WT_FLAGS_ADPCM_NIBBLE 1 /* high/low nibble flag */
|
||||
#define WT_FLAGS_ADPCM_READY 2 /* first 2 samples are decoded */
|
||||
#define WT_FLAGS_USE_ADPCM 4 /* sample is ADPCM encoded */
|
||||
|
||||
/* eg1State and eg2State */
|
||||
typedef enum {
|
||||
eEnvelopeStateInit = 0,
|
||||
eEnvelopeStateDelay,
|
||||
eEnvelopeStateAttack,
|
||||
eEnvelopeStateHold,
|
||||
eEnvelopeStateDecay,
|
||||
eEnvelopeStateSustain,
|
||||
eEnvelopeStateRelease,
|
||||
eEnvelopeStateMuting,
|
||||
eEnvelopeStateMuted,
|
||||
eEnvelopeStateInvalid /* should never be in this state! */
|
||||
} E_ENVELOPE_STATE;
|
||||
|
||||
#define DEFAULT_EG1_STATE eEnvelopeStateAttack
|
||||
#define DEFAULT_EG1_VALUE 0
|
||||
#define DEFAULT_EG1_INCREMENT 0
|
||||
#define DEFAULT_EG2_STATE eEnvelopeStateAttack
|
||||
#define DEFAULT_EG2_VALUE 0
|
||||
#define DEFAULT_EG2_INCREMENT 0
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* S_WT_VOICE
|
||||
*
|
||||
* This structure contains state data for the wavetable engine
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
typedef struct s_wt_voice_tag
|
||||
{
|
||||
EAS_U32 loopEnd; /* points to last PCM sample (not 1 beyond last) */
|
||||
EAS_U32 loopStart; /* points to first sample at start of loop */
|
||||
EAS_U32 phaseAccum; /* current sample, integer portion of phase */
|
||||
EAS_U32 phaseFrac; /* fractional portion of phase */
|
||||
|
||||
#if (NUM_OUTPUT_CHANNELS == 2)
|
||||
EAS_I16 gainLeft; /* current gain, left ch */
|
||||
EAS_I16 gainRight; /* current gain, right ch */
|
||||
#endif
|
||||
|
||||
#if defined(_FILTER_ENABLED)
|
||||
S_FILTER_CONTROL filter; /* low pass filter */
|
||||
#endif
|
||||
|
||||
S_LFO_CONTROL modLFO; /* modulator LFO */
|
||||
|
||||
#ifdef DLS_SYNTHESIZER
|
||||
S_LFO_CONTROL vibLFO; /* vibrato LFO */
|
||||
#endif
|
||||
|
||||
/* envelope control */
|
||||
EAS_I16 eg1Value;
|
||||
EAS_I16 eg2Value;
|
||||
EAS_I16 eg1Increment;
|
||||
EAS_I16 eg2Increment;
|
||||
EAS_U8 eg1State;
|
||||
EAS_U8 eg2State;
|
||||
|
||||
EAS_U16 artIndex; /* index to articulation params */
|
||||
|
||||
} S_WT_VOICE;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* prototypes
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, EAS_BOOL update);
|
||||
void WT_ProcessVoice (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame);
|
||||
|
||||
#ifdef EAS_SPLIT_WT_SYNTH
|
||||
void WTE_ConfigVoice (EAS_I32 voiceNum, S_WT_CONFIG *pWTConfig, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
|
||||
void WTE_ProcessVoice (EAS_I32 voiceNum, S_WT_FRAME *pWTParams, EAS_FRAME_BUFFER_HANDLE pFrameBuffer);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1251
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wtsynth.c
Executable file
1251
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wtsynth.c
Executable file
File diff suppressed because it is too large
Load Diff
66
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wtsynth.h
Executable file
66
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/eas_wtsynth.h
Executable file
@@ -0,0 +1,66 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* File:
|
||||
* eas_wtsynth.h
|
||||
*
|
||||
* Contents and purpose:
|
||||
* This file defines the interface for synthesizer engine
|
||||
*
|
||||
* 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_WTSYNTH_H
|
||||
#define _EAS_WTSYNTH_H
|
||||
|
||||
#include "eas_sndlib.h"
|
||||
#include "eas_wtengine.h"
|
||||
|
||||
/* adjust the filter cutoff frequency to the sample rate */
|
||||
#if defined (_SAMPLE_RATE_8000)
|
||||
#define FILTER_CUTOFF_FREQ_ADJUST 0
|
||||
#elif defined (_SAMPLE_RATE_16000)
|
||||
#define FILTER_CUTOFF_FREQ_ADJUST 1200
|
||||
#elif defined (_SAMPLE_RATE_20000)
|
||||
#define FILTER_CUTOFF_FREQ_ADJUST 1586
|
||||
#elif defined (_SAMPLE_RATE_22050)
|
||||
#define FILTER_CUTOFF_FREQ_ADJUST 1756
|
||||
#elif defined (_SAMPLE_RATE_24000)
|
||||
#define FILTER_CUTOFF_FREQ_ADJUST 1902
|
||||
#elif defined (_SAMPLE_RATE_32000)
|
||||
#define FILTER_CUTOFF_FREQ_ADJUST 2400
|
||||
#elif defined (_SAMPLE_RATE_44100)
|
||||
#define FILTER_CUTOFF_FREQ_ADJUST 2956
|
||||
#elif defined (_SAMPLE_RATE_48000)
|
||||
#define FILTER_CUTOFF_FREQ_ADJUST 3102
|
||||
#else
|
||||
#error "_SAMPLE_RATE_XXXXX must be defined to valid rate"
|
||||
#endif
|
||||
|
||||
/* function prototypes */
|
||||
void WT_UpdateLFO (S_LFO_CONTROL *pLFO, EAS_I16 phaseInc);
|
||||
|
||||
#if defined(_FILTER_ENABLED) || defined(DLS_SYNTHESIZER)
|
||||
void WT_SetFilterCoeffs (S_WT_INT_FRAME *pIntFrame, EAS_I32 cutoff, EAS_I32 resonance);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
5149
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/hybrid_22khz_mcu.c
Executable file
5149
common/embeddedaudiosynthesis/arm-hybrid-22k/lib_src/hybrid_22khz_mcu.c
Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user