windows-nt/Source/XPSP1/NT/multimedia/directx/dmusic/dmsynth/mixc.cpp
2020-09-26 16:20:57 +08:00

229 lines
5.2 KiB
C++

// Mixc.cpp
// Copyright (c) Microsoft Corporation 1996-1999
// C version of the Mix Engine
#include "simple.h"
#include <mmsystem.h>
#include "synth.h"
#pragma warning(disable : 4101 4102 4146)
DWORD CDigitalAudio::Mix16(
short **ppBuffers,
DWORD *pdwChannels,
DWORD dwBufferCount,
DWORD dwLength,
DWORD dwDeltaPeriod,
VFRACT vfDeltaLVolume,
VFRACT vfDeltaRVolume,
PFRACT pfDeltaPitch,
PFRACT pfSampleLength,
PFRACT pfLoopLength)
{
DWORD dwI;
DWORD dwIndex;
DWORD dwPosition;
long lA;
long lM;
DWORD dwIncDelta = dwDeltaPeriod;
VFRACT dwFract;
short * pcWave = m_pnWave;
PFRACT pfSamplePos = m_pfLastSample;
VFRACT vfLVolume = m_vfLastLVolume;
VFRACT vfRVolume = m_vfLastRVolume;
PFRACT pfPitch = m_pfLastPitch;
PFRACT pfPFract = pfPitch << 8;
VFRACT vfLVFract = vfLVolume << 8;
VFRACT vfRVFract = vfRVolume << 8;
for (dwI = 0; dwI < dwLength;)
{
if (pfSamplePos >= pfSampleLength)
{
if (pfLoopLength)
{
pfSamplePos -= pfLoopLength;
}
else
break;
}
dwIncDelta--;
if (!dwIncDelta)
{
dwIncDelta = dwDeltaPeriod;
pfPFract += pfDeltaPitch;
pfPitch = pfPFract >> 8;
vfLVFract += vfDeltaLVolume;
vfLVolume = vfLVFract >> 8;
vfRVFract += vfDeltaRVolume;
vfRVolume = vfRVFract >> 8;
}
dwPosition = pfSamplePos >> 12;
dwFract = pfSamplePos & 0xFFF;
pfSamplePos += pfPitch;
// Interpolate
lA = (long)pcWave[dwPosition];
lM = (((pcWave[dwPosition+1] - lA) * dwFract) >> 12) + lA;
lA = lM;
lA *= vfLVolume;
lA >>= 13; // Signal bumps up to 15 bits.
lM *= vfRVolume;
lM >>= 13;
dwIndex = 0;
while ( dwIndex < dwBufferCount )
{
short *pBuffer = &ppBuffers[dwIndex][dwI];
if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_LEFT )
{
// Keep this around so we can use it to generate new assembly code (see below...)
*pBuffer += (short) lA;
_asm{jno no_oflowl}
*pBuffer = 0x7fff;
_asm{js no_oflowl}
*pBuffer = (short) 0x8000;
}
no_oflowl:
if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_RIGHT )
{
// Keep this around so we can use it to generate new assembly code (see below...)
*pBuffer += (short) lM;
_asm{jno no_oflowr}
*pBuffer = 0x7fff;
_asm{js no_oflowr}
*pBuffer = (short) 0x8000;
}
no_oflowr:
dwIndex++;
}
dwI++;
}
m_vfLastLVolume = vfLVolume;
m_vfLastRVolume = vfRVolume;
m_pfLastPitch = pfPitch;
m_pfLastSample = pfSamplePos;
return (dwI);
}
DWORD CDigitalAudio::Mix16InterLeaved(
short **ppBuffers,
DWORD *pdwChannels,
DWORD dwBufferCount,
DWORD dwLength,
DWORD dwDeltaPeriod,
VFRACT vfDeltaLVolume,
VFRACT vfDeltaRVolume,
PFRACT pfDeltaPitch,
PFRACT pfSampleLength,
PFRACT pfLoopLength)
{
DWORD dwI;
DWORD dwIndex;
DWORD dwPosition;
long lA;
long lM;
DWORD dwIncDelta = dwDeltaPeriod;
VFRACT dwFract;
short * pcWave = m_pnWave;
PFRACT pfSamplePos = m_pfLastSample;
VFRACT vfLVolume = m_vfLastLVolume;
VFRACT vfRVolume = m_vfLastRVolume;
PFRACT pfPitch = m_pfLastPitch;
PFRACT pfPFract = pfPitch << 8;
VFRACT vfLVFract = vfLVolume << 8;
VFRACT vfRVFract = vfRVolume << 8;
dwLength <<= 1;
for (dwI = 0; dwI < dwLength;)
{
if (pfSamplePos >= pfSampleLength)
{
if (pfLoopLength)
{
pfSamplePos -= pfLoopLength;
}
else
break;
}
dwIncDelta--;
if (!dwIncDelta)
{
dwIncDelta = dwDeltaPeriod;
pfPFract += pfDeltaPitch;
pfPitch = pfPFract >> 8;
vfLVFract += vfDeltaLVolume;
vfLVolume = vfLVFract >> 8;
vfRVFract += vfDeltaRVolume;
vfRVolume = vfRVFract >> 8;
}
dwPosition = pfSamplePos >> 12;
dwFract = pfSamplePos & 0xFFF;
pfSamplePos += pfPitch;
// Interpolate
lA = (long)pcWave[dwPosition];
lM = (((pcWave[dwPosition+1] - lA) * dwFract) >> 12) + lA;
lA = lM;
lA *= vfLVolume;
lA >>= 13; // Signal bumps up to 15 bits.
lM *= vfRVolume;
lM >>= 13;
dwIndex = 0;
while ( dwIndex < dwBufferCount )
{
short *pBuffer = &ppBuffers[dwIndex][dwI];
if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_LEFT )
{
// Keep this around so we can use it to generate new assembly code (see below...)
*pBuffer += (short) lA;
_asm{jno no_oflowl}
*pBuffer = 0x7fff;
_asm{js no_oflowl}
*pBuffer = (short) 0x8000;
}
no_oflowl:
if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_RIGHT )
{
// Keep this around so we can use it to generate new assembly code (see below...)
pBuffer++;
*pBuffer += (short) lM;
_asm{jno no_oflowr}
*pBuffer = 0x7fff;
_asm{js no_oflowr}
*pBuffer = (short) 0x8000;
}
no_oflowr:
dwIndex++;
}
dwI += 2;
}
m_vfLastLVolume = vfLVolume;
m_vfLastRVolume = vfRVolume;
m_pfLastPitch = pfPitch;
m_pfLastSample = pfSamplePos;
return (dwI >> 1);
}