package nxm.sys.test.junit.libm;

import nxm.sys.lib.Midas;
import nxm.sys.lib.Data;
import nxm.sys.libm.Dbf;
import nxm.sys.test.junit.*;

/** Unit test for the {@link Dbf} class.

   Revisions:
   DATE        AUTHOR     DESCRIPTION
   ----------  ---------  ---------------------------------------
   2008-08-29  NTN        Initial version to test Bug 1596 (for Big-Endian machines)

    @author  Neon Ngo
    @version $Id: DbfTest.java,v 1.3 2012/10/17 16:34:29 ntn Exp $
    @since NeXtMidas 2.7.0
 */
public class DbfTest extends NMTestCase {
  /** public constructor to allow running this test case directly with JUnit. */
  public DbfTest(String methodName) { this(methodName, null); }

  /** This constructor is required by NeXtMidas Unit Testing framework. */
  public DbfTest(String methodName, Midas midas) {
    super(methodName, midas);
  }

  //////////////////////////////////////////////////////////////////////////////
  //Ratio  1    1.25 1.6  2    2.5  3.2  4    5    6.3  8   10
  //dB     0    1    2    3    4    5    6    7    8    9   10
  static final float[] input     = {1, 1.6f, 2, 3.2f, 4, 5, 10, 20, 40, 50, 100, 500, 1000, 1e4f, 1e5f, 1e6f, 1e9f, 4e9f, 5e9f};
  //           float[] expected  = {0, 2,    3, 5,    6, 7, 10, 13, 16, 17, 20,  27,  30,   40,   50,   60,   90,   96,   97  };
  final float   tolerance = 0.5f; // DBF is good to +-.5 dB
  // NTN: for input values 1e10f  and larger, we are not longer within .5 dB (seems like our fft/dbf explain file may need to be updated)

  /**
   * Test the {@link Dbf#work(byte[], int, int)} method.
   */
  public void testWork() {
    int flags  = 0;
    Data d     = new Data(input, 1);
    int size   = input.length;
    byte[] buf = d.getBuf();

    // System.out.println("testWork() orig data= "+d+" size="+size);
    Dbf.work(buf, size, flags);
    // System.out.println("  data after Dbf.work()= "+d);

    validateResult(input, d, size);
  }

  public void testProcess() {
    int flags  = 0;
    Data d     = new Data(input, 1);
    int size   = input.length;
    byte[] buf = d.getBuf();

    // System.out.println("testProcess() orig data= "+d+" size="+size);
    Dbf.process(buf, size, flags);
    // System.out.println("  data after Dbf.process()= "+d);

    validateResult(input, d, size);
  }

  // validate dB result
  private void validateResult(float[] input, Data d, int size) {
    for (int i=0; i<size; i++) {
      float x = input[i];
      float expect = (float)(Math.log(x)*Dbf.LN2DB);
      assertEquals("dbf("+x+") ", expect, d.getF(i), tolerance);
    }
  }
}
