Changeset 7c9ad74 for python/aubio


Ignore:
Timestamp:
Dec 19, 2005, 10:24:51 PM (19 years ago)
Author:
Paul Brossier <piem@altern.org>
Branches:
feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/pydocstrings, feature/timestretch, fix/ffmpeg5, master, pitchshift, sampler, timestretch, yinfft+
Children:
4f4a8a4
Parents:
50e99cc
Message:

added tasks fot onset, silence and cut
added tasks fot onset, silence and cut

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/aubio/tasks.py

    r50e99cc r7c9ad74  
    202202                self.derivate = False
    203203                self.localmin = False
     204                self.storefunc = False
    204205                self.bufsize = 512
    205206                self.hopsize = 256
     
    208209                self.step = float(self.hopsize)/float(self.samplerate)
    209210                self.threshold = 0.1
    210                 self.mode = 'yin'
     211                self.onsetmode = 'dual'
     212                self.pitchmode = 'yin'
    211213                self.omode = aubio_pitchm_freq
    212214
    213215class task(taskparams):
     216        """ default template class to apply tasks on a stream """
    214217        def __init__(self,input,output=None,params=None):
    215                 """ open the input file and initialize default argument """
     218                """ open the input file and initialize default argument
     219                parameters should be set *before* calling this method.
     220                """
    216221                if params == None: self.params = taskparams()
    217222                else: self.params = params
     223                self.frameread = 0
     224                self.readsize  = self.params.hopsize
    218225                self.input     = input
    219226                self.filei     = sndfile(self.input)
    220227                self.srate     = self.filei.samplerate()
    221228                self.channels  = self.filei.channels()
     229                self.step      = float(self.srate)/float(self.params.hopsize)
     230                self.myvec     = fvec(self.params.hopsize,self.channels)
    222231                self.output    = output
    223         def compute_step(self):
    224                 pass
     232        def __call__(self):
     233                self.readsize = self.filei.read(self.params.hopsize,self.myvec)
     234                self.frameread += 1
     235               
    225236        def compute_all(self):
    226237                """ Compute data """
    227238                mylist    = []
    228239                while(self.readsize==self.params.hopsize):
    229                         mylist.append(self())
     240                        tmp = self()
     241                        if tmp: mylist.append(tmp)
    230242                return mylist
    231243
     
    238250                pass
    239251
     252class tasksilence(task):
     253        wassilence = 1
     254        issilence  = 1
     255        def __call__(self):
     256                task.__call__(self)
     257                if (aubio_silence_detection(self.myvec(),self.params.silence)==1):
     258                        if self.wassilence == 1: self.issilence = 1
     259                        else: self.issilence = 2
     260                        self.wassilence = 1
     261                else:
     262                        if self.wassilence <= 0: self.issilence = 0
     263                        else: self.issilence = -1
     264                        self.wassilence = 0
     265                if self.issilence == -1:
     266                        return -1, self.frameread
     267                elif self.issilence == 2:
     268                        return 2, self.frameread
     269
    240270class taskpitch(task):
    241         #def __init__(self,input,output):
    242         #       pass
    243         #       task.__init__(self,input)
    244         #       #taskparams.__init__(self)
    245271        def __init__(self,input,params=None):
    246272                task.__init__(self,input,params=params)
    247                 self.myvec     = fvec(self.params.hopsize,self.channels)
    248                 self.frameread = 0
    249                 self.readsize  = self.params.hopsize
    250                 self.pitchdet  = pitchdetection(mode=get_pitch_mode(self.params.mode),
     273                self.pitchdet  = pitchdetection(mode=get_pitch_mode(self.params.pitchmode),
    251274                        bufsize=self.params.bufsize,
    252275                        hopsize=self.params.hopsize,
     
    256279
    257280        def __call__(self):
    258                 self.readsize = self.filei.read(self.params.hopsize,self.myvec)
     281                #print "%.3f     %.2f" % (now,freq)
     282                task.__call__(self)
    259283                freq = self.pitchdet(self.myvec)
    260                 #print "%.3f     %.2f" % (now,freq)
    261                 self.frameread += 1
    262284                if (aubio_silence_detection(self.myvec(),self.params.silence)!=1):
    263285                        return freq
     
    266288
    267289        def gettruth(self):
     290                """ big hack to extract midi note from /path/to/file.<midinote>.wav """
    268291                return float(self.input.split('.')[-2])
    269292               
     
    281304                                sum += i
    282305                                num += 1
    283                 avg = aubio_freqtomidi(sum / float(num))
     306                if num == 0:
     307                        avg = 0; med = 0
     308                else:
     309                        avg = aubio_freqtomidi(sum / float(num))
     310                        med = aubio_freqtomidi(short_find(res,len(res)/2))
    284311                avgdist = self.truth - avg
    285                 med = aubio_freqtomidi(short_find(res,len(res)/2))
    286312                meddist = self.truth - med
    287313                return avgdist, meddist
     
    296322
    297323
    298 
     324class taskonset(task):
     325        def __init__(self,input,output=None,params=None):
     326                """ open the input file and initialize arguments
     327                parameters should be set *before* calling this method.
     328                """
     329                task.__init__(self,input,params=params)
     330                self.opick = onsetpick(self.params.bufsize,
     331                        self.params.hopsize,
     332                        self.channels,
     333                        self.myvec,
     334                        self.params.threshold,
     335                        mode=get_onset_mode(self.params.onsetmode),
     336                        derivate=self.params.derivate)
     337                self.olist = []
     338                self.ofunc = []
     339                self.d,self.d2 = [],[]
     340                self.maxofunc = 0
     341                if self.params.localmin:
     342                        ovalist   = [0., 0., 0., 0., 0.]
     343
     344        def __call__(self):
     345                task.__call__(self)
     346                isonset,val = self.opick.do(self.myvec)
     347                if (aubio_silence_detection(self.myvec(),self.params.silence)):
     348                        isonset=0
     349                if self.params.storefunc:
     350                        self.ofunc.append(val)
     351                if self.params.localmin:
     352                        if val > 0: ovalist.append(val)
     353                        else: ovalist.append(0)
     354                        ovalist.pop(0)
     355                if (isonset == 1):
     356                        if self.params.localmin:
     357                                i=len(self.ovalist)-1
     358                                # find local minima before peak
     359                                while self.ovalist[i-1] < self.ovalist[i] and i > 0:
     360                                        i -= 1
     361                                now = (self.frameread+1-i)
     362                        else:
     363                                now = self.frameread
     364                        if now < 0 :
     365                                now = 0
     366                        return now, val
     367
     368        def eval(self,lres):
     369                from txtfile import read_datafile
     370                from onsetcompare import onset_roc
     371                amode = 'roc'
     372                vmode = 'verbose'
     373                vmode = ''
     374                for i in range(len(lres)): lres[i] = lres[i][0]*self.params.step
     375                ltru = read_datafile(self.input.replace('.wav','.txt'),depth=0)
     376                if vmode=='verbose':
     377                        print "Running with mode %s" % self.params.mode,
     378                        print " and threshold %f" % self.params.threshold,
     379                        print " on file", input
     380                #print ltru; print lres
     381                if amode == 'localisation':
     382                        l = onset_diffs(ltru,lres,self.params.tol)
     383                        mean = 0
     384                        for i in l: mean += i
     385                        if len(l): print "%.3f" % (mean/len(l))
     386                        else: print "?0"
     387                elif amode == 'roc':
     388                        self.orig, self.missed, self.merged, \
     389                                self.expc, self.bad, self.doubled = \
     390                                onset_roc(ltru,lres,self.params.tol)
     391
     392        def plot(self,onsets,ofunc):
     393                import Gnuplot, Gnuplot.funcutils
     394                import aubio.txtfile
     395                import os.path
     396                import numarray
     397                from aubio.onsetcompare import onset_roc
     398
     399                self.lenofunc = len(ofunc)
     400                self.maxofunc = max(max(ofunc), self.maxofunc)
     401                # onset detection function
     402                downtime = numarray.arange(len(ofunc))/self.step
     403                self.d.append(Gnuplot.Data(downtime,ofunc,with='lines'))
     404
     405                # detected onsets
     406                x1 = numarray.array(onsets)/self.step
     407                y1 = self.maxofunc*numarray.ones(len(onsets))
     408                self.d.append(Gnuplot.Data(x1,y1,with='impulses'))
     409                self.d2.append(Gnuplot.Data(x1,-y1,with='impulses'))
     410
     411                # check if datafile exists truth
     412                datafile = self.input.replace('.wav','.txt')
     413                if datafile == self.input: datafile = ""
     414                if not os.path.isfile(datafile):
     415                        self.title = "truth file not found"
     416                        t = Gnuplot.Data(0,0,with='impulses')
     417                else:
     418                        t_onsets = aubio.txtfile.read_datafile(datafile)
     419                        y2 = self.maxofunc*numarray.ones(len(t_onsets))
     420                        x2 = numarray.array(t_onsets).resize(len(t_onsets))
     421                        self.d2.append(Gnuplot.Data(x2,y2,with='impulses'))
     422                       
     423                        tol = 0.050
     424
     425                        orig, missed, merged, expc, bad, doubled = \
     426                                onset_roc(x2,x1,tol)
     427                        self.title = "GD %2.3f%% FP %2.3f%%" % \
     428                                ((100*float(orig-missed-merged)/(orig)),
     429                                 (100*float(bad+doubled)/(orig)))
     430
     431
     432        def plotplot(self,outplot=None):
     433                from aubio.gnuplot import gnuplot_init, audio_to_array, make_audio_plot
     434                import re
     435                # audio data
     436                time,data = audio_to_array(self.input)
     437                self.d2.append(make_audio_plot(time,data))
     438                # prepare the plot
     439                g = gnuplot_init(outplot)
     440
     441                g('set title \'%s %s\'' % (re.sub('.*/','',self.input),self.title))
     442
     443                g('set multiplot')
     444
     445                # hack to align left axis
     446                g('set lmargin 15')
     447
     448                # plot waveform and onsets
     449                g('set size 1,0.3')
     450                g('set origin 0,0.7')
     451                g('set xrange [0:%f]' % max(time))
     452                g('set yrange [-1:1]')
     453                g.ylabel('amplitude')
     454                g.plot(*self.d2)
     455               
     456                g('unset title')
     457
     458                # plot onset detection function
     459                g('set size 1,0.7')
     460                g('set origin 0,0')
     461                g('set xrange [0:%f]' % (self.lenofunc/self.step))
     462                g('set yrange [0:%f]' % (self.maxofunc*1.01))
     463                g.xlabel('time')
     464                g.ylabel('onset detection value')
     465                g.plot(*self.d)
     466
     467                g('unset multiplot')
     468
     469class taskcut(task):
     470        def __init__(self,input,slicetimes,params=None,output=None):
     471                """ open the input file and initialize arguments
     472                parameters should be set *before* calling this method.
     473                """
     474                task.__init__(self,input,output=None,params=params)
     475                self.newname   = "%s%s%09.5f%s%s" % (self.input.split(".")[0].split("/")[-1],".",
     476                                        self.frameread/self.step,".",self.input.split(".")[-1])
     477                self.fileo       = sndfile(self.newname,model=self.filei)
     478                self.myvec       = fvec(self.params.hopsize,self.channels)
     479                self.mycopy     = fvec(self.params.hopsize,self.channels)
     480                self.slicetimes = slicetimes
     481
     482        def __call__(self):
     483                task.__call__(self)
     484                # write to current file
     485                if len(self.slicetimes) and self.frameread >= self.slicetimes[0]:
     486                        self.slicetimes.pop(0)
     487                        # write up to 1st zero crossing
     488                        zerocross = 0
     489                        while ( abs( self.myvec.get(zerocross,0) ) > self.params.zerothres ):
     490                                zerocross += 1
     491                        writesize = self.fileo.write(zerocross,self.myvec)
     492                        fromcross = 0
     493                        while (zerocross < self.readsize):
     494                                for i in range(self.channels):
     495                                        self.mycopy.set(self.myvec.get(zerocross,i),fromcross,i)
     496                                        fromcross += 1
     497                                        zerocross += 1
     498                        del self.fileo
     499                        self.fileo = sndfile("%s%s%09.5f%s%s" %
     500                                (self.input.split(".")[0].split("/")[-1],".",
     501                                self.frameread/self.step,".",self.input.split(".")[-1]),model=self.filei)
     502                        writesize = self.fileo.write(fromcross,self.mycopy)
     503                else:
     504                        writesize = self.fileo.write(self.readsize,self.myvec)
Note: See TracChangeset for help on using the changeset viewer.