#include "./pxtn.h"
#include "./pxtnPulse_Frequency.h"
#define _OCTAVE_NUM 16
#define _KEY_PER_OCTAVE 12
#define _FREQUENCY_PER_KEY 0x10
#define _BASIC_FREQUENCY_INDEX ((_OCTAVE_NUM/2) * _KEY_PER_OCTAVE * _FREQUENCY_PER_KEY )
#define _TABLE_SIZE ( _OCTAVE_NUM * _KEY_PER_OCTAVE * _FREQUENCY_PER_KEY )
double pxtnPulse_Frequency::_GetDivideOctaveRate( int32_t divi )
{
double parameter = 1.0;
double work;
double result;
double add;
int32_t i, j, k;
for( i = 0; i < 17; i++ )
{
add = 1;
for( j = 0; j < i; j++ ) add = add * 0.1;
for( j = 0; j < 10; j++ )
{
work = parameter + add * j;
result = 1.0;
for( k = 0; k < divi; k++ )
{
result *= work;
if( result >= 2.0 ) break;
}
if( k != divi ) break;
}
parameter += add * ( j - 1 );
}
return parameter;
}
pxtnPulse_Frequency::pxtnPulse_Frequency()
{
_freq_table = NULL;
}
pxtnPulse_Frequency::~pxtnPulse_Frequency()
{
if( _freq_table ) free( _freq_table ); _freq_table = NULL;
}
bool pxtnPulse_Frequency::Init()
{
bool b_ret = false;
double oct_table[ _OCTAVE_NUM ] =
{
0.00390625, 0.0078125, 0.015625, 0.03125, 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64, 128, };
int32_t key ;
int32_t f ;
double oct_x24;
double work;
if( !( _freq_table = (float*)malloc( sizeof(float) * _TABLE_SIZE ) ) ) goto End;
oct_x24 = _GetDivideOctaveRate( _KEY_PER_OCTAVE * _FREQUENCY_PER_KEY );
for( f = 0; f < _OCTAVE_NUM * (_KEY_PER_OCTAVE * _FREQUENCY_PER_KEY); f++ )
{
work = oct_table[ f / (_KEY_PER_OCTAVE * _FREQUENCY_PER_KEY) ];
for( key = 0; key < f % (_KEY_PER_OCTAVE * _FREQUENCY_PER_KEY); key++ )
{
work *= oct_x24;
}
_freq_table[ f ] = (float) work;
}
b_ret = true;
End:
return b_ret;
}
float pxtnPulse_Frequency::Get( int32_t key )
{
int32_t i;
i = (key + 0x6000) * _FREQUENCY_PER_KEY / 0x100;
if ( i < 0 ) i = 0;
else if( i >= _TABLE_SIZE ) i = _TABLE_SIZE -1;
return _freq_table[ i ];
}
float pxtnPulse_Frequency::Get2( int32_t key )
{
int32_t i = key >> 4;
if ( i < 0 ) i = 0;
else if( i >= _TABLE_SIZE ) i = _TABLE_SIZE - 1;
return _freq_table[ i ];
}
const float* pxtnPulse_Frequency::GetDirect( int32_t *p_size )
{
*p_size = _TABLE_SIZE;
return _freq_table;
}