import
This commit is contained in:
109
Player/arm7/source/Instrument.c
Normal file
109
Player/arm7/source/Instrument.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "Instrument.h"
|
||||
#include "Utils.h"
|
||||
#include <nds.h>
|
||||
|
||||
#define SOUND_PSG_DUTY(duty) ((duty)<<24)
|
||||
|
||||
void Instrument_Init(Instrument* pInstrument, int iChannel, InstrumentParameters* pParameters)
|
||||
{
|
||||
pInstrument->pParameters = pParameters;
|
||||
pInstrument->iChannel = iChannel;
|
||||
pInstrument->iLastFrequency = 0;
|
||||
pInstrument->pFrequencies[0] = 1;
|
||||
pInstrument->iFrequency = 0;
|
||||
pInstrument->iNbFrequencies = 0;
|
||||
pInstrument->iEffectTimer = 0;
|
||||
pInstrument->iSweepFrequency = 0;
|
||||
pInstrument->iModulationAmplitude = 0;
|
||||
pInstrument->iPortamentoFrequency = 0;
|
||||
pInstrument->iArpeggioTimer = 0;
|
||||
|
||||
Envelope_Init(&pInstrument->oEnvelope);
|
||||
}
|
||||
|
||||
void Instrument_Compute(Instrument* pInstrument)
|
||||
{
|
||||
InstrumentParameters* pParameters = pInstrument->pParameters;
|
||||
|
||||
int iVolume = pParameters->iVolume;
|
||||
|
||||
if ( pParameters->iTremoloAmplitude != 0 )
|
||||
{
|
||||
int iSin = Sinus(pInstrument->iEffectTimer * 12868 * pParameters->iTremoloFrequency / 256) / 2 + 2048;
|
||||
int iAmplitude = pParameters->iTremoloAmplitude * pParameters->iVolume / 255;
|
||||
iVolume -= iSin * iAmplitude / 4096;
|
||||
}
|
||||
|
||||
iVolume = Envelope_Compute(& pInstrument->oEnvelope, pParameters) * iVolume / 127;
|
||||
|
||||
if ( pParameters->iArpeggio > 0 )
|
||||
{
|
||||
pInstrument->iArpeggioTimer++;
|
||||
if ( pInstrument->iArpeggioTimer >= pParameters->iArpeggio )
|
||||
{
|
||||
pInstrument->iArpeggioTimer = 0;
|
||||
pInstrument->iFrequency++;
|
||||
if ( pInstrument->iFrequency >= pInstrument->iNbFrequencies )
|
||||
pInstrument->iFrequency = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pInstrument->iEffectTimer++;
|
||||
|
||||
int iSweep = 0;
|
||||
if ( pParameters->iSweepLength != 0
|
||||
&& pInstrument->iEffectTimer < pParameters->iSweepLength )
|
||||
iSweep = pInstrument->iSweepFrequency - (pInstrument->iEffectTimer * pInstrument->iSweepFrequency) / pParameters->iSweepLength;
|
||||
|
||||
int iModulation = Sinus(pInstrument->iEffectTimer * 12868 * pParameters->iModulationFrequency / 256) * pInstrument->iModulationAmplitude / 4096;
|
||||
|
||||
int iPortamento = 0;
|
||||
if ( pParameters->iPortamentoLength != 0 && pInstrument->iEffectTimer < pParameters->iPortamentoLength )
|
||||
iPortamento = pInstrument->iPortamentoFrequency - (pInstrument->iEffectTimer * pInstrument->iPortamentoFrequency) / pParameters->iPortamentoLength;
|
||||
|
||||
pInstrument->iLastFrequency = pInstrument->pFrequencies[pInstrument->iFrequency] + iSweep + iModulation + iPortamento;
|
||||
|
||||
if ( pInstrument->iLastFrequency <= 0 )
|
||||
pInstrument->iLastFrequency = 1;
|
||||
|
||||
SCHANNEL_CR(pInstrument->iChannel) = SCHANNEL_ENABLE
|
||||
| SOUND_VOL(iVolume)
|
||||
| SOUND_PAN(pParameters->iPanning)
|
||||
| SOUND_FORMAT_PSG
|
||||
| SOUND_PSG_DUTY(pParameters->iDuty)
|
||||
;
|
||||
SCHANNEL_TIMER(pInstrument->iChannel) = SOUND_FREQ(pInstrument->iLastFrequency * 8);
|
||||
}
|
||||
|
||||
void Instrument_NoteOn(Instrument* pInstrument, int iNote, int iVelocity)
|
||||
{
|
||||
int n = iNote + pInstrument->pParameters->iDetune;
|
||||
|
||||
Envelope_NoteOn(& pInstrument->oEnvelope, iVelocity);
|
||||
|
||||
if ( pInstrument->iEffectTimer < 3
|
||||
&& pInstrument->iNbFrequencies <= sizeof(pInstrument->pFrequencies)/sizeof(pInstrument->pFrequencies[0]) )
|
||||
{
|
||||
// Arpeggio !
|
||||
pInstrument->pFrequencies[pInstrument->iNbFrequencies++] = MidiNoteToFrequency(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
pInstrument->pFrequencies[0] = MidiNoteToFrequency(n);
|
||||
pInstrument->iNbFrequencies = 1;
|
||||
pInstrument->iArpeggioTimer = 0;
|
||||
pInstrument->iEffectTimer = 0;
|
||||
pInstrument->iFrequency = 0;
|
||||
if ( pInstrument->iLastFrequency == 0 )
|
||||
pInstrument->iLastFrequency = pInstrument->pFrequencies[0];
|
||||
pInstrument->iPortamentoFrequency = pInstrument->iLastFrequency - pInstrument->pFrequencies[0];
|
||||
pInstrument->iSweepFrequency = MidiNoteToFrequency(n + pInstrument->pParameters->iSweepOffset) - pInstrument->pFrequencies[0];
|
||||
pInstrument->iModulationAmplitude = MidiNoteToFrequency(n + pInstrument->pParameters->iModulationAmplitude) - pInstrument->pFrequencies[0];
|
||||
}
|
||||
}
|
||||
|
||||
void Instrument_NoteOff(Instrument* pInstrument)
|
||||
{
|
||||
Envelope_NoteOff(& pInstrument->oEnvelope);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user