OpenCores
URL https://opencores.org/ocsvn/sqmusic/sqmusic/trunk

Subversion Repositories sqmusic

[/] [sqmusic/] [trunk/] [cpp/] [sintable.cc] - Rev 20

Go to most recent revision | Compare with Previous | Blame | View Log

/*
	sintable: sine wave table generator
	Based on MAME's fm.c file.
 
  (c) Jose Tejada Gomez, May 2013
  You can use this file following the GNU GENERAL PUBLIC LICENSE version 3
  Read the details of the license in:
  http://www.gnu.org/licenses/gpl.txt
 
  Send comments to: jose.tejada at ieee.org
 
*/
 
#include <iostream>
#include <cmath>
#include "../cpp/args.h"
 
using namespace std;
 
#define ENV_BITS        10
#define ENV_LEN         (1<<ENV_BITS)
#define ENV_STEP        (128.0/ENV_LEN)
#define TL_RES_LEN      (256) /* 8 bits addressing (real chip) */
#define SIN_BITS        10
#define SIN_LEN         (1<<SIN_BITS)
#define SIN_MASK        (SIN_LEN-1)
 
signed int tl_tab[TL_RES_LEN];
unsigned int sin_tab[SIN_LEN];
 
void init_tables(void) // copied from fm.c
{
	signed int i,x;
	signed int n;
	double o,m;
 
	for (x=0; x<TL_RES_LEN; x++)
	{
		m = (1<<16) / pow(2, (x+1) * (ENV_STEP/4.0) / 8.0);
		m = floor(m);
 
		/* we never reach (1<<16) here due to the (x+1) */
		/* result fits within 16 bits at maximum */
 
		n = (int)m;     /* 16 bits here */
		n >>= 4;        /* 12 bits here */
		if (n&1)        /* round to nearest */
			n = (n>>1)+1;
		else
			n = n>>1;
						/* 11 bits here (rounded) */
		n <<= 2;        /* 13 bits here (as in real chip) */
		tl_tab[ x ] = n;
	}
 
	for (i=0; i<SIN_LEN; i++)
	{
		/* non-standard sinus */
		m = sin( ((i*2)+1) * M_PI / SIN_LEN ); /* checked against the real chip */
 
		/* we never reach zero here due to ((i*2)+1) */
		if (m>0.0)
			o = 8*log(1.0/m)/log(2.0);  /* convert to 'decibels' */
		else
			o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */
 
		o = o / (ENV_STEP/4);
 
		n = (int)(2.0*o);
		if (n&1)                        /* round to nearest */
			n = (n>>1)+1;
		else
			n = n>>1;
 
		sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 );
		/*logerror("FM.C: sin [%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[i],tl_tab[sin_tab[i]]);*/
	}
}
 
void dump_tl_tab() {
  for( int i=0; i<TL_RES_LEN; i++ ) {
    cout <<  tl_tab[i] << "\n";
  }
}
 
void dump_sin_tab() {
  for( int i=0; i<SIN_LEN; i++ ) {
    cout << sin_tab[i] << "\n";
  }
}
 
void dump_composite() {
  for( int i=0; i<SIN_LEN; i++ ) {
    int v = sin_tab[i];
    int m = (v>>1)&0xFF;
    int lin = tl_tab[m];
    int exp = v>>9;
    int adj0 = lin>>exp;
    int adj1 = (v&1) ? -1*adj0 : adj0;
    cout << v << "," << lin << "," << exp << "," << adj0 << "," << adj1 << "\n";
  }
}
 
unsigned conv( double x ) {
  double xmax = 0xFFFFF; // 20 bits, all ones
  return (unsigned)(xmax* 20*log(x+0.5));
}
 
int main(int argc, char *argv[]) {
  arg_vector_t legal_args;
  argument_t arg_hex( legal_args, "hex", argument_t::flag, 
    "set output to hexadecimal mode" );
  argument_t arg_sin( legal_args, "sin", argument_t::flag,
    "dump sine wave" );
  argument_t arg_pow( legal_args, "pow", argument_t::flag,
    "dump power table" );
  argument_t arg_comp( legal_args, "composite", argument_t::flag,
    "dump pow[ sine ] composite function" );
  Args args_parser( argc, argv, legal_args );
  if( args_parser.help_request() ) { return 0; }
  if( argc==1 ) { args_parser.show_help(); return 0; }
  init_tables();  
 
	if( arg_hex.is_set() ) cout.setf( ios::hex, ios::basefield );
	if( arg_pow.is_set() ) dump_tl_tab();
	if( arg_sin.is_set() ) dump_sin_tab();
	if( arg_comp.is_set() ) dump_composite();		
	return 0;
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.