Changes in / [212da72:dddf1f5]


Ignore:
Files:
17 added
37 deleted
15 edited

Legend:

Unmodified
Added
Removed
  • README

    r212da72 rdddf1f5  
    119119CONTACT
    120120
    121 The home page of this project can be found at http://aubio.org/. Feel free
     121The home page of this project can be found at http://aubio.piem.org/. Feel free
    122122to drop me a comment (piem@altern.org) or on the mailing list, aubio@piem.org.
    123123Suggestions and feedback are most welcome.
  • configure.ac

    r212da72 rdddf1f5  
    8282AC_LIBTOOL_DLOPEN
    8383dnl AC_DISABLE_STATIC
    84 dnl allow cross compiling
    85 AC_LIBTOOL_WIN32_DLL
    8684AC_PROG_LIBTOOL
    8785
     
    9189AM_CONDITIONAL(MINGW, false)
    9290AM_CONDITIONAL(DARWIN, false)
    93 case "${host_os}" in
     91case "${build_os}" in
    9492*mingw* | *cygwin*)
    9593  mingw32_support="yes"
  • examples/utils.c

    r212da72 rdddf1f5  
    2222void save_data (void);
    2323void restore_data(lash_config_t * lash_config);
     24void flush_process(aubio_process_func_t process_func, aubio_print_func_t print);
    2425pthread_t lash_thread;
    2526#endif /* LASH_SUPPORT */
     
    409410
    410411void flush_process(aubio_process_func_t process_func, aubio_print_func_t print){
    411   uint_t i,j;
     412  uint i,j;
    412413  for (i = 0; i < channels; i++) {
    413414    for (j = 0; j < obuf->length; j++) {
  • examples/utils.h

    r212da72 rdddf1f5  
    5757#endif
    5858void examples_common_process(aubio_process_func_t process_func, aubio_print_func_t print);
    59 void flush_process(aubio_process_func_t process_func, aubio_print_func_t print);
    6059
    6160
  • src/Makefile.am

    r212da72 rdddf1f5  
    1 noinst_HEADERS = \
    2         aubio_priv.h \
    3         temporal/filter_priv.h
    4 
     1noinst_HEADERS = aubio_priv.h
    52pkginclude_HEADERS = aubio.h \
    63        types.h \
    74        fvec.h \
    8         lvec.h \
    95        cvec.h \
    10         mathutils.h
    11 
    12 pkgincludeutilsdir = $(pkgincludedir)/utils
    13 pkgincludetemporaldir = $(pkgincludedir)/temporal
    14 pkgincludespectraldir = $(pkgincludedir)/spectral
    15 pkgincludepitchdir = $(pkgincludedir)/pitch
    16 pkgincludeonsetdir = $(pkgincludedir)/onset
    17 pkgincludetempodir = $(pkgincludedir)/tempo
    18 
    19 pkgincludeutils_HEADERS = \
     6        mathutils.h \
    207        utils/hist.h \
    21         utils/scale.h
    22 
    23 pkgincludetemporal_HEADERS = \
     8        utils/scale.h \
    249        temporal/resample.h \
    2510        temporal/biquad.h \
    2611        temporal/filter.h \
    27         temporal/adesign.h \
    28         temporal/cdesign.h
    29 
    30 pkgincludespectral_HEADERS = \
    3112        spectral/filterbank.h \
    32         spectral/mfcc.h \
     13        spectral/mfcc.c \
    3314        spectral/phasevoc.h \
    3415        spectral/fft.h \
    3516        spectral/tss.h \
    36         spectral/spectral_centroid.h
    37 
    38 pkgincludepitch_HEADERS = \
     17        spectral/spectral_centroid.h \
    3918        pitch/pitchdetection.h \
    4019        pitch/pitchmcomb.h \
     
    4221        pitch/pitchschmitt.h \
    4322        pitch/pitchfcomb.h \
    44         pitch/pitchyinfft.h
    45 
    46 pkgincludeonset_HEADERS =       \
     23        pitch/pitchyinfft.h \
    4724        onset/onset.h \
    4825        onset/onsetdetection.h \
    49         onset/peakpick.h
    50 
    51 pkgincludetempo_HEADERS =       \
     26        onset/peakpick.h \
    5227        tempo/tempo.h \
    5328        tempo/beattracking.h
    5429
     30nodist_pkginclude_HEADERS = config.h
     31
    5532lib_LTLIBRARIES = libaubio.la
    56 libaubio_la_SOURCES = \
     33libaubio_la_SOURCES = aubio.h \
     34        types.h \
    5735        fvec.c \
    58         lvec.c \
     36        fvec.h \
    5937        cvec.c \
     38        cvec.h \
    6039        mathutils.c \
     40        mathutils.h \
    6141        utils/hist.c \
     42        utils/hist.h \
    6243        utils/scale.c \
     44        utils/scale.h \
    6345        temporal/resample.c \
     46        temporal/resample.h \
    6447        temporal/biquad.c \
     48        temporal/biquad.h \
    6549        temporal/filter.c \
    66         temporal/adesign.c \
    67         temporal/cdesign.c \
     50        temporal/filter.h \
    6851        spectral/filterbank.c \
     52        spectral/filterbank.h \
     53        spectral/mfcc.h \
    6954        spectral/mfcc.c \
    7055        spectral/phasevoc.c \
     56        spectral/phasevoc.h \
    7157        spectral/fft.c \
     58        spectral/fft.h \
    7259        spectral/tss.c \
     60        spectral/tss.h \
    7361        spectral/spectral_centroid.c \
     62        spectral/spectral_centroid.h \
    7463        pitch/pitchdetection.c \
     64        pitch/pitchdetection.h \
    7565        pitch/pitchmcomb.c \
     66        pitch/pitchmcomb.h \
    7667        pitch/pitchyin.c \
     68        pitch/pitchyin.h \
    7769        pitch/pitchschmitt.c \
     70        pitch/pitchschmitt.h \
    7871        pitch/pitchfcomb.c \
     72        pitch/pitchfcomb.h \
    7973        pitch/pitchyinfft.c \
     74        pitch/pitchyinfft.h \
    8075        onset/onset.c \
     76        onset/onset.h \
    8177        onset/onsetdetection.c \
     78        onset/onsetdetection.h \
    8279        onset/peakpick.c \
     80        onset/peakpick.h \
    8381        tempo/tempo.c \
    84         tempo/beattracking.c
     82        tempo/tempo.h \
     83        tempo/beattracking.c \
     84        tempo/beattracking.h
    8585
    8686AM_CFLAGS = @AUBIO_CFLAGS@ @FFTWLIB_CFLAGS@ @SAMPLERATE_CFLAGS@
  • src/aubio.h

    r212da72 rdddf1f5  
    6161#include "fvec.h"
    6262#include "cvec.h"
    63 #include "lvec.h"
    6463#include "mathutils.h"
    6564#include "utils/scale.h"
     
    6968#include "temporal/biquad.h"
    7069#include "temporal/filter.h"
    71 #include "temporal/adesign.h"
    72 #include "temporal/cdesign.h"
    7370#include "spectral/filterbank.h"
    7471#include "spectral/mfcc.h"
  • src/aubio_priv.h

    r212da72 rdddf1f5  
    170170#define ELEM_SWAP(a,b) { register smpl_t t=(a);(a)=(b);(b)=t; }
    171171
    172 #define ISDENORMAL(f) f < 1.e-37
    173 
    174172#define UNUSED __attribute__((unused))
    175173
  • src/pitch/pitchdetection.c

    r212da72 rdddf1f5  
    2222#include "spectral/phasevoc.h"
    2323#include "mathutils.h"
    24 #include "temporal/cdesign.h"
     24#include "temporal/filter.h"
    2525#include "pitch/pitchmcomb.h"
    2626#include "pitch/pitchyin.h"
     
    103103      p->fftgrain = new_cvec(bufsize, channels);
    104104      p->mcomb    = new_aubio_pitchmcomb(bufsize,hopsize,channels,samplerate);
    105       p->filter   = new_aubio_cdsgn_filter(samplerate, channels);
     105      p->filter   = new_aubio_cdsgn_filter(samplerate);
    106106      p->callback = aubio_pitchdetection_mcomb;
    107107      break;
  • src/spectral/fft.c

    r212da72 rdddf1f5  
    155155    spectrum->phas[i][0] = 0.;
    156156    for (j=1; j < spectrum->length - 1; j++) {
    157       if (compspec->data[i][j] == 0.) spectrum->phas[i][j] = 0;
    158       else
    159157      spectrum->phas[i][j] = atan2f(compspec->data[i][compspec->length-j],
    160158          compspec->data[i][j]);
  • src/temporal/filter.c

    r212da72 rdddf1f5  
    2424#include "aubio_priv.h"
    2525#include "fvec.h"
    26 #include "lvec.h"
    2726#include "mathutils.h"
    2827#include "temporal/filter.h"
    29 #include "temporal/filter_priv.h"
    30 
     28
     29struct _aubio_filter_t {
     30  uint_t order;
     31  lsmp_t * a;
     32  lsmp_t * b;
     33  lsmp_t * y;
     34  lsmp_t * x;
     35};
     36
     37/* bug: mono only */
    3138void aubio_filter_do(aubio_filter_t * f, fvec_t * in) {
    32   aubio_filter_do_outplace(f, in, in);
     39  uint_t i,j,l, order = f->order;
     40  lsmp_t *x = f->x;
     41  lsmp_t *y = f->y;
     42  lsmp_t *a = f->a;
     43  lsmp_t *b = f->b;
     44  i=0;//for (i=0;i<in->channels;i++) {
     45  for (j = 0; j < in->length; j++) {
     46    /* new input */
     47    //AUBIO_DBG("befor %f\t", in->data[i][j]);
     48    x[0] = in->data[i][j];
     49    y[0] = b[0] * x[0];
     50    for (l=1;l<order; l++) {
     51      y[0] += b[l] * x[l];
     52      y[0] -= a[l] * y[l];
     53    } /* + 1e-37; for denormal ? */
     54    /* new output */
     55    in->data[i][j] = y[0];
     56    //AUBIO_DBG("after %f\n", in->data[i][j]);
     57    /* store states for next sample */
     58    for (l=order-1; l>0; l--){
     59      x[l] = x[l-1];
     60      y[l] = y[l-1];
     61    }
     62  }
     63  /* store states for next buffer */
     64  f->x = x;
     65  f->y = y;
     66  //}   
    3367}
    3468
    3569void aubio_filter_do_outplace(aubio_filter_t * f, fvec_t * in, fvec_t * out) {
    3670  uint_t i,j,l, order = f->order;
    37   lsmp_t *x;
    38   lsmp_t *y;
    39   lsmp_t *a = f->a->data[0];
    40   lsmp_t *b = f->b->data[0];
    41 
    42   for (i = 0; i < in->channels; i++) {
    43     x = f->x->data[i];
    44     y = f->y->data[i];
    45     for (j = 0; j < in->length; j++) {
    46       /* new input */
    47       if (ISDENORMAL(in->data[i][j])) {
    48         x[0] = y[0] = 0.;
    49       } else {
    50         x[0] = in->data[i][j];
    51         y[0] = b[0] * x[0];
    52         for (l=1;l<order; l++) {
    53           y[0] += b[l] * x[l];
    54           y[0] -= a[l] * y[l];
    55         }
    56       }
    57       /* new output */
    58       out->data[i][j] = y[0];
    59       /* store for next sample */
    60       for (l=order-1; l>0; l--){
    61         x[l] = x[l-1];
    62         y[l] = y[l-1];
    63       }
     71  lsmp_t *x = f->x;
     72  lsmp_t *y = f->y;
     73  lsmp_t *a = f->a;
     74  lsmp_t *b = f->b;
     75
     76  i=0; // works in mono only !!!
     77  //for (i=0;i<in->channels;i++) {
     78  for (j = 0; j < in->length; j++) {
     79    /* new input */
     80    x[0] = in->data[i][j];
     81    y[0] = b[0] * x[0];
     82    for (l=1;l<order; l++) {
     83      y[0] += b[l] * x[l];
     84      y[0] -= a[l] * y[l];
    6485    }
    65     /* store for next run */
    66     f->x->data[i] = x;
    67     f->y->data[i] = y;
    68   }
     86    // + 1e-37;
     87    /* new output */
     88    out->data[i][j] = y[0];
     89    /* store for next sample */
     90    for (l=order-1; l>0; l--){
     91      x[l] = x[l-1];
     92      y[l] = y[l-1];
     93    }
     94  }
     95  /* store for next run */
     96  f->x = x;
     97  f->y = y;
     98  //}
    6999}
    70100
     
    103133}
    104134
    105 aubio_filter_t * new_aubio_filter(uint_t samplerate UNUSED, uint_t order, uint_t channels) {
     135
     136aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate) {
     137  aubio_filter_t * f = new_aubio_filter(samplerate, 7);
     138  lsmp_t * a = f->a;
     139  lsmp_t * b = f->b;
     140  /* uint_t l; */
     141  /* for now, 44100, adsgn */
     142  a[0] =  1.00000000000000000000000000000000000000000000000000000;
     143  a[1] = -4.01957618111583236952810693765059113502502441406250000;
     144  a[2] =  6.18940644292069386267485242569819092750549316406250000;
     145  a[3] = -4.45319890354411640487342083360999822616577148437500000;
     146  a[4] =  1.42084294962187751565352300531230866909027099609375000;
     147  a[5] = -0.14182547383030480458998567883099894970655441284179688;
     148  a[6] =  0.00435117723349511334451911181986361043527722358703613;
     149  b[0] =  0.25574112520425740235907596797915175557136535644531250;
     150  b[1] = -0.51148225040851391653973223583307117223739624023437500;
     151  b[2] = -0.25574112520426162120656954357400536537170410156250000;
     152  b[3] =  1.02296450081703405032840237254276871681213378906250000;
     153  b[4] = -0.25574112520426051098354491841746494174003601074218750;
     154  b[5] = -0.51148225040851369449512731080176308751106262207031250;
     155  b[6] =  0.25574112520425729133677350546349771320819854736328125;
     156  /* DBG: filter coeffs at creation time */
     157  /*
     158  for (l=0; l<f->order; l++){
     159    AUBIO_DBG("a[%d]=\t%1.16f\tb[%d]=\t%1.16f\n",l,a[l],l,b[l]);
     160  }
     161  */
     162  f->a = a;
     163  f->b = b;
     164  return f;
     165}
     166
     167aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate) {
     168  aubio_filter_t * f = new_aubio_filter(samplerate, 5);
     169  lsmp_t * a = f->a;
     170  lsmp_t * b = f->b;
     171  /* uint_t l; */
     172  /* for now, 44100, cdsgn */
     173  a[0] =  1.000000000000000000000000000000000000000000000000000000000000;
     174  a[1] = -2.134674963687040794013682898366823792457580566406250000000000;
     175  a[2] =  1.279333533236063358273781886964570730924606323242187500000000;
     176  a[3] = -0.149559846089396208945743182994192466139793395996093750000000;
     177  a[4] =  0.004908700174624848651394604104325480875559151172637939453125;
     178  b[0] =  0.217008561949218803377448239189106971025466918945312500000000;
     179  b[1] = -0.000000000000000222044604925031308084726333618164062500000000;
     180  b[2] = -0.434017123898438272888711253472138196229934692382812500000000;
     181  b[3] =  0.000000000000000402455846426619245903566479682922363281250000;
     182  b[4] =  0.217008561949218969910901932962588034570217132568359375000000;
     183  /* DBG: filter coeffs at creation time */
     184  /*
     185  for (l=0; l<f->order; l++){
     186    AUBIO_DBG("a[%d]=\t%1.16f\tb[%d]=\t%1.16f\n",l,a[l],l,b[l]);
     187  }
     188  */
     189  f->a = a;
     190  f->b = b;
     191  return f;
     192}
     193
     194aubio_filter_t * new_aubio_filter(uint_t samplerate UNUSED, uint_t order) {
    106195  aubio_filter_t * f = AUBIO_NEW(aubio_filter_t);
    107   f->x = new_lvec(order, channels);
    108   f->y = new_lvec(order, channels);
    109   f->a = new_lvec(order, 1);
    110   f->b = new_lvec(order, 1);
    111   f->a->data[0][1] = 1.;
     196  lsmp_t * x = f->x;
     197  lsmp_t * y = f->y;
     198  lsmp_t * a = f->a;
     199  lsmp_t * b = f->b;
     200  uint_t l;
    112201  f->order = order;
     202  a = AUBIO_ARRAY(lsmp_t,f->order);
     203  b = AUBIO_ARRAY(lsmp_t,f->order);
     204  x = AUBIO_ARRAY(lsmp_t,f->order);
     205  y = AUBIO_ARRAY(lsmp_t,f->order);
     206  /* initial states to zeros */
     207  for (l=0; l<f->order; l++){
     208    x[l] = 0.;
     209    y[l] = 0.;
     210  }
     211  f->x = x;
     212  f->y = y;
     213  f->a = a;
     214  f->b = b;
    113215  return f;
    114216}
  • src/temporal/filter.h

    r212da72 rdddf1f5  
    6969  \param samplerate signal sampling rate
    7070  \param order order of the filter (number of coefficients)
    71   \param channels number of channels to allocate
    7271
    7372*/
    74 aubio_filter_t * new_aubio_filter(uint_t samplerate, uint_t order, uint_t channels);
     73aubio_filter_t * new_aubio_filter(uint_t samplerate, uint_t order);
     74/** create a new A-design filter
     75
     76  \param samplerate sampling-rate of the signal to filter
     77
     78*/
     79aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate);
     80/** create a new C-design filter
     81
     82  \param samplerate sampling-rate of the signal to filter
     83
     84*/
     85aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate);
    7586/** delete a filter object
    7687 
  • swig/aubio.i

    r212da72 rdddf1f5  
    8686
    8787/* filter */
    88 extern aubio_filter_t * new_aubio_filter(uint_t samplerate, uint_t order, uint_t channels);
     88extern aubio_filter_t * new_aubio_filter(uint_t samplerate, uint_t order);
     89extern aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate);
     90extern aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate);
    8991extern void aubio_filter_do(aubio_filter_t * b, fvec_t * in);
    9092extern void aubio_filter_do_outplace(aubio_filter_t * b, fvec_t * in, fvec_t * out);
    9193extern void aubio_filter_do_filtfilt(aubio_filter_t * b, fvec_t * in, fvec_t * tmp);
    92 extern void del_aubio_filter(aubio_filter_t * b);
    93 
    94 extern aubio_filter_t * new_aubio_adsgn_filter(uint_t samplerate, uint_t channels);
    95 extern void aubio_adsgn_filter_do(aubio_filter_t * b, fvec_t * in);
    96 extern void del_aubio_adsgn_filter(aubio_filter_t * b);
    97 
    98 extern aubio_filter_t * new_aubio_cdsgn_filter(uint_t samplerate, uint_t channels);
    99 extern void aubio_cdsgn_filter_do(aubio_filter_t * b, fvec_t * in);
    100 extern void del_aubio_cdsgn_filter(aubio_filter_t * b);
     94/*extern int del_aubio_filter(aubio_filter_t * b);*/
    10195
    10296/* biquad */
     
    174168
    175169/* scale */
    176 extern aubio_scale_t * new_aubio_scale(smpl_t flow, smpl_t fhig, smpl_t ilow, smpl_t ihig);
     170extern aubio_scale_t * new_aubio_scale(smpl_t flow, smpl_t fhig, smpl_t ilow, smpl_t ihig       );
    177171extern void aubio_scale_set (aubio_scale_t *s, smpl_t ilow, smpl_t ihig, smpl_t olow, smpl_t ohig);
    178172extern void aubio_scale_do(aubio_scale_t *s, fvec_t * input);
     
    220214        aubio_pitch_schmitt,
    221215        aubio_pitch_fcomb,
    222         aubio_pitch_yinfft
     216        aubio_pitch_yinfft
    223217} aubio_pitchdetection_type;
    224218
     
    237231
    238232aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize,
    239     uint_t hopsize,
    240     uint_t channels,
    241     uint_t samplerate,
    242     aubio_pitchdetection_type type,
    243     aubio_pitchdetection_mode mode);
     233                uint_t hopsize,
     234                uint_t channels,
     235                uint_t samplerate,
     236                aubio_pitchdetection_type type,
     237                aubio_pitchdetection_mode mode);
    244238
    245239
     
    269263aubio_pickpeak_t * new_aubio_peakpicker(smpl_t threshold);
    270264uint_t aubio_peakpick_pimrt(fvec_t * DF, aubio_pickpeak_t * p);
     265smpl_t aubio_peakpick_pimrt_getval(aubio_pickpeak_t* p);
    271266uint_t aubio_peakpick_pimrt_wt( fvec_t* DF, aubio_pickpeak_t* p, smpl_t* peakval );
    272 smpl_t aubio_peakpick_pimrt_getval(aubio_pickpeak_t* p);
    273267void del_aubio_peakpicker(aubio_pickpeak_t * p);
    274 void aubio_peakpicker_set_threshold(aubio_pickpeak_t * p, smpl_t threshold);
    275 smpl_t aubio_peakpicker_get_threshold(aubio_pickpeak_t * p);
    276268
    277269/* transient/steady state separation */
     
    483475sint_t aubio_midi_player_join(aubio_midi_player_t* player);
    484476sint_t aubio_track_send_events(aubio_track_t* track,
    485     /*  aubio_synth_t* synth, */
    486     aubio_midi_player_t* player,
    487     uint_t ticks);
     477/*  aubio_synth_t* synth, */
     478                           aubio_midi_player_t* player,
     479                           uint_t ticks);
    488480sint_t aubio_midi_send_event(aubio_midi_player_t* player, aubio_midi_event_t* event);
    489481
  • tests/python/examples/aubioonset.py

    r212da72 rdddf1f5  
    11from template import *
    22
    3 class aubioonset_unit(program_test_case):
     3class aubioonset_test_case(program_test_case):
    44 
    55  import os.path
     
    2424    self.getOutput()
    2525    # only one onset in woodblock.aiff
    26     self.assertNotEqual(0, len(str(self.output)), \
    27       "no output produced with command:\n" + self.command)
    28     self.assertEqual(1, len(self.output.split('\n')) )
     26    assert len(str(self.output)) != 0, "no output produced with command:\n" \
     27      + self.command
     28    assert len(self.output.split('\n')) == 1
    2929    # onset should be at 0.00000
    30     self.assertEqual(0, float(self.output.strip()))
     30    assert float(self.output.strip()) == 0.
    3131
    32 list_of_onset_modes = ["energy", "specdiff", "hfc", "complex", "phase", \
    33                       "kl", "mkl", "specflux"]
    34 
    35 for name in list_of_onset_modes:
    36   exec("class aubioonset_"+name+"_unit(aubioonset_unit):\n\
     32for name in ["energy", "specdiff", "hfc", "complex", "phase", "kl", "mkl"]:
     33  exec("class aubioonset_test_case_"+name+"(aubioonset_test_case):\n\
    3734  options = \" -O "+name+" \"")
    3835
  • tests/python/run_all_tests

    r212da72 rdddf1f5  
    11#! /usr/bin/python
     2
     3# add ${src}/python and ${src}/python/aubio/.libs to python path
     4# so the script is runnable from a compiled source tree.
     5import sys, os
     6
     7cur_dir = os.path.dirname(sys.argv[0])
     8sys.path.append(os.path.join(cur_dir,'..','..','python'))
     9sys.path.append(os.path.join(cur_dir,'..','..','python','aubio','.libs'))
    210
    311import unittest
     
    715  return [i.split('.')[0].replace('/','.') for i in glob(path)]
    816
    9 modules_to_test  = []
    10 modules_to_test += list_of_test_files('src/*.py')
    11 modules_to_test += list_of_test_files('src/*/*.py')
     17modules_to_test  = list_of_test_files('*.py')
    1218modules_to_test += list_of_test_files('examples/aubio*.py')
    13 modules_to_test += list_of_test_files('*.py')
    1419
    1520if __name__ == '__main__':
  • tests/python/template.py

    r212da72 rdddf1f5  
     1
    12import unittest
    23
     
    45 
    56  def assertCloseEnough(self, first, second, places=5, msg=None):
    6     """Fail if the two objects are unequal as determined by their
    7        *relative* difference rounded to the given number of decimal places
    8        (default 7) and comparing to zero.
    9     """
    10     if round(first, places) == 0:
    11       if round(second-first, places) != 0:
    12         raise self.failureException, \
    13               (msg or '%r != %r within %r places' % (first, second, places))
    14     else:
    15       if round((second-first)/first, places) != 0:
    16         raise self.failureException, \
    17               (msg or '%r != %r within %r places' % (first, second, places))
     7        """Fail if the two objects are unequal as determined by their
     8           *relative* difference rounded to the given number of decimal places
     9           (default 7) and comparing to zero.
     10        """
     11        if round(first, places) == 0:
     12          if round(second-first, places) != 0:
     13              raise self.failureException, \
     14                    (msg or '%r != %r within %r places' % (first, second, places))
     15        else:
     16          if round((second-first)/first, places) != 0:
     17              raise self.failureException, \
     18                    (msg or '%r != %r within %r places' % (first, second, places))
Note: See TracChangeset for help on using the changeset viewer.