Changeset 568fc60


Ignore:
Timestamp:
Nov 5, 2018, 3:43:02 PM (5 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/timestretch, fix/ffmpeg5, master
Children:
893e699
Parents:
a9e3bd0 (diff), bc1ed63 (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 branch 'master' into feature/pytest

Files:
15 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    ra9e3bd0 r568fc60  
    4949python/tests/sounds
    5050aubio.egg-info
     51.eggs
     52.cache
  • MANIFEST.in

    ra9e3bd0 r568fc60  
    22include python/README.md
    33include this_version.py
     4include waf
     5recursive-include waflib *.py
    46include Makefile wscript */wscript_build
    5 include waf waflib/* waflib/*/*
    6 exclude waflib/__pycache__/*
    77include aubio.pc.in
    88include requirements.txt
  • doc/py_io.rst

    ra9e3bd0 r568fc60  
    4040    down-mixed to produce the new samples.
    4141
    42     return: A tuple of one array of samples and one integer.
     42    :returns: A tuple of one array of samples and one integer.
    4343    :rtype: (array, int)
    4444
  • python/demos/demo_filter.py

    ra9e3bd0 r568fc60  
    44import os.path
    55import aubio
     6
    67
    78def apply_filter(path, target):
     
    2829        total_frames += read
    2930        # end of file reached
    30         if read < s.hop_size: break
     31        if read < s.hop_size:
     32            break
    3133
    3234    # print some info
     
    3436    input_str = "input: {:s} ({:.2f} s, {:d} Hz)"
    3537    output_str = "output: {:s}, A-weighting filtered ({:d} frames total)"
    36     print (input_str.format(s.uri, duration, samplerate))
    37     print (output_str.format(o.uri, total_frames))
     38    print(input_str.format(s.uri, duration, samplerate))
     39    print(output_str.format(o.uri, total_frames))
    3840
    3941if __name__ == '__main__':
    4042    usage = "{:s} <input_file> [output_file]".format(sys.argv[0])
    4143    if not 1 < len(sys.argv) < 4:
    42         print (usage)
     44        print(usage)
    4345        sys.exit(1)
    4446    if len(sys.argv) < 3:
  • python/demos/demo_filterbank.py

    ra9e3bd0 r568fc60  
    11#! /usr/bin/env python
    22
    3 from aubio import filterbank, fvec
    4 from pylab import loglog, show, xlim, ylim, xlabel, ylabel, title
    5 from numpy import vstack, arange
     3"""Create a filterbank from a list of frequencies.
    64
     5This demo uses `aubio.filterbank.set_triangle_bands` to build a set of
     6triangular filters from a list of frequencies.
     7
     8The filterbank coefficients are then modified before being displayed."""
     9
     10import aubio
     11import numpy as np
     12import matplotlib.pyplot as plt
     13
     14# sampling rate and size of the fft
     15samplerate = 48000
    716win_s = 2048
    8 samplerate = 48000
    917
     18# define a list of custom frequency
    1019freq_list = [60, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 24000]
     20# number of filters to create
    1121n_filters = len(freq_list) - 2
    1222
    13 f = filterbank(n_filters, win_s)
    14 freqs = fvec(freq_list)
     23# create a new filterbank
     24f = aubio.filterbank(n_filters, win_s)
     25freqs = aubio.fvec(freq_list)
    1526f.set_triangle_bands(freqs, samplerate)
    1627
     28# get the coefficients from the filterbank
    1729coeffs = f.get_coeffs()
    18 coeffs[4] *= 5.
    19 
     30# apply a gain to fifth band
     31coeffs[4] *= 6.
     32# load the modified coeffs into the filterbank
    2033f.set_coeffs(coeffs)
    2134
    22 times = vstack([arange(win_s // 2 + 1) * samplerate / win_s] * n_filters)
    23 title('Bank of filters built using a simple list of boundaries\nThe middle band has been amplified by 2.')
    24 loglog(times.T, f.get_coeffs().T, '.-')
    25 xlim([50, samplerate/2])
    26 ylim([1.0e-6, 2.0e-2])
    27 xlabel('log frequency (Hz)')
    28 ylabel('log amplitude')
    29 
    30 show()
     35# display the band gains in a loglog plot
     36freqs = np.vstack([np.arange(win_s // 2 + 1) * samplerate / win_s] * n_filters)
     37plt.title('filterbank built from a list of frequencies\n'
     38          'The 5th band has been amplified by a factor 6.')
     39plt.loglog(freqs.T, f.get_coeffs().T, '.-')
     40plt.xlim([50, samplerate/2])
     41plt.ylim([1.0e-6, 2.0e-2])
     42plt.xlabel('log frequency (Hz)')
     43plt.ylabel('log amplitude')
     44plt.show()
  • python/demos/demo_source_simple.py

    ra9e3bd0 r568fc60  
    11#! /usr/bin/env python
     2
     3"""A simple example using aubio.source."""
     4
    25import sys
    36import aubio
    47
    5 samplerate = 0 # use original source samplerate
    6 hop_size = 256 # number of frames to read in one block
     8samplerate = 0  # use original source samplerate
     9hop_size = 256  # number of frames to read in one block
    710src = aubio.source(sys.argv[1], samplerate, hop_size)
    811total_frames = 0
    912
    1013while True:
    11     samples, read = src()     # read hop_size new samples from source
    12     total_frames += read      # increment total number of frames
    13     if read < hop_size: break # end of file reached
     14    samples, read = src()  # read hop_size new samples from source
     15    total_frames += read   # increment total number of frames
     16    if read < hop_size:    # end of file reached
     17        break
    1418
    1519fmt_string = "read {:d} frames at {:d}Hz from {:s}"
    16 print (fmt_string.format(total_frames, src.samplerate, src.uri))
     20print(fmt_string.format(total_frames, src.samplerate, src.uri))
  • python/ext/py-sink.c

    ra9e3bd0 r568fc60  
    1515"sink(path, samplerate=44100, channels=1)\n"
    1616"\n"
    17 "Open `path` to write a WAV file.\n"
     17"Write audio samples to file.\n"
    1818"\n"
    1919"Parameters\n"
  • python/ext/py-source.c

    ra9e3bd0 r568fc60  
    1919"source(path, samplerate=0, hop_size=512, channels=0)\n"
    2020"\n"
    21 "Create a new source, opening the given pathname for reading.\n"
     21"Read audio samples from a media file.\n"
    2222"\n"
    2323"`source` open the file specified in `path` and creates a callable\n"
     
    248248"Returns\n"
    249249"-------\n"
    250 "samples : numpy.ndarray, shape `(hop_size,)`, dtype aubio.float_type\n"
     250"samples : numpy.ndarray\n"
    251251"    `fvec` of size `hop_size` containing the new samples.\n"
    252252"read : int\n"
     
    284284"Returns\n"
    285285"-------\n"
    286 "samples : np.ndarray([hop_size, channels], dtype=aubio.float_type)\n"
     286"samples : numpy.ndarray\n"
    287287"    NumPy array of shape `(hop_size, channels)` containing the new\n"
    288288"    audio samples.\n"
  • python/lib/aubio/__init__.py

    ra9e3bd0 r568fc60  
    2929from .midiconv import *
    3030from .slicing import *
     31
    3132
    3233class fvec(numpy.ndarray):
  • python/lib/aubio/cmd.py

    ra9e3bd0 r568fc60  
    1212import sys
    1313import argparse
     14import warnings
    1415import aubio
    1516
     
    169170
    170171    def add_verbose_help(self):
    171         self.add_argument("-v","--verbose",
     172        self.add_argument("-v", "--verbose",
    172173                action="count", dest="verbose", default=1,
    173174                help="make lots of noise [default]")
    174         self.add_argument("-q","--quiet",
     175        self.add_argument("-q", "--quiet",
    175176                action="store_const", dest="verbose", const=0,
    176177                help="be quiet")
     
    181182
    182183    def add_buf_size(self, buf_size=512):
    183         self.add_argument("-B","--bufsize",
     184        self.add_argument("-B", "--bufsize",
    184185                action="store", dest="buf_size", default=buf_size,
    185186                metavar = "<size>", type=int,
     
    187188
    188189    def add_hop_size(self, hop_size=256):
    189         self.add_argument("-H","--hopsize",
     190        self.add_argument("-H", "--hopsize",
    190191                metavar = "<size>", type=int,
    191192                action="store", dest="hop_size", default=hop_size,
     
    193194
    194195    def add_method(self, method='default', helpstr='method'):
    195         self.add_argument("-m","--method",
     196        self.add_argument("-m", "--method",
    196197                metavar = "<method>", type=str,
    197198                action="store", dest="method", default=method,
     
    199200
    200201    def add_threshold(self, default=None):
    201         self.add_argument("-t","--threshold",
     202        self.add_argument("-t", "--threshold",
    202203                metavar = "<threshold>", type=float,
    203204                action="store", dest="threshold", default=default,
     
    240241
    241242    def add_slicer_options(self):
    242         self.add_argument("-o","--output", type = str,
     243        self.add_argument("-o", "--output", type = str,
    243244                metavar = "<outputdir>",
    244245                action="store", dest="output_directory", default=None,
    245                 help="specify path where slices of the original file should be created")
     246                help="specify path where slices of the original file should"
     247                " be created")
    246248        self.add_argument("--cut-until-nsamples", type = int,
    247249                metavar = "<samples>",
    248250                action = "store", dest = "cut_until_nsamples", default = None,
    249                 help="how many extra samples should be added at the end of each slice")
     251                help="how many extra samples should be added at the end of"
     252                " each slice")
    250253        self.add_argument("--cut-every-nslices", type = int,
    251254                metavar = "<samples>",
     
    255258                metavar = "<slices>",
    256259                action = "store", dest = "cut_until_nslices", default = None,
    257                 help="how many extra slices should be added at the end of each slice")
     260                help="how many extra slices should be added at the end of"
     261                " each slice")
    258262        self.add_argument("--create-first",
    259263                action = "store_true", dest = "create_first", default = False,
     
    289293        if args.verbose > 2 and hasattr(self, 'options'):
    290294            name = type(self).__name__.split('_')[1]
    291             optstr = ' '.join(['running', name, 'with options', repr(self.options), '\n'])
     295            optstr = ' '.join(['running', name, 'with options',
     296                repr(self.options), '\n'])
    292297            sys.stderr.write(optstr)
    293298    def flush(self, frames_read, samplerate):
     
    297302    def parse_options(self, args, valid_opts):
    298303        # get any valid options found in a dictionnary of arguments
    299         options = {k :v for k,v in vars(args).items() if k in valid_opts}
     304        options = {k: v for k, v in vars(args).items() if k in valid_opts}
    300305        self.options = options
    301306
     
    378383            outstr = "unknown bpm"
    379384        else:
    380             bpms = 60./ np.diff(self.beat_locations)
     385            bpms = 60. / np.diff(self.beat_locations)
    381386            median_bpm = np.mean(bpms)
    382387            if len(self.beat_locations) < 10:
     
    399404        return self.notes(block)
    400405    def repr_res(self, res, frames_read, samplerate):
    401         if res[2] != 0: # note off
     406        if res[2] != 0:  # note off
    402407            fmt_out = self.time2string(frames_read, samplerate)
    403408            sys.stdout.write(fmt_out + '\n')
    404         if res[0] != 0: # note on
     409        if res[0] != 0:  # note on
    405410            lastmidi = res[0]
    406411            fmt_out = "%f\t" % lastmidi
    407412            fmt_out += self.time2string(frames_read, samplerate)
    408             sys.stdout.write(fmt_out) # + '\t')
     413            sys.stdout.write(fmt_out)  # + '\t')
    409414    def flush(self, frames_read, samplerate):
    410415        eof = self.time2string(frames_read, samplerate)
     
    473478            if self.wassilence != 1:
    474479                self.wassilence = 1
    475                 return 2 # newly found silence
    476             return 1 # silence again
     480                return 2   # newly found silence
     481            return 1       # silence again
    477482        else:
    478483            if self.wassilence != 0:
    479484                self.wassilence = 0
    480                 return -1 # newly found noise
    481             return 0 # noise again
     485                return -1  # newly found noise
     486            return 0       # noise again
    482487
    483488    def repr_res(self, res, frames_read, samplerate):
     
    499504    def __call__(self, block):
    500505        ret = super(process_cut, self).__call__(block)
    501         if ret: self.slices.append(self.onset.get_last())
     506        if ret:
     507            self.slices.append(self.onset.get_last())
    502508        return ret
    503509
    504510    def flush(self, frames_read, samplerate):
    505         from aubio.cut import _cut_slice
    506511        _cut_slice(self.options, self.slices)
    507         duration = float (frames_read) / float(samplerate)
    508         base_info = '%(source_file)s' % {'source_file': self.options.source_uri}
     512        duration = float(frames_read) / float(samplerate)
     513        base_info = '%(source_file)s' % \
     514                    {'source_file': self.options.source_uri}
    509515        base_info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % \
    510                 {'duration': duration, 'samplerate': samplerate}
     516                     {'duration': duration, 'samplerate': samplerate}
    511517        info = "created %d slices from " % len(self.slices)
    512518        info += base_info
    513519        sys.stderr.write(info)
     520
     521def _cut_slice(options, timestamps):
     522    # cutting pass
     523    nstamps = len(timestamps)
     524    if nstamps > 0:
     525        # generate output files
     526        timestamps_end = None
     527        if options.cut_every_nslices:
     528            timestamps = timestamps[::options.cut_every_nslices]
     529            nstamps = len(timestamps)
     530        if options.cut_until_nslices and options.cut_until_nsamples:
     531            msg = "using cut_until_nslices, but cut_until_nsamples is set"
     532            warnings.warn(msg)
     533        if options.cut_until_nsamples:
     534            lag = options.cut_until_nsamples
     535            timestamps_end = [t + lag for t in timestamps[1:]]
     536            timestamps_end += [1e120]
     537        if options.cut_until_nslices:
     538            slice_lag = options.cut_until_nslices
     539            timestamps_end = [t for t in timestamps[1 + slice_lag:]]
     540            timestamps_end += [1e120] * (options.cut_until_nslices + 1)
     541        aubio.slice_source_at_stamps(options.source_uri,
     542                timestamps, timestamps_end = timestamps_end,
     543                output_dir = options.output_directory,
     544                samplerate = options.samplerate,
     545                create_first = options.create_first)
    514546
    515547def main():
     
    526558                action="store_true", dest="show_version")
    527559        args, extras = parser_root.parse_known_args()
    528         if args.show_version == False: # no -V, forward to parser
     560        if not args.show_version: # no -V, forward to parser
    529561            args = parser.parse_args(extras, namespace=args)
    530         elif len(extras) != 0: # -V with other arguments, print help
     562        elif len(extras) != 0:     # -V with other arguments, print help
    531563            parser.print_help()
    532564            sys.exit(1)
    533     else: # in py3, we can simply use parser directly
     565    else:  # in py3, we can simply use parser directly
    534566        args = parser.parse_args()
    535567    if 'show_version' in args and args.show_version:
     
    538570    elif 'verbose' in args and args.verbose > 3:
    539571        sys.stderr.write('aubio version ' + aubio.version + '\n')
    540     if 'command' not in args or args.command is None or args.command in ['help']:
     572    if 'command' not in args or args.command is None \
     573            or args.command in ['help']:
    541574        # no command given, print help and return 1
    542575        parser.print_help()
     
    572605                frames_read += read
    573606                # exit loop at end of file
    574                 if read < a_source.hop_size: break
     607                if read < a_source.hop_size:
     608                    break
    575609            # flush the processor if needed
    576610            processor.flush(frames_read, a_source.samplerate)
     
    580614                fmt_string += " from {:s} at {:d}Hz\n"
    581615                sys.stderr.write(fmt_string.format(
    582                         frames_read/float(a_source.samplerate),
     616                        frames_read / float(a_source.samplerate),
    583617                        frames_read,
    584618                        frames_read // a_source.hop_size + 1,
  • python/lib/aubio/cut.py

    ra9e3bd0 r568fc60  
    66
    77import sys
    8 from aubio.cmd import AubioArgumentParser
     8from aubio.cmd import AubioArgumentParser, _cut_slice
    99
    1010def aubio_cut_parser():
    1111    parser = AubioArgumentParser()
    1212    parser.add_input()
    13     parser.add_argument("-O","--onset-method",
     13    parser.add_argument("-O", "--onset-method",
    1414            action="store", dest="onset_method", default='default',
    1515            metavar = "<onset_method>",
     
    1717                    complexdomain|hfc|phase|specdiff|energy|kl|mkl")
    1818    # cutting methods
    19     parser.add_argument("-b","--beat",
     19    parser.add_argument("-b", "--beat",
    2020            action="store_true", dest="beat", default=False,
    2121            help="slice at beat locations")
    2222    """
    23     parser.add_argument("-S","--silencecut",
     23    parser.add_argument("-S", "--silencecut",
    2424            action="store_true", dest="silencecut", default=False,
    2525            help="use silence locations")
    26     parser.add_argument("-s","--silence",
     26    parser.add_argument("-s", "--silence",
    2727            metavar = "<value>",
    2828            action="store", dest="silence", default=-70,
     
    3131    # algorithm parameters
    3232    parser.add_buf_hop_size()
    33     parser.add_argument("-t","--threshold", "--onset-threshold",
     33    parser.add_argument("-t", "--threshold", "--onset-threshold",
    3434            metavar = "<threshold>", type=float,
    3535            action="store", dest="threshold", default=0.3,
    3636            help="onset peak picking threshold [default=0.3]")
    37     parser.add_argument("-c","--cut",
     37    parser.add_argument("-c", "--cut",
    3838            action="store_true", dest="cut", default=False,
    3939            help="cut input sound file at detected labels")
     
    4141
    4242    """
    43     parser.add_argument("-D","--delay",
     43    parser.add_argument("-D", "--delay",
    4444            action = "store", dest = "delay", type = float,
    4545            metavar = "<seconds>", default=0,
    4646            help="number of seconds to take back [default=system]\
    4747                    default system delay is 3*hopsize/samplerate")
    48     parser.add_argument("-C","--dcthreshold",
     48    parser.add_argument("-C", "--dcthreshold",
    4949            metavar = "<value>",
    5050            action="store", dest="dcthreshold", default=1.,
    5151            help="onset peak picking DC component [default=1.]")
    52     parser.add_argument("-L","--localmin",
     52    parser.add_argument("-L", "--localmin",
    5353            action="store_true", dest="localmin", default=False,
    5454            help="use local minima after peak detection")
    55     parser.add_argument("-d","--derivate",
     55    parser.add_argument("-d", "--derivate",
    5656            action="store_true", dest="derivate", default=False,
    5757            help="derivate onset detection function")
    58     parser.add_argument("-z","--zerocross",
     58    parser.add_argument("-z", "--zerocross",
    5959            metavar = "<value>",
    6060            action="store", dest="zerothres", default=0.008,
    6161            help="zero-crossing threshold for slicing [default=0.00008]")
    6262    # plotting functions
    63     parser.add_argument("-p","--plot",
     63    parser.add_argument("-p", "--plot",
    6464            action="store_true", dest="plot", default=False,
    6565            help="draw plot")
    66     parser.add_argument("-x","--xsize",
     66    parser.add_argument("-x", "--xsize",
    6767            metavar = "<size>",
    6868            action="store", dest="xsize", default=1.,
    6969            type=float, help="define xsize for plot")
    70     parser.add_argument("-y","--ysize",
     70    parser.add_argument("-y", "--ysize",
    7171            metavar = "<size>",
    7272            action="store", dest="ysize", default=1.,
    7373            type=float, help="define ysize for plot")
    74     parser.add_argument("-f","--function",
     74    parser.add_argument("-f", "--function",
    7575            action="store_true", dest="func", default=False,
    7676            help="print detection function")
    77     parser.add_argument("-n","--no-onsets",
     77    parser.add_argument("-n", "--no-onsets",
    7878            action="store_true", dest="nplot", default=False,
    7979            help="do not plot detected onsets")
    80     parser.add_argument("-O","--outplot",
     80    parser.add_argument("-O", "--outplot",
    8181            metavar = "<output_image>",
    8282            action="store", dest="outplot", default=None,
    8383            help="save plot to output.{ps,png}")
    84     parser.add_argument("-F","--spectrogram",
     84    parser.add_argument("-F", "--spectrogram",
    8585            action="store_true", dest="spectro", default=False,
    8686            help="add spectrogram to the plot")
     
    106106
    107107    if options.beat:
    108         o = tempo(options.onset_method, bufsize, hopsize, samplerate=samplerate)
     108        o = tempo(options.onset_method, bufsize, hopsize,
     109                samplerate=samplerate)
    109110    else:
    110         o = onset(options.onset_method, bufsize, hopsize, samplerate=samplerate)
     111        o = onset(options.onset_method, bufsize, hopsize,
     112                samplerate=samplerate)
    111113        if options.minioi:
    112114            if options.minioi.endswith('ms'):
     
    123125        samples, read = s()
    124126        if o(samples):
    125             timestamps.append (o.get_last())
    126             if options.verbose: print ("%.4f" % o.get_last_s())
     127            timestamps.append(o.get_last())
     128            if options.verbose:
     129                print("%.4f" % o.get_last_s())
    127130        total_frames += read
    128         if read < hopsize: break
     131        if read < hopsize:
     132            break
    129133    del s
    130134    return timestamps, total_frames
    131 
    132 def _cut_slice(options, timestamps):
    133     # cutting pass
    134     nstamps = len(timestamps)
    135     if nstamps > 0:
    136         # generate output files
    137         from aubio.slicing import slice_source_at_stamps
    138         timestamps_end = None
    139         if options.cut_every_nslices:
    140             timestamps = timestamps[::options.cut_every_nslices]
    141             nstamps = len(timestamps)
    142         if options.cut_until_nslices and options.cut_until_nsamples:
    143             print ("warning: using cut_until_nslices, but cut_until_nsamples is set")
    144         if options.cut_until_nsamples:
    145             timestamps_end = [t + options.cut_until_nsamples for t in timestamps[1:]]
    146             timestamps_end += [ 1e120 ]
    147         if options.cut_until_nslices:
    148             timestamps_end = [t for t in timestamps[1 + options.cut_until_nslices:]]
    149             timestamps_end += [ 1e120 ] * (options.cut_until_nslices + 1)
    150         slice_source_at_stamps(options.source_uri,
    151                 timestamps, timestamps_end = timestamps_end,
    152                 output_dir = options.output_directory,
    153                 samplerate = options.samplerate,
    154                 create_first = options.create_first)
    155135
    156136def main():
     
    168148
    169149    # print some info
    170     duration = float (total_frames) / float(options.samplerate)
     150    duration = float(total_frames) / float(options.samplerate)
    171151    base_info = '%(source_uri)s' % {'source_uri': options.source_uri}
    172152    base_info += ' (total %(duration).2fs at %(samplerate)dHz)\n' % \
  • python/lib/aubio/midiconv.py

    ra9e3bd0 r568fc60  
    22""" utilities to convert midi note number to and from note names """
    33
    4 __all__ = ['note2midi', 'midi2note', 'freq2note', 'note2freq']
    5 
    64import sys
    75from ._aubio import freqtomidi, miditofreq
     6
     7__all__ = ['note2midi', 'midi2note', 'freq2note', 'note2freq']
    88
    99py3 = sys.version_info[0] == 3
     
    1414    str_instances = (str, unicode)
    1515    int_instances = (int, long)
     16
    1617
    1718def note2midi(note):
     
    5657    midi2note, freqtomidi, miditofreq
    5758    """
    58     _valid_notenames = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}
     59    _valid_notenames = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7,
     60                        'A': 9, 'B': 11}
    5961    _valid_modifiers = {
    60             u'𝄫': -2,                        # double flat
    61             u'♭': -1, 'b': -1, '\u266d': -1, # simple flat
    62             u'♮': 0, '\u266e': 0, None: 0,   # natural
    63             '#': +1, u'♯': +1, '\u266f': +1, # sharp
    64             u'𝄪': +2,                        # double sharp
     62            u'𝄫': -2,                         # double flat
     63            u'♭': -1, 'b': -1, '\u266d': -1,  # simple flat
     64            u'♮': 0, '\u266e': 0, None: 0,    # natural
     65            '#': +1, u'♯': +1, '\u266f': +1,  # sharp
     66            u'𝄪': +2,                         # double sharp
    6567            }
    6668    _valid_octaves = range(-1, 10)
     
    7173        msg = "string of 2 to 4 characters expected, got {:d} ({:s})"
    7274        raise ValueError(msg.format(len(note), note))
    73     notename, modifier, octave = [None]*3
     75    notename, modifier, octave = [None] * 3
    7476
    7577    if len(note) == 4:
     
    9496        raise ValueError("%s is not a valid octave" % octave)
    9597
    96     midi = 12 + octave * 12 + _valid_notenames[notename] \
    97             + _valid_modifiers[modifier]
     98    midi = (octave + 1) * 12 + _valid_notenames[notename] \
     99                             + _valid_modifiers[modifier]
    98100    if midi > 127:
    99101        raise ValueError("%s is outside of the range C-2 to G8" % note)
    100102    return midi
     103
    101104
    102105def midi2note(midi):
     
    137140        raise ValueError(msg.format(midi))
    138141    _valid_notenames = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#',
    139             'A', 'A#', 'B']
     142                        'A', 'A#', 'B']
    140143    return _valid_notenames[midi % 12] + str(int(midi / 12) - 1)
     144
    141145
    142146def freq2note(freq):
     
    163167    return midi2note(nearest_note)
    164168
     169
    165170def note2freq(note):
    166171    """Convert note name to corresponding frequency, in Hz.
  • python/lib/aubio/slicing.py

    ra9e3bd0 r568fc60  
    55
    66_max_timestamp = 1e120
     7
    78
    89def slice_source_at_stamps(source_file, timestamps, timestamps_end=None,
     
    7374    """
    7475
    75     if timestamps is None or len(timestamps) == 0:
     76    if not timestamps:
    7677        raise ValueError("no timestamps given")
    7778
     
    9091
    9192    regions = list(zip(timestamps, timestamps_end))
    92     #print regions
    9393
    9494    source_base_name, _ = os.path.splitext(os.path.basename(source_file))
     
    9898        source_base_name = os.path.join(output_dir, source_base_name)
    9999
    100     def new_sink_name(source_base_name, timestamp, samplerate):
    101         """ create a sink based on a timestamp in samples, converted in seconds """
     100    def _new_sink_name(source_base_name, timestamp, samplerate):
     101        # create name based on a timestamp in samples, converted in seconds
    102102        timestamp_seconds = timestamp / float(samplerate)
    103103        return source_base_name + "_%011.6f" % timestamp_seconds + '.wav'
     
    114114        vec, read = _source.do_multi()
    115115        # if the total number of frames read will exceed the next region start
    116         while len(regions) and total_frames + read >= regions[0][0]:
    117             #print "getting", regions[0], "at", total_frames
     116        while regions and total_frames + read >= regions[0][0]:
    118117            # get next region
    119118            start_stamp, end_stamp = regions.pop(0)
    120119            # create a name for the sink
    121             new_sink_path = new_sink_name(source_base_name, start_stamp, samplerate)
     120            new_sink_path = _new_sink_name(source_base_name, start_stamp,
     121                                           samplerate)
    122122            # create its sink
    123123            _sink = sink(new_sink_path, samplerate, _source.channels)
    124124            # create a dictionary containing all this
    125             new_slice = {'start_stamp': start_stamp, 'end_stamp': end_stamp, 'sink': _sink}
     125            new_slice = {'start_stamp': start_stamp, 'end_stamp': end_stamp,
     126                         'sink': _sink}
    126127            # append the dictionary to the current list of slices
    127128            slices.append(new_slice)
     
    135136            # number of samples yet to written be until end of region
    136137            remaining = end_stamp - total_frames + 1
    137             #print current_slice, remaining, start
    138138            # not enough frames remaining, time to split
    139139            if remaining < read:
     
    141141                    # write remaining samples from current region
    142142                    _sink.do_multi(vec[:, start:remaining], remaining - start)
    143                     #print("closing region", "remaining", remaining)
    144143                    # close this file
    145144                    _sink.close()
     
    150149        # remove old slices
    151150        slices = list(filter(lambda s: s['end_stamp'] > total_frames,
    152             slices))
     151                             slices))
    153152        if read < hopsize:
    154153            break
  • setup.py

    ra9e3bd0 r568fc60  
    11#! /usr/bin/env python
    22
    3 import sys, os.path, glob
     3import sys
     4import os.path
     5import glob
    46from setuptools import setup, Extension
    57
    68# add ./python/lib to current path
    7 sys.path.append(os.path.join('python', 'lib'))
     9sys.path.append(os.path.join('python', 'lib'))  # noqa
    810from moresetuptools import build_ext, CleanGenerated
    911
     
    1921extra_link_args = []
    2022
    21 include_dirs += [ 'python/ext' ]
     23include_dirs += ['python/ext']
    2224try:
    2325    import numpy
    24     include_dirs += [ numpy.get_include() ]
     26    include_dirs += [numpy.get_include()]
    2527except ImportError:
    2628    pass
    2729
    2830if sys.platform.startswith('darwin'):
    29     extra_link_args += ['-framework','CoreFoundation', '-framework','AudioToolbox']
     31    extra_link_args += ['-framework', 'CoreFoundation',
     32            '-framework', 'AudioToolbox']
    3033
    3134sources = sorted(glob.glob(os.path.join('python', 'ext', '*.c')))
     
    3841    define_macros = define_macros)
    3942
    40 if os.path.isfile('src/aubio.h'):
    41     if not os.path.isdir(os.path.join('build','src')):
    42         pass
    43         #__version__ += 'a2' # python only version
     43# TODO: find a way to track if package is built against libaubio
     44# if os.path.isfile('src/aubio.h'):
     45#     if not os.path.isdir(os.path.join('build','src')):
     46#         pass
     47#         #__version__ += 'a2' # python only version
    4448
    4549classifiers = [
     
    5559    'Programming Language :: C',
    5660    'Programming Language :: Python',
    57     'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
     61    'License :: OSI Approved :: '
     62    'GNU General Public License v3 or later (GPLv3+)',
    5863    ]
    5964
     
    6166    version = __version__,
    6267    packages = ['aubio'],
    63     package_dir = {'aubio':'python/lib/aubio'},
     68    package_dir = {'aubio': 'python/lib/aubio'},
    6469    ext_modules = [aubio_extension],
    6570    description = 'a collection of tools for music analysis',
  • wscript

    ra9e3bd0 r568fc60  
    4343            choices = ('debug', 'release'),
    4444            dest = 'build_type',
    45             help = 'whether to compile with (--build-type=release) or without (--build-type=debug) '\
    46               ' compiler opimizations [default: release]')
     45            help = 'whether to compile with (--build-type=release)' \
     46                    ' or without (--build-type=debug)' \
     47                    ' compiler opimizations [default: release]')
    4748    add_option_enable_disable(ctx, 'fftw3f', default = False,
    4849            help_str = 'compile with fftw3f instead of ooura (recommended)',
     
    110111
    111112    ctx.add_option('--with-target-platform', type='string',
    112             help='set target platform for cross-compilation', dest='target_platform')
     113            help='set target platform for cross-compilation',
     114            dest='target_platform')
    113115
    114116    ctx.load('compiler_c')
     
    206208            ctx.msg('Checking for AudioToolbox.framework', 'yes')
    207209        else:
    208             ctx.msg('Checking for AudioToolbox.framework', 'no (disabled)', color = 'YELLOW')
     210            ctx.msg('Checking for AudioToolbox.framework', 'no (disabled)',
     211                    color = 'YELLOW')
    209212        if (ctx.options.enable_accelerate != False):
    210213            ctx.define('HAVE_ACCELERATE', 1)
     
    212215            ctx.msg('Checking for Accelerate framework', 'yes')
    213216        else:
    214             ctx.msg('Checking for Accelerate framework', 'no (disabled)', color = 'YELLOW')
     217            ctx.msg('Checking for Accelerate framework', 'no (disabled)',
     218                    color = 'YELLOW')
    215219
    216220    if target_platform in [ 'ios', 'iosimulator' ]:
     
    266270        # tell emscripten functions we want to expose
    267271        from python.lib.gen_external import get_c_declarations, \
    268                 get_cpp_objects_from_c_declarations, get_all_func_names_from_lib, \
     272                get_cpp_objects_from_c_declarations, \
     273                get_all_func_names_from_lib, \
    269274                generate_lib_from_c_declarations
    270         c_decls = get_c_declarations(usedouble=False)  # emscripten can't use double
     275        # emscripten can't use double
     276        c_decls = get_c_declarations(usedouble=False)
    271277        objects = list(get_cpp_objects_from_c_declarations(c_decls))
    272278        # ensure that aubio structs are exported
     
    275281        exported_funcnames = get_all_func_names_from_lib(lib)
    276282        c_mangled_names = ['_' + s for s in exported_funcnames]
    277         ctx.env.LINKFLAGS_cshlib += ['-s', 'EXPORTED_FUNCTIONS=%s' % c_mangled_names]
     283        ctx.env.LINKFLAGS_cshlib += ['-s',
     284                'EXPORTED_FUNCTIONS=%s' % c_mangled_names]
    278285
    279286    # check support for C99 __VA_ARGS__ macros
     
    305312    # check for Intel IPP
    306313    if (ctx.options.enable_intelipp != False):
    307         has_ipp_headers = ctx.check(header_name=['ippcore.h', 'ippvm.h', 'ipps.h'],
    308                 mandatory = False)
     314        has_ipp_headers = ctx.check(header_name=['ippcore.h', 'ippvm.h',
     315            'ipps.h'], mandatory = False)
    309316        has_ipp_libs = ctx.check(lib=['ippcore', 'ippvm', 'ipps'],
    310317                uselib_store='INTEL_IPP', mandatory = False)
     
    313320            ctx.define('HAVE_INTEL_IPP', 1)
    314321            if ctx.env.CC_NAME == 'msvc':
    315                 # force linking multi-threaded static IPP libraries on Windows with msvc
     322                # force linking multi-threaded static IPP libraries on Windows
     323                # with msvc
    316324                ctx.define('_IPP_SEQUENTIAL_STATIC', 1)
    317325        else:
     
    362370    if (ctx.options.enable_double):
    363371        if (ctx.options.enable_samplerate):
    364             ctx.fatal("Could not compile aubio in double precision mode with libsamplerate")
     372            ctx.fatal("Could not compile aubio in double precision mode' \
     373                    ' with libsamplerate")
    365374        else:
    366375            ctx.options.enable_samplerate = False
    367             ctx.msg('Checking if using samplerate', 'no (disabled in double precision mode)',
    368                     color = 'YELLOW')
     376            ctx.msg('Checking if using samplerate',
     377                    'no (disabled in double precision mode)', color = 'YELLOW')
    369378    if (ctx.options.enable_samplerate != False):
    370379        ctx.check_cfg(package = 'samplerate',
     
    409418        elif 'HAVE_AVUTIL' not in ctx.env:
    410419            ctx.msg(msg_check, 'not found (missing avutil)', color = 'YELLOW')
    411         elif 'HAVE_SWRESAMPLE' not in ctx.env and 'HAVE_AVRESAMPLE' not in ctx.env:
     420        elif 'HAVE_SWRESAMPLE' not in ctx.env \
     421                and 'HAVE_AVRESAMPLE' not in ctx.env:
    412422            resample_missing = 'not found (avresample or swresample required)'
    413423            ctx.msg(msg_check, resample_missing, color = 'YELLOW')
     
    422432    if (ctx.options.enable_wavread != False):
    423433        ctx.define('HAVE_WAVREAD', 1)
    424     ctx.msg('Checking if using source_wavread', ctx.options.enable_wavread and 'yes' or 'no')
     434    ctx.msg('Checking if using source_wavread',
     435            ctx.options.enable_wavread and 'yes' or 'no')
    425436    if (ctx.options.enable_wavwrite!= False):
    426437        ctx.define('HAVE_WAVWRITE', 1)
    427     ctx.msg('Checking if using sink_wavwrite', ctx.options.enable_wavwrite and 'yes' or 'no')
     438    ctx.msg('Checking if using sink_wavwrite',
     439            ctx.options.enable_wavwrite and 'yes' or 'no')
    428440
    429441    # use BLAS/ATLAS
     
    543555
    544556def sphinx(bld):
    545     # build documentation from source files using sphinx-build
    546     # note: build in ../doc/_build/html, otherwise waf wont install unsigned files
     557    # build documentation from source files using sphinx-build note: build in
     558    # ../doc/_build/html, otherwise waf wont install unsigned files
    547559    if bld.env['SPHINX']:
    548560        bld.env.VERSION = VERSION
    549561        bld( name = 'sphinx',
    550                 rule = '${SPHINX} -b html -D release=${VERSION} -D version=${VERSION} -a -q `dirname ${SRC}` `dirname ${TGT}`',
     562                rule = '${SPHINX} -b html -D release=${VERSION}' \
     563                        ' -D version=${VERSION} -a -q' \
     564                        ' `dirname ${SRC}` `dirname ${TGT}`',
    551565                source = 'doc/conf.py',
    552566                target = '../doc/_build/html/index.html')
     
    578592    from waflib import Logs
    579593    if bld.options.target_platform in ['ios', 'iosimulator']:
    580         msg ='building for %s, contact the author for a commercial license' % bld.options.target_platform
     594        msg ='building for %s, contact the author for a commercial license' \
     595                % bld.options.target_platform
    581596        Logs.pprint('RED', msg)
    582597        msg ='   Paul Brossier <piem@aubio.org>'
     
    584599
    585600def dist(ctx):
    586     ctx.excl  = ' **/.waf* **/*~ **/*.pyc **/*.swp **/*.swo **/*.swn **/.lock-w* **/.git*'
     601    ctx.excl  = ' **/.waf*'
     602    ctx.excl += ' **/.git*'
     603    ctx.excl += ' **/*~ **/*.pyc **/*.swp **/*.swo **/*.swn **/.lock-w*'
    587604    ctx.excl += ' **/build/*'
    588605    ctx.excl += ' doc/_build'
     
    592609    ctx.excl += ' **/python/lib/aubio/_aubio.so'
    593610    ctx.excl += ' **.egg-info'
     611    ctx.excl += ' **/.eggs'
     612    ctx.excl += ' **/.pytest_cache'
     613    ctx.excl += ' **/.cache'
    594614    ctx.excl += ' **/**.zip **/**.tar.bz2'
    595615    ctx.excl += ' **.tar.bz2'
Note: See TracChangeset for help on using the changeset viewer.