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

Subversion Repositories sqmusic

[/] [sqmusic/] [trunk/] [cpp/] [sintable.cc] - Diff between revs 15 and 18

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 15 Rev 18
Line 1... Line 1...
 
/*
 
        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() {
 
        // cout.setf( ios::hex, ios::basefield );
 
  for( int i=0; i<SIN_LEN; i++ ) {
 
    cout << sin_tab[i] << "," << tl_tab[ sin_tab[i] ] << "\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" );
 
  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();
 
        //dump_composite();
 
        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();
 
        return 0;
 
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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