Changeset 82c588a


Ignore:
Timestamp:
Oct 30, 2007, 3:33:19 AM (12 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/constantq, feature/pitchshift, feature/pydocstrings, feature/timestretch, master, pitchshift, sampler, timestretch, yinfft+
Children:
36fa6cb, ef7df76
Parents:
647a2d8 (diff), 6d4ec49 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge from main branch

Files:
2 added
5 edited
38 moved

Legend:

Unmodified
Added
Removed
  • configure.ac

    r647a2d8 r82c588a  
    2525dnl Check for programs
    2626AC_PROG_CC
     27AM_PROG_CC_C_O dnl compiling with per-target flag
    2728if test "$ac_cv_prog_cc" = "no" ; then
    2829   AC_MSG_ERROR([*** No C compiler found !])
     
    240241    ext/Makefile
    241242    examples/Makefile
    242     examples/tests/Makefile
     243    tests/Makefile
     244    tests/src/Makefile
    243245    sounds/Makefile
    244246    swig/Makefile
  • examples/Makefile.am

    r647a2d8 r82c588a  
    1 if COMPILE_TESTS
    2 SUBDIRS = tests
    3 endif
    4 
    51# global flags
    62AM_CFLAGS = -DAUBIO_PREFIX=\"$(prefix)\" -I$(top_srcdir)/src -I$(top_srcdir)/ext @AUBIO_CFLAGS@ @LASH_CFLAGS@ @FFTWLIB_CFLAGS@
  • src/aubio.h

    r647a2d8 r82c588a  
    11/*
    2         Copyright (C) 2003 Paul Brossier <piem@altern.org>
     2  Copyright (C) 2003 Paul Brossier <piem@altern.org>
    33
    4         This program is free software; you can redistribute it and/or modify
    5         it under the terms of the GNU General Public License as published by
    6         the Free Software Foundation; either version 2 of the License, or
    7         (at your option) any later version.
     4  This program is free software; you can redistribute it and/or modify
     5  it under the terms of the GNU General Public License as published by
     6  the Free Software Foundation; either version 2 of the License, or
     7  (at your option) any later version.
    88
    9         This program is distributed in the hope that it will be useful,
    10         but WITHOUT ANY WARRANTY; without even the implied warranty of
    11         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12         GNU General Public License for more details.
     9  This program is distributed in the hope that it will be useful,
     10  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  GNU General Public License for more details.
    1313
    14         You should have received a copy of the GNU General Public License
    15         along with this program; if not, write to the Free Software
    16         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    17        
     14  You should have received a copy of the GNU General Public License
     15  along with this program; if not, write to the Free Software
     16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     17 
    1818*/
    1919
     
    2222 * \section whatis Introduction
    2323 *
    24  *      Aubio is a library for audio labelling: it provides functions for pitch
    25  *      estimation, onset detection, beat tracking, and other annotation tasks.
     24 *  Aubio is a library for audio labelling: it provides functions for pitch
     25 *  estimation, onset detection, beat tracking, and other annotation tasks.
    2626 *
    2727 *  \verbinclude README
     
    2929 * \section bugs bugs and todo
    3030 *
    31  *      This software is under development. It needs debugging and
    32  *      optimisations.
     31 *  This software is under development. It needs debugging and
     32 *  optimisations.
    3333 *
    3434 *  See <a href='bug.html'>bugs</a> and <a href='todo.html'>todo</a> lists.
  • src/pitchdetection.c

    r647a2d8 r82c588a  
    1515   along with this program; if not, write to the Free Software
    1616   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    17 */
     17   */
    1818
    1919#include "aubio_priv.h"
     
    2929#include "pitchdetection.h"
    3030
    31 typedef smpl_t (*aubio_pitchdetection_func_t)(aubio_pitchdetection_t *p,
    32                 fvec_t * ibuf);
    33 typedef smpl_t (*aubio_pitchdetection_conv_t)(smpl_t value,uint_t srate,uint_t bufsize);
     31typedef smpl_t (*aubio_pitchdetection_func_t)
     32  (aubio_pitchdetection_t *p, fvec_t * ibuf);
     33typedef smpl_t (*aubio_pitchdetection_conv_t)
     34  (smpl_t value, uint_t srate, uint_t bufsize);
     35
    3436void aubio_pitchdetection_slideblock(aubio_pitchdetection_t *p, fvec_t *ibuf);
    3537
    36 smpl_t aubio_pitchdetection_mcomb(aubio_pitchdetection_t *p, fvec_t * ibuf);
    37 smpl_t aubio_pitchdetection_yin(aubio_pitchdetection_t *p, fvec_t *ibuf);
    38 smpl_t aubio_pitchdetection_schmitt(aubio_pitchdetection_t *p, fvec_t *ibuf);
    39 smpl_t aubio_pitchdetection_fcomb(aubio_pitchdetection_t *p, fvec_t *ibuf);
    40 smpl_t aubio_pitchdetection_yinfft(aubio_pitchdetection_t *p, fvec_t *ibuf);
     38smpl_t aubio_pitchdetection_mcomb   (aubio_pitchdetection_t *p, fvec_t *ibuf);
     39smpl_t aubio_pitchdetection_yin     (aubio_pitchdetection_t *p, fvec_t *ibuf);
     40smpl_t aubio_pitchdetection_schmitt (aubio_pitchdetection_t *p, fvec_t *ibuf);
     41smpl_t aubio_pitchdetection_fcomb   (aubio_pitchdetection_t *p, fvec_t *ibuf);
     42smpl_t aubio_pitchdetection_yinfft  (aubio_pitchdetection_t *p, fvec_t *ibuf);
    4143
    4244/** generic pitch detection structure */
     
    6466smpl_t freqconvbin(smpl_t f,uint_t srate,uint_t bufsize);
    6567smpl_t freqconvbin(smpl_t f,uint_t srate,uint_t bufsize){
    66         return aubio_freqtobin(f,srate,bufsize);
     68  return aubio_freqtobin(f,srate,bufsize);
    6769}
    6870
    6971smpl_t freqconvmidi(smpl_t f,uint_t srate,uint_t bufsize);
    7072smpl_t freqconvmidi(smpl_t f,uint_t srate UNUSED,uint_t bufsize UNUSED){
    71         return aubio_freqtomidi(f);
     73  return aubio_freqtomidi(f);
    7274}
    7375
    7476smpl_t freqconvpass(smpl_t f,uint_t srate,uint_t bufsize);
    7577smpl_t freqconvpass(smpl_t f,uint_t srate UNUSED,uint_t bufsize UNUSED){
    76         return f;
     78  return f;
    7779}
    7880
    7981aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize,
    80                 uint_t hopsize,
    81                 uint_t channels,
    82                 uint_t samplerate,
    83                 aubio_pitchdetection_type type,
    84                 aubio_pitchdetection_mode mode)
     82    uint_t hopsize,
     83    uint_t channels,
     84    uint_t samplerate,
     85    aubio_pitchdetection_type type,
     86    aubio_pitchdetection_mode mode)
    8587{
    86         aubio_pitchdetection_t *p = AUBIO_NEW(aubio_pitchdetection_t);
    87         p->srate = samplerate;
    88         p->type = type;
    89         p->mode = mode;
    90         p->bufsize = bufsize;
    91         switch(p->type) {
    92                 case aubio_pitch_yin:
    93                         p->buf      = new_fvec(bufsize,channels);
    94                         p->yin      = new_fvec(bufsize/2,channels);
    95                         p->callback = aubio_pitchdetection_yin;
    96                         p->yinthres = 0.15;
    97                         break;
    98                 case aubio_pitch_mcomb:
    99                         p->pv       = new_aubio_pvoc(bufsize, hopsize, channels);
    100                         p->fftgrain = new_cvec(bufsize, channels);
    101                         p->mcomb    = new_aubio_pitchmcomb(bufsize,hopsize,channels,samplerate);
    102                         p->filter   = new_aubio_cdsgn_filter(samplerate);
    103                         p->callback = aubio_pitchdetection_mcomb;
    104                         break;
    105                 case aubio_pitch_fcomb:
    106                         p->buf      = new_fvec(bufsize,channels);
    107                         p->fcomb    = new_aubio_pitchfcomb(bufsize,hopsize,samplerate);
    108                         p->callback = aubio_pitchdetection_fcomb;
    109                         break;
    110                 case aubio_pitch_schmitt:
    111                         p->buf      = new_fvec(bufsize,channels);
    112                         p->schmitt  = new_aubio_pitchschmitt(bufsize,samplerate);
    113                         p->callback = aubio_pitchdetection_schmitt;
    114                         break;
    115                 case aubio_pitch_yinfft:
    116                         p->buf      = new_fvec(bufsize,channels);
    117                         p->yinfft   = new_aubio_pitchyinfft(bufsize);
    118                         p->callback = aubio_pitchdetection_yinfft;
    119                         p->yinthres = 0.85;
    120                         break;
    121                 default:
    122                         break;
    123         }
    124         switch(p->mode) {
    125                 case aubio_pitchm_freq:
    126                         p->freqconv = freqconvpass;
    127                         break;
    128                 case aubio_pitchm_midi:
    129                         p->freqconv = freqconvmidi;
    130                         break;
    131                 case aubio_pitchm_cent:
    132                         /* bug: not implemented */
    133                         p->freqconv = freqconvmidi;
    134                         break;
    135                 case aubio_pitchm_bin:
    136                         p->freqconv = freqconvbin;
    137                         break;
    138                 default:
    139                         break;
    140         }
    141         return p;
     88  aubio_pitchdetection_t *p = AUBIO_NEW(aubio_pitchdetection_t);
     89  p->srate = samplerate;
     90  p->type = type;
     91  p->mode = mode;
     92  p->bufsize = bufsize;
     93  switch(p->type) {
     94    case aubio_pitch_yin:
     95      p->buf      = new_fvec(bufsize,channels);
     96      p->yin      = new_fvec(bufsize/2,channels);
     97      p->callback = aubio_pitchdetection_yin;
     98      p->yinthres = 0.15;
     99      break;
     100    case aubio_pitch_mcomb:
     101      p->pv       = new_aubio_pvoc(bufsize, hopsize, channels);
     102      p->fftgrain = new_cvec(bufsize, channels);
     103      p->mcomb    = new_aubio_pitchmcomb(bufsize,hopsize,channels,samplerate);
     104      p->filter   = new_aubio_cdsgn_filter(samplerate);
     105      p->callback = aubio_pitchdetection_mcomb;
     106      break;
     107    case aubio_pitch_fcomb:
     108      p->buf      = new_fvec(bufsize,channels);
     109      p->fcomb    = new_aubio_pitchfcomb(bufsize,hopsize,samplerate);
     110      p->callback = aubio_pitchdetection_fcomb;
     111      break;
     112    case aubio_pitch_schmitt:
     113      p->buf      = new_fvec(bufsize,channels);
     114      p->schmitt  = new_aubio_pitchschmitt(bufsize,samplerate);
     115      p->callback = aubio_pitchdetection_schmitt;
     116      break;
     117    case aubio_pitch_yinfft:
     118      p->buf      = new_fvec(bufsize,channels);
     119      p->yinfft   = new_aubio_pitchyinfft(bufsize);
     120      p->callback = aubio_pitchdetection_yinfft;
     121      p->yinthres = 0.85;
     122      break;
     123    default:
     124      break;
     125  }
     126  switch(p->mode) {
     127    case aubio_pitchm_freq:
     128      p->freqconv = freqconvpass;
     129      break;
     130    case aubio_pitchm_midi:
     131      p->freqconv = freqconvmidi;
     132      break;
     133    case aubio_pitchm_cent:
     134      /* bug: not implemented */
     135      p->freqconv = freqconvmidi;
     136      break;
     137    case aubio_pitchm_bin:
     138      p->freqconv = freqconvbin;
     139      break;
     140    default:
     141      break;
     142  }
     143  return p;
    142144}
    143145
    144146void del_aubio_pitchdetection(aubio_pitchdetection_t * p) {
    145         switch(p->type) {
    146                 case aubio_pitch_yin:
    147                         del_fvec(p->yin);
    148                         del_fvec(p->buf);
    149                         break;
    150                 case aubio_pitch_mcomb:
    151                         del_aubio_pvoc(p->pv);
    152                         del_cvec(p->fftgrain);
    153                         del_aubio_pitchmcomb(p->mcomb);
    154                         break;
    155                 case aubio_pitch_schmitt:
    156                         del_fvec(p->buf);
    157                         del_aubio_pitchschmitt(p->schmitt);
    158                         break;
    159                 case aubio_pitch_fcomb:
    160                         del_fvec(p->buf);
    161                         del_aubio_pitchfcomb(p->fcomb);
    162                         break;
    163                 case aubio_pitch_yinfft:
    164                         del_fvec(p->buf);
    165                         del_aubio_pitchyinfft(p->yinfft);
    166                         break;
    167                 default:
    168                         break;
    169         }
    170         AUBIO_FREE(p);
     147  switch(p->type) {
     148    case aubio_pitch_yin:
     149      del_fvec(p->yin);
     150      del_fvec(p->buf);
     151      break;
     152    case aubio_pitch_mcomb:
     153      del_aubio_pvoc(p->pv);
     154      del_cvec(p->fftgrain);
     155      del_aubio_pitchmcomb(p->mcomb);
     156      break;
     157    case aubio_pitch_schmitt:
     158      del_fvec(p->buf);
     159      del_aubio_pitchschmitt(p->schmitt);
     160      break;
     161    case aubio_pitch_fcomb:
     162      del_fvec(p->buf);
     163      del_aubio_pitchfcomb(p->fcomb);
     164      break;
     165    case aubio_pitch_yinfft:
     166      del_fvec(p->buf);
     167      del_aubio_pitchyinfft(p->yinfft);
     168      break;
     169    default:
     170      break;
     171  }
     172  AUBIO_FREE(p);
    171173}
    172174
    173175void aubio_pitchdetection_slideblock(aubio_pitchdetection_t *p, fvec_t *ibuf){
    174         uint_t i,j = 0, overlap_size = 0;
    175         overlap_size = p->buf->length-ibuf->length;
    176         for (i=0;i<p->buf->channels;i++){
    177                 for (j=0;j<overlap_size;j++){
    178                         p->buf->data[i][j] =
    179                                 p->buf->data[i][j+ibuf->length];
    180                 }
    181         }
    182         for (i=0;i<ibuf->channels;i++){
    183                 for (j=0;j<ibuf->length;j++){
    184                         p->buf->data[i][j+overlap_size] =
    185                                 ibuf->data[i][j];
    186                 }
    187         }
     176  uint_t i,j = 0, overlap_size = 0;
     177  overlap_size = p->buf->length-ibuf->length;
     178  for (i=0;i<p->buf->channels;i++){
     179    for (j=0;j<overlap_size;j++){
     180      p->buf->data[i][j] = p->buf->data[i][j+ibuf->length];
     181    }
     182  }
     183  for (i=0;i<ibuf->channels;i++){
     184    for (j=0;j<ibuf->length;j++){
     185      p->buf->data[i][j+overlap_size] = ibuf->data[i][j];
     186    }
     187  }
    188188}
    189189
    190190void aubio_pitchdetection_set_yinthresh(aubio_pitchdetection_t *p, smpl_t thres) {
    191         p->yinthres = thres;
     191  p->yinthres = thres;
    192192}
    193193
    194194smpl_t aubio_pitchdetection(aubio_pitchdetection_t *p, fvec_t * ibuf) {
    195         return p->freqconv(p->callback(p,ibuf),p->srate,p->bufsize);
     195  return p->freqconv(p->callback(p,ibuf),p->srate,p->bufsize);
    196196}
    197197
    198198smpl_t aubio_pitchdetection_mcomb(aubio_pitchdetection_t *p, fvec_t *ibuf) {
    199         smpl_t pitch = 0.;
    200         aubio_filter_do(p->filter,ibuf);
    201         aubio_pvoc_do(p->pv,ibuf,p->fftgrain);
    202         pitch = aubio_pitchmcomb_detect(p->mcomb,p->fftgrain);
    203         /** \bug should move the >0 check within aubio_bintofreq */
    204         if (pitch>0.) {
    205                 pitch = aubio_bintofreq(pitch,p->srate,p->bufsize);
    206         } else {
    207                 pitch = 0.;
    208         }
    209         return pitch;
     199  smpl_t pitch = 0.;
     200  aubio_filter_do(p->filter,ibuf);
     201  aubio_pvoc_do(p->pv,ibuf,p->fftgrain);
     202  pitch = aubio_pitchmcomb_detect(p->mcomb,p->fftgrain);
     203  /** \bug should move the >0 check within aubio_bintofreq */
     204  if (pitch>0.) {
     205    pitch = aubio_bintofreq(pitch,p->srate,p->bufsize);
     206  } else {
     207    pitch = 0.;
     208  }
     209  return pitch;
    210210}
    211211
    212212smpl_t aubio_pitchdetection_yin(aubio_pitchdetection_t *p, fvec_t *ibuf) {
    213         smpl_t pitch = 0.;
    214         aubio_pitchdetection_slideblock(p,ibuf);
    215         pitch = aubio_pitchyin_getpitchfast(p->buf,p->yin, p->yinthres);
    216         if (pitch>0) {
    217                 pitch = p->srate/(pitch+0.);
    218         } else {
    219                 pitch = 0.;
    220         }
    221         return pitch;
     213  smpl_t pitch = 0.;
     214  aubio_pitchdetection_slideblock(p,ibuf);
     215  pitch = aubio_pitchyin_getpitchfast(p->buf,p->yin, p->yinthres);
     216  if (pitch>0) {
     217    pitch = p->srate/(pitch+0.);
     218  } else {
     219    pitch = 0.;
     220  }
     221  return pitch;
    222222}
    223223
    224224
    225225smpl_t aubio_pitchdetection_yinfft(aubio_pitchdetection_t *p, fvec_t *ibuf){
    226         smpl_t pitch = 0.;
    227         aubio_pitchdetection_slideblock(p,ibuf);
    228         pitch = aubio_pitchyinfft_detect(p->yinfft,p->buf,p->yinthres);
    229         if (pitch>0) {
    230                 pitch = p->srate/(pitch+0.);
    231         } else {
    232                 pitch = 0.;
    233         }
    234         return pitch;
     226  smpl_t pitch = 0.;
     227  aubio_pitchdetection_slideblock(p,ibuf);
     228  pitch = aubio_pitchyinfft_detect(p->yinfft,p->buf,p->yinthres);
     229  if (pitch>0) {
     230    pitch = p->srate/(pitch+0.);
     231  } else {
     232    pitch = 0.;
     233  }
     234  return pitch;
    235235}
    236236
    237237smpl_t aubio_pitchdetection_fcomb(aubio_pitchdetection_t *p, fvec_t *ibuf){
    238         aubio_pitchdetection_slideblock(p,ibuf);
    239         return aubio_pitchfcomb_detect(p->fcomb,p->buf);
     238  aubio_pitchdetection_slideblock(p,ibuf);
     239  return aubio_pitchfcomb_detect(p->fcomb,p->buf);
    240240}
    241241
    242242smpl_t aubio_pitchdetection_schmitt(aubio_pitchdetection_t *p, fvec_t *ibuf){
    243         aubio_pitchdetection_slideblock(p,ibuf);
    244         return aubio_pitchschmitt_detect(p->schmitt,p->buf);
    245 }
     243  aubio_pitchdetection_slideblock(p,ibuf);
     244  return aubio_pitchschmitt_detect(p->schmitt,p->buf);
     245}
  • src/pitchdetection.h

    r647a2d8 r82c588a  
    1515   along with this program; if not, write to the Free Software
    1616   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    17 */
     17   */
    1818
    1919#ifndef PITCHAUTOTCORR_H
     
    2626/** \file
    2727
    28   Generic method for pitch detection 
     28  Generic method for pitch detection
    2929
    3030  This file creates the objects required for the computation of the selected
     
    3535/** pitch detection algorithm */
    3636typedef enum {
    37         aubio_pitch_yin,     /**< YIN algorithm */
    38         aubio_pitch_mcomb,   /**< Multi-comb filter */
    39         aubio_pitch_schmitt, /**< Schmitt trigger */
    40         aubio_pitch_fcomb,   /**< Fast comb filter */
    41         aubio_pitch_yinfft   /**< Spectral YIN */
     37  aubio_pitch_yin,     /**< YIN algorithm */
     38  aubio_pitch_mcomb,   /**< Multi-comb filter */
     39  aubio_pitch_schmitt, /**< Schmitt trigger */
     40  aubio_pitch_fcomb,   /**< Fast comb filter */
     41  aubio_pitch_yinfft   /**< Spectral YIN */
    4242} aubio_pitchdetection_type;
    4343
    4444/** pitch detection output mode */
    4545typedef enum {
    46         aubio_pitchm_freq,   /**< Frequency (Hz) */
    47         aubio_pitchm_midi,   /**< MIDI note (0.,127) */
    48         aubio_pitchm_cent,   /**< Cent */
    49         aubio_pitchm_bin     /**< Frequency bin (0,bufsize) */
     46  aubio_pitchm_freq,   /**< Frequency (Hz) */
     47  aubio_pitchm_midi,   /**< MIDI note (0.,127) */
     48  aubio_pitchm_cent,   /**< Cent */
     49  aubio_pitchm_bin     /**< Frequency bin (0,bufsize) */
    5050} aubio_pitchdetection_mode;
    5151
     
    5454
    5555/** execute pitch detection on an input signal frame
    56  
     56
    5757  \param p pitch detection object as returned by new_aubio_pitchdetection
    58   \param ibuf input signal of length hopsize 
    59  
     58  \param ibuf input signal of length hopsize
     59
    6060*/
    6161smpl_t aubio_pitchdetection(aubio_pitchdetection_t * p, fvec_t * ibuf);
    6262
    6363/** change yin or yinfft tolerance threshold
    64  
     64
    6565  default is 0.15 for yin and 0.85 for yinfft
    66  
     66
    6767*/
    6868void aubio_pitchdetection_set_yinthresh(aubio_pitchdetection_t *p, smpl_t thres);
    6969
    7070/** deletion of the pitch detection object
    71  
     71
    7272  \param p pitch detection object as returned by new_aubio_pitchdetection
    73  
     73
    7474*/
    7575void del_aubio_pitchdetection(aubio_pitchdetection_t * p);
    7676
    7777/** creation of the pitch detection object
    78  
    79   \param bufsize size of the input buffer to analyse 
    80   \param hopsize step size between two consecutive analysis instant 
     78
     79  \param bufsize size of the input buffer to analyse
     80  \param hopsize step size between two consecutive analysis instant
    8181  \param channels number of channels to analyse
    82   \param samplerate sampling rate of the signal 
     82  \param samplerate sampling rate of the signal
    8383  \param type set pitch detection algorithm
    8484  \param mode set pitch units for output
    85  
     85
    8686*/
    87 aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize, 
    88         uint_t hopsize,
    89         uint_t channels,
    90         uint_t samplerate,
    91         aubio_pitchdetection_type type,
    92         aubio_pitchdetection_mode mode);
     87aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize,
     88    uint_t hopsize,
     89    uint_t channels,
     90    uint_t samplerate,
     91    aubio_pitchdetection_type type,
     92    aubio_pitchdetection_mode mode);
    9393
    9494#ifdef __cplusplus
     
    9696#endif
    9797
    98 #endif /*PITCHDETECTION_H*/ 
     98#endif /*PITCHDETECTION_H*/
  • tests/python/run_all_tests

    r647a2d8 r82c588a  
    44# so the script is runnable from a compiled source tree.
    55import sys, os
    6 sys.path.append('..')
    7 sys.path.append(os.path.join('..','aubio','.libs'))
     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'))
    810
    911import unittest
Note: See TracChangeset for help on using the changeset viewer.