Remove dtmf2num - warvox - VoIP based wardialing tool, forked from rapid7/warvox.
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit 3f4572631842f38da7c8020f2632b3238b6ae055
 (DIR) parent edcebe28cb22ff7f9e7091638c88bd7c5ea4df84
 (HTM) Author: HD Moore <hd_moore@rapid7.com>
       Date:   Wed, 26 Dec 2012 23:15:36 -0600
       
       Remove dtmf2num
       
       Diffstat:
         M Gemfile.lock                        |      17 +++++++----------
         M Makefile                            |       9 +--------
         M app/views/analyze/view.html.erb     |       6 ------
         M app/views/analyze/view_matches.htm… |      36 +++++++++++---------------------
         M bin/verify_install.rb               |       7 -------
         M config/warvox.conf                  |       5 ++---
         M db/schema.rb                        |       2 --
         M docs/ChangeLog                      |       1 +
         M lib/warvox/jobs/analysis.rb         |      22 ----------------------
         D src/dtmf2num/Makefile               |      16 ----------------
         D src/dtmf2num/README                 |       5 -----
         D src/dtmf2num/dsp.c                  |     502 -------------------------------
         D src/dtmf2num/dtmf2num.c             |     372 -------------------------------
         D src/dtmf2num/mywav.h                |     244 -------------------------------
         D src/dtmf2num/resample2.c            |     342 -------------------------------
       
       15 files changed, 23 insertions(+), 1563 deletions(-)
       ---
 (DIR) diff --git a/Gemfile.lock b/Gemfile.lock
       @@ -37,13 +37,10 @@ GEM
              coffee-script-source
              execjs
            coffee-script-source (1.4.0)
       -    delayed_job (3.0.4)
       -      activesupport (~> 3.0)
       -    delayed_job_active_record (0.3.3)
       -      activerecord (>= 2.1.0, < 4)
       -      delayed_job (~> 3.0)
       +    daemons (1.1.9)
            dynamic_form (1.1.4)
            erubis (2.7.0)
       +    eventmachine (1.0.0)
            execjs (1.4.0)
              multi_json (~> 1.0)
            hike (1.2.1)
       @@ -88,7 +85,6 @@ GEM
            rake (10.0.3)
            rdoc (3.12)
              json (~> 1.4)
       -    ref (1.0.2)
            sass (3.2.4)
            sass-rails (3.2.5)
              railties (~> 3.2.0)
       @@ -98,8 +94,10 @@ GEM
              hike (~> 1.2)
              rack (~> 1.0)
              tilt (~> 1.1, != 1.3.0)
       -    therubyracer (0.11.0)
       -      ref
       +    thin (1.5.0)
       +      daemons (>= 1.0.9)
       +      eventmachine (>= 0.12.6)
       +      rack (>= 1.0.0)
            thor (0.16.0)
            tilt (1.3.3)
            treetop (1.4.12)
       @@ -116,7 +114,6 @@ PLATFORMS
        
        DEPENDENCIES
          coffee-rails (~> 3.2.1)
       -  delayed_job_active_record
          dynamic_form
          jquery-rails
          kissfft
       @@ -124,6 +121,6 @@ DEPENDENCIES
          pg (= 0.11)
          rails (= 3.2.8)
          sass-rails (~> 3.2.3)
       -  therubyracer
       +  thin
          uglifier (>= 1.0.3)
          will_paginate (~> 3.0)
 (DIR) diff --git a/Makefile b/Makefile
       @@ -3,11 +3,7 @@ all: test
        test: install
                bin/verify_install.rb
        
       -install: bundler dtmf2num
       -        cp -a src/dtmf2num/dtmf2num bin/
       -
       -dtmf2num:
       -        make -C src/dtmf2num/
       +install: bundler
        
        db:
                @echo "Checking the database.."
       @@ -22,6 +18,3 @@ bundler:
        
                @echo "Installing missing gems as needed.."
                bundle install
       -
       -clean:
       -        make -C src/dtmf2num/ clean
 (DIR) diff --git a/app/views/analyze/view.html.erb b/app/views/analyze/view.html.erb
       @@ -38,12 +38,6 @@
                        Provider: <%=h dial_result.provider.name %><br/>
                        Audio: <%=h dial_result.seconds %> Seconds<br/>
                        Ringer: <%=h dial_result.ringtime %> Seconds<br/>
       -                <% if(dial_result.dtmf and dial_result.dtmf.length > 0) %>
       -                        DTMF: <%=h dial_result.dtmf %><br/>
       -                <% end %>
       -                <% if(dial_result.mf and dial_result.mf.length > 0) %>
       -                        MF: <%=h dial_result.mf %><br/>
       -                <% end %>
                </td>
                  <td align='center'>
                        <b><%=h dial_result.line_type.upcase %></b><br/>
 (DIR) diff --git a/app/views/analyze/view_matches.html.erb b/app/views/analyze/view_matches.html.erb
       @@ -10,10 +10,10 @@
        
          <tr>
            <td align='center'>
       -        
       +
                        <object
                                type="application/x-shockwave-flash"
       -                        data="/assets/musicplayer.swf?song_url=<%=resource_analyze_path(@job_id, dial_result.id, "mp3")%>" 
       +                        data="/assets/musicplayer.swf?song_url=<%=resource_analyze_path(@job_id, dial_result.id, "mp3")%>"
                                width="20"
                                height="17"
                                style="margin-bottom: -5px;"
       @@ -21,31 +21,25 @@
                                <param name="movie" value="/assets/musicplayer.swf?song_url=<%=resource_analyze_path(@job_id, dial_result.id, "mp3")%>"></param>
                                <param name="wmode" value="transparent"></param>
                        </object>
       -                
       +
                        <b><%= dial_result.number %></b>
                        <hr width='100%' size='1'/>
                        CallerID: <%= dial_result.cid%><br/>
                        Provider: <%=h dial_result.provider.name %><br/>
                        Audio: <%=h dial_result.seconds %> Seconds<br/>
                        Ringer: <%=h dial_result.ringtime %> Seconds<br/>
       -                <% if(dial_result.dtmf and dial_result.dtmf.length > 0) %>
       -                        DTMF: <%=h dial_result.dtmf %><br/>
       -                <% end %>
       -                <% if(dial_result.mf and dial_result.mf.length > 0) %>
       -                        MF: <%=h dial_result.mf %><br/>
       -                <% end %>                                        
                </td>
                  <td align='center'>
                        <b><%=h dial_result.line_type.upcase %></b><br/>
                        <a href="<%=resource_analyze_path(@job_id, dial_result.id, "big_sig_dots")%>" rel="lightbox"><img src="<%=resource_analyze_path(@job_id, dial_result.id, "small_sig")%>" /></a>
                        <a href="<%=resource_analyze_path(@job_id, dial_result.id, "big_freq")%>" rel="lightbox"><img src="<%=resource_analyze_path(@job_id, dial_result.id, "small_freq")%>" /></a><br/>
       -                <% (dial_result.signatures||"").split("\n").each do |s| 
       +                <% (dial_result.signatures||"").split("\n").each do |s|
                                sid,mat,name = s.split(':', 3)
                                str = [mat.to_i * 6.4, 255].min
                                col = ("%.2x" % (255 - str)) * 3
                        %>
                                <div style="color: #<%= col%>;"><%=h name%> (<%=h sid %>@<%=h mat %>)</div>
       -                <% end %>                                
       +                <% end %>
                </td>
          </tr>
        </table><br/><br/>
       @@ -61,12 +55,12 @@
        <%  @results.each do |dial_result| %>
          <tr>
            <td align='center'>
       -        
       +
                        <br/><%= raw(fwd_match_html(dial_result.matchscore)) %><br/><br/>
       -                
       +
                        <object
                                type="application/x-shockwave-flash"
       -                        data="/assets/musicplayer.swf?song_url=<%=resource_analyze_path(@job_id, dial_result.id, "mp3")%>" 
       +                        data="/assets/musicplayer.swf?song_url=<%=resource_analyze_path(@job_id, dial_result.id, "mp3")%>"
                                width="20"
                                height="17"
                                style="margin-bottom: -5px;"
       @@ -74,34 +68,28 @@
                                <param name="movie" value="/assets/musicplayer.swf?song_url=<%=resource_analyze_path(@job_id, dial_result.id, "mp3")%>"></param>
                                <param name="wmode" value="transparent"></param>
                        </object>
       -                
       +
                        <b><%= dial_result.number %></b>
                        <hr width='100%' size='1'/>
                        CallerID: <%= dial_result.cid%><br/>
                        Provider: <%=h dial_result.provider.name %><br/>
                        Audio: <%=h dial_result.seconds %> Seconds<br/>
                        Ringer: <%=h dial_result.ringtime %> Seconds<br/>
       -                <% if(dial_result.dtmf and dial_result.dtmf.length > 0) %>
       -                        DTMF: <%=h dial_result.dtmf %><br/>
       -                <% end %>
       -                <% if(dial_result.mf and dial_result.mf.length > 0) %>
       -                        MF: <%=h dial_result.mf %><br/>
       -                <% end %>                                        
                </td>
                  <td align='center'>
                        <b><%=h dial_result.line_type.upcase %></b><br/>
                        <a href="<%=resource_analyze_path(@job_id, dial_result.id, "big_sig_dots")%>" rel="lightbox"><img src="<%=resource_analyze_path(@job_id, dial_result.id, "small_sig")%>" /></a>
                        <a href="<%=resource_analyze_path(@job_id, dial_result.id, "big_freq")%>" rel="lightbox"><img src="<%=resource_analyze_path(@job_id, dial_result.id, "small_freq")%>" /></a><br/>
       -                <% (dial_result.signatures||"").split("\n").each do |s| 
       +                <% (dial_result.signatures||"").split("\n").each do |s|
                                sid,mat,name = s.split(':', 3)
                                str = [mat.to_i * 6.4, 255].min
                                col = ("%.2x" % (255 - str)) * 3
                        %>
                                <div style="color: #<%= col%>;"><%=h name%> (<%=h sid %>@<%=h mat %>)</div>
       -                <% end %>                        
       +                <% end %>
                        <% if dial_result.fprint %>
                                <a href="<%=view_matches_path(dial_result.id)%>">View Matches</a>
       -                <% end %>                
       +                <% end %>
                </td>
          </tr>
        <% end %>
 (DIR) diff --git a/bin/verify_install.rb b/bin/verify_install.rb
       @@ -56,13 +56,6 @@ end
        puts "[*] The LAME binary appears to be available"
        
        
       -if(not WarVOX::Config.tool_path('dtmf2num'))
       -        puts "[*] ERROR: The 'dtmf2num' binary could not be installed"
       -        exit
       -end
       -puts "[*] The DTMF2NUM binary appears to be available"
       -
       -
        puts " "
        puts "[*] Congratulations! You are almost ready to run WarVOX"
        puts " "
 (DIR) diff --git a/config/warvox.conf b/config/warvox.conf
       @@ -24,7 +24,6 @@ tools:
          gnuplot: gnuplot
          lame: lame
          iaxrecord: "%BASE%/bin/iaxrecord.rb"
       -  dtmf2num: "%BASE%/bin/dtmf2num"
        
        #
        # Concurrent processing jobs, change this to
       @@ -37,9 +36,9 @@ analysis_threads: 2
        #
        # Configure the dial blacklist location
        #
       -blacklist: "%BASE%/etc/blacklist.txt"
       +blacklist: "%BASE%/config/blacklist.txt"
        
        #
        # Configure the signature directory
        #
       -signatures: "%BASE%/etc/sigs"
       +signatures: "%BASE%/config/sigs"
 (DIR) diff --git a/db/schema.rb b/db/schema.rb
       @@ -50,8 +50,6 @@ ActiveRecord::Schema.define(:version => 20110801000003) do
            t.text     "line_type"
            t.text     "notes"
            t.text     "signatures"
       -    t.text     "dtmf"
       -    t.text     "mf"
            t.string   "fprint",         :limit => nil
            t.binary   "audio"
            t.binary   "mp3"
 (DIR) diff --git a/docs/ChangeLog b/docs/ChangeLog
       @@ -1,6 +1,7 @@
        2012-12-26  HD Moore <hdm[at]rapid7.com>
         * overhauled, updated gems, merged directories with web
         * swapped in Rapid7-licensed Highcharts for graphics
       + * remove dtmf2num (limited value, too inaccurate)
        
        2011-02-23  HD Moore <hdm[at]rapid7.com>
         * bumped the version number to 1.2.0
 (DIR) diff --git a/lib/warvox/jobs/analysis.rb b/lib/warvox/jobs/analysis.rb
       @@ -323,27 +323,6 @@ class Analysis < Base
        
                        [png_big, png_big_dots, png_big_freq, png_sig, png_sig_freq ].map {|x| x.unlink; x.close }
        
       -
       -                # Detect DTMF and MF tones
       -                dtmf = ''
       -                mf   = ''
       -                pfd = IO.popen("#{WarVOX::Config.tool_path('dtmf2num')} -r 8000 1 16 #{rawfile.path} 2>/dev/null")
       -                pfd.each_line do |line|
       -                        line = line.strip
       -                        if(line.strip =~ /^- MF numbers:\s+(.*)/)
       -                                next if $1 == 'none'
       -                                mf = $1
       -                        end
       -                        if(line.strip =~ /^- DTMF numbers:\s+(.*)/)
       -                                next if $1 == 'none'
       -                                dtmf = $1
       -                        end
       -                end
       -                pfd.close
       -                res[:dtmf] = dtmf
       -                res[:mf]   = mf
       -
       -
                        tmp_wav = Tempfile.new("wav")
                        tmp_mp3 = Tempfile.new("mp3")
        
       @@ -418,4 +397,3 @@ end
        
        end
        end
       -
 (DIR) diff --git a/src/dtmf2num/Makefile b/src/dtmf2num/Makefile
       @@ -1,16 +0,0 @@
       -EXE     = dtmf2num
       -CFLAGS        += -O2 -s
       -BINDIR        = $(PREFIX)/bin
       -LIBS        = -lm
       -
       -all:
       -        $(CC) $(CFLAGS) -c dtmf2num.c
       -        $(CC) $(CFLAGS) -c dsp.c
       -        $(CC) $(CFLAGS) -c resample2.c
       -        $(CC) $(CFLAGS) -o $(EXE) dtmf2num.o dsp.o resample2.o $(LIBS)
       -
       -clean:
       -        @rm -f *.o $(EXE)
       -        
       -.PHONY:
       -        install
 (DIR) diff --git a/src/dtmf2num/README b/src/dtmf2num/README
       @@ -1,5 +0,0 @@
       -This is a barely tweaked copy of DTMF2NUM, developed by Luigi Auriemma
       -        - http://aluigi.org/mytoolz.htm#dtmf2num
       -
       -This tool is provided under the GPL:
       -        - http://www.gnu.org/licenses/gpl.txt
 (DIR) diff --git a/src/dtmf2num/dsp.c b/src/dtmf2num/dsp.c
       @@ -1,502 +0,0 @@
       -/*
       - * Asterisk -- An open source telephony toolkit.
       - *
       - * Copyright (C) 1999 - 2005, Digium, Inc.
       - *
       - * Mark Spencer <markster@digium.com>
       - *
       - * Goertzel routines are borrowed from Steve Underwood's tremendous work on the
       - * DTMF detector.
       - *
       - * See http://www.asterisk.org for more information about
       - * the Asterisk project. Please do not directly contact
       - * any of the maintainers of this project for assistance;
       - * the project provides a web site, mailing lists and IRC
       - * channels for your use.
       - *
       - * This program is free software, distributed under the terms of
       - * the GNU General Public License Version 2. See the LICENSE file
       - * at the top of the source tree.
       - */
       -
       -/*! \file
       - *
       - * \brief Convenience Signal Processing routines
       - *
       - * \author Mark Spencer <markster@digium.com>
       - * \author Steve Underwood <steveu@coppice.org>
       - */
       -
       -/* Some routines from tone_detect.c by Steven Underwood as published under the zapata library */
       -/*
       -        tone_detect.c - General telephony tone detection, and specific
       -                                        detection of DTMF.
       -
       -        Copyright (C) 2001  Steve Underwood <steveu@coppice.org>
       -
       -        Despite my general liking of the GPL, I place this code in the
       -        public domain for the benefit of all mankind - even the slimy
       -        ones who might try to proprietize my work and use it to my
       -        detriment.
       -*/
       -
       -/*
       -  modifications for decoding also damaged audio by Luigi auriemma "// aluigi work-around"
       -*/
       -
       -#include <stdio.h>
       -#include <stdlib.h>
       -#include <string.h>
       -#include <stdint.h>
       -#include <math.h>
       -#include <malloc.h>
       -
       -#define        DSP_DIGITMODE_DTMF                        0                                /*!< Detect DTMF digits */
       -#define DSP_DIGITMODE_MF                        1                                /*!< Detect MF digits */
       -
       -#define DSP_DIGITMODE_NOQUELCH                (1 << 8)                /*!< Do not quelch DTMF from in-band */
       -#define DSP_DIGITMODE_RELAXDTMF                (1 << 11)                /*!< "Radio" mode (relaxed DTMF) */
       -
       -#define        MAX_DTMF_DIGITS                1024
       -
       -/* Basic DTMF specs:
       - *
       - * Minimum tone on = 40ms
       - * Minimum tone off = 50ms
       - * Maximum digit rate = 10 per second
       - * Normal twist <= 8dB accepted
       - * Reverse twist <= 4dB accepted
       - * S/N >= 15dB will detect OK
       - * Attenuation <= 26dB will detect OK
       - * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
       - */
       -
       -//#define DTMF_THRESHOLD                8.0e7
       -#define DTMF_THRESHOLD      800000000.0 // aluigi work-around
       -#define DTMF_NORMAL_TWIST        6.3     /* 8dB */
       -#ifdef        RADIO_RELAX
       -#define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 6.5 : 2.5)     /* 4dB normal */
       -#else
       -#define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5)     /* 4dB normal */
       -#endif
       -#define DTMF_RELATIVE_PEAK_ROW        6.3     /* 8dB */
       -#define DTMF_RELATIVE_PEAK_COL        6.3     /* 8dB */
       -#define DTMF_2ND_HARMONIC_ROW       ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5)     /* 4dB normal */
       -#define DTMF_2ND_HARMONIC_COL        63.1    /* 18dB */
       -#define DTMF_TO_TOTAL_ENERGY        42.0
       -
       -//#define BELL_MF_THRESHOLD        1.6e9
       -#define BELL_MF_THRESHOLD   DTMF_THRESHOLD  // aluigi work-around
       -#define BELL_MF_TWIST                4.0     /* 6dB */
       -#define BELL_MF_RELATIVE_PEAK        12.6    /* 11dB */
       -
       -static int SAMPLE_RATE = 8000;
       -
       -typedef struct {
       -        int v2;
       -        int v3;
       -        int chunky;
       -        int fac;
       -        int samples;
       -} goertzel_state_t;
       -
       -typedef struct {
       -        int value;
       -        int power;
       -} goertzel_result_t;
       -
       -typedef struct
       -{
       -        goertzel_state_t row_out[4];
       -        goertzel_state_t col_out[4];
       -        int lasthit;
       -        int current_hit;
       -        float energy;
       -        int current_sample;
       -} dtmf_detect_state_t;
       -
       -typedef struct
       -{
       -        goertzel_state_t tone_out[6];
       -        int current_hit;
       -        int hits[5];
       -        int current_sample;
       -} mf_detect_state_t;
       -
       -typedef struct
       -{
       -        char digits[MAX_DTMF_DIGITS + 1];
       -        int current_digits;
       -        int detected_digits;
       -        int lost_digits;
       -
       -        union {
       -                dtmf_detect_state_t dtmf;
       -                mf_detect_state_t mf;
       -        } td;
       -} digit_detect_state_t;
       -
       -static float dtmf_row[] =
       -{
       -        697.0,  770.0,  852.0,  941.0
       -};
       -static float dtmf_col[] =
       -{
       -        1209.0, 1336.0, 1477.0, 1633.0
       -};
       -
       -static float mf_tones[] =
       -{
       -        700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
       -};
       -
       -static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
       -
       -static char bell_mf_positions[] = "1247C-358A--69*---0B----#";
       -
       -static inline void goertzel_sample(goertzel_state_t *s, short sample)
       -{
       -        int v1;
       -        
       -        v1 = s->v2;
       -        s->v2 = s->v3;
       -        
       -        s->v3 = (s->fac * s->v2) >> 15;
       -        s->v3 = s->v3 - v1 + (sample >> s->chunky);
       -        if (abs(s->v3) > 32768) {
       -                s->chunky++;
       -                s->v3 = s->v3 >> 1;
       -                s->v2 = s->v2 >> 1;
       -                v1 = v1 >> 1;
       -        }
       -}
       -
       -static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
       -{
       -        int i;
       -        
       -        for (i=0;i<count;i++) 
       -                goertzel_sample(s, samps[i]);
       -}
       -
       -static inline float goertzel_result(goertzel_state_t *s)
       -{
       -        goertzel_result_t r;
       -        r.value = (s->v3 * s->v3) + (s->v2 * s->v2);
       -        r.value -= ((s->v2 * s->v3) >> 15) * s->fac;
       -        r.power = s->chunky * 2;
       -        return (float)r.value * (float)(1 << r.power);
       -}
       -
       -static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
       -{
       -        s->v2 = s->v3 = s->chunky = 0.0;
       -        s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * freq / SAMPLE_RATE));
       -        s->samples = samples;
       -}
       -
       -static inline void goertzel_reset(goertzel_state_t *s)
       -{
       -        s->v2 = s->v3 = s->chunky = 0.0;
       -}
       -
       -static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
       -{
       -        int i;
       -
       -        s->lasthit = 0;
       -        s->current_hit = 0;
       -        for (i = 0;  i < 4;  i++) {
       -                goertzel_init (&s->row_out[i], dtmf_row[i], 102);
       -                goertzel_init (&s->col_out[i], dtmf_col[i], 102);
       -                s->energy = 0.0;
       -        }
       -        s->current_sample = 0;
       -}
       -
       -static void ast_mf_detect_init (mf_detect_state_t *s)
       -{
       -        int i;
       -        s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
       -        for (i = 0;  i < 6;  i++) {
       -                goertzel_init (&s->tone_out[i], mf_tones[i], 160);
       -        }
       -        s->current_sample = 0;
       -        s->current_hit = 0;
       -}
       -
       -static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
       -{
       -        s->current_digits = 0;
       -        s->detected_digits = 0;
       -        s->lost_digits = 0;
       -        s->digits[0] = '\0';
       -
       -        if (mf)
       -                ast_mf_detect_init(&s->td.mf);
       -        else
       -                ast_dtmf_detect_init(&s->td.dtmf);
       -}
       -
       -static void store_digit(digit_detect_state_t *s, char digit)
       -{
       -        s->detected_digits++;
       -        if (s->current_digits < MAX_DTMF_DIGITS) {
       -                s->digits[s->current_digits++] = digit;
       -                s->digits[s->current_digits] = '\0';
       -        } else {
       -                //ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
       -                s->lost_digits++;
       -        }
       -}
       -
       -static int dtmf_detect(digit_detect_state_t *s, int16_t amp[], int samples, 
       -                 int digitmode, int *writeback)
       -{
       -        float row_energy[4];
       -        float col_energy[4];
       -        float famp;
       -        int i;
       -        int j;
       -        int sample;
       -        int best_row;
       -        int best_col;
       -        int hit;
       -        int limit;
       -
       -        hit = 0;
       -        for (sample = 0;  sample < samples;  sample = limit) {
       -                /* 102 is optimised to meet the DTMF specs. */
       -                if ((samples - sample) >= (102 - s->td.dtmf.current_sample))
       -                        limit = sample + (102 - s->td.dtmf.current_sample);
       -                else
       -                        limit = samples;
       -                /* The following unrolled loop takes only 35% (rough estimate) of the 
       -                   time of a rolled loop on the machine on which it was developed */
       -                for (j = sample; j < limit; j++) {
       -                        famp = amp[j];
       -                        s->td.dtmf.energy += famp*famp;
       -                        /* With GCC 2.95, the following unrolled code seems to take about 35%
       -                           (rough estimate) as long as a neat little 0-3 loop */
       -                        goertzel_sample(s->td.dtmf.row_out, amp[j]);
       -                        goertzel_sample(s->td.dtmf.col_out, amp[j]);
       -                        goertzel_sample(s->td.dtmf.row_out + 1, amp[j]);
       -                        goertzel_sample(s->td.dtmf.col_out + 1, amp[j]);
       -                        goertzel_sample(s->td.dtmf.row_out + 2, amp[j]);
       -                        goertzel_sample(s->td.dtmf.col_out + 2, amp[j]);
       -                        goertzel_sample(s->td.dtmf.row_out + 3, amp[j]);
       -                        goertzel_sample(s->td.dtmf.col_out + 3, amp[j]);
       -                }
       -                s->td.dtmf.current_sample += (limit - sample);
       -                if (s->td.dtmf.current_sample < 102) {
       -                        if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
       -                                /* If we had a hit last time, go ahead and clear this out since likely it
       -                                   will be another hit */
       -                                for (i=sample;i<limit;i++) 
       -                                        amp[i] = 0;
       -                                *writeback = 1;
       -                        }
       -                        continue;
       -                }
       -                /* We are at the end of a DTMF detection block */
       -                /* Find the peak row and the peak column */
       -                row_energy[0] = goertzel_result (&s->td.dtmf.row_out[0]);
       -                col_energy[0] = goertzel_result (&s->td.dtmf.col_out[0]);
       -
       -                for (best_row = best_col = 0, i = 1;  i < 4;  i++) {
       -                        row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
       -                        if (row_energy[i] > row_energy[best_row])
       -                                best_row = i;
       -                        col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
       -                        if (col_energy[i] > col_energy[best_col])
       -                                best_col = i;
       -                }
       -                hit = 0;
       -
       -                /* Basic signal level test and the twist test */
       -                if (row_energy[best_row] >= DTMF_THRESHOLD && 
       -                    col_energy[best_col] >= DTMF_THRESHOLD &&
       -//                    col_energy[best_col] < row_energy[best_row] *DTMF_REVERSE_TWIST &&          // aluigi work-around
       -                    col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
       -                        /* Relative peak test */
       -                        for (i = 0;  i < 4;  i++) {
       -                                if ((i != best_col &&
       -                                    col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
       -                                    (i != best_row 
       -                                     && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
       -                                        break;
       -                                }
       -                        }
       -                        /* ... and fraction of total energy test */
       -                        if (i >= 4 /*&&
       -                            (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->td.dtmf.energy*/) {     // aluigi work-around
       -                                /* Got a hit */
       -                                hit = dtmf_positions[(best_row << 2) + best_col];
       -                                if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
       -                                        /* Zero out frame data if this is part DTMF */
       -                                        for (i=sample;i<limit;i++) 
       -                                                amp[i] = 0;
       -                                        *writeback = 1;
       -                                }
       -                        }
       -                } 
       -
       -                /* The logic in the next test is:
       -                   For digits we need two successive identical clean detects, with
       -                   something different preceeding it. This can work with
       -                   back to back differing digits. More importantly, it
       -                   can work with nasty phones that give a very wobbly start
       -                   to a digit */
       -                if (hit != s->td.dtmf.current_hit) {
       -                        if (hit && s->td.dtmf.lasthit == hit) {
       -                                s->td.dtmf.current_hit = hit;
       -                                store_digit(s, hit);
       -                        } else if (s->td.dtmf.lasthit != s->td.dtmf.current_hit) {
       -                                s->td.dtmf.current_hit = 0;
       -                        }
       -                }
       -                s->td.dtmf.lasthit = hit;
       -
       -                /* Reinitialise the detector for the next block */
       -                for (i = 0;  i < 4;  i++) {
       -                        goertzel_reset(&s->td.dtmf.row_out[i]);
       -                        goertzel_reset(&s->td.dtmf.col_out[i]);
       -                }
       -                s->td.dtmf.energy = 0.0;
       -                s->td.dtmf.current_sample = 0;
       -        }
       -        return (s->td.dtmf.current_hit);        /* return the debounced hit */
       -}
       -
       -/* MF goertzel size */
       -#define MF_GSIZE 120
       -
       -static int mf_detect(digit_detect_state_t *s, int16_t amp[],
       -        int samples, int digitmode, int *writeback)
       -{
       -        float energy[6];
       -        int best;
       -        int second_best;
       -        float famp;
       -        int i;
       -        int j;
       -        int sample;
       -        int hit;
       -        int limit;
       -
       -        hit = 0;
       -        for (sample = 0;  sample < samples;  sample = limit) {
       -                /* 80 is optimised to meet the MF specs. */
       -                if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample))
       -                        limit = sample + (MF_GSIZE - s->td.mf.current_sample);
       -                else
       -                        limit = samples;
       -                /* The following unrolled loop takes only 35% (rough estimate) of the 
       -                   time of a rolled loop on the machine on which it was developed */
       -                for (j = sample;  j < limit;  j++) {
       -                        famp = amp[j];
       -                        /* With GCC 2.95, the following unrolled code seems to take about 35%
       -                           (rough estimate) as long as a neat little 0-3 loop */
       -                        goertzel_sample(s->td.mf.tone_out, amp[j]);
       -                        goertzel_sample(s->td.mf.tone_out + 1, amp[j]);
       -                        goertzel_sample(s->td.mf.tone_out + 2, amp[j]);
       -                        goertzel_sample(s->td.mf.tone_out + 3, amp[j]);
       -                        goertzel_sample(s->td.mf.tone_out + 4, amp[j]);
       -                        goertzel_sample(s->td.mf.tone_out + 5, amp[j]);
       -                }
       -                s->td.mf.current_sample += (limit - sample);
       -                if (s->td.mf.current_sample < MF_GSIZE) {
       -                        if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
       -                                /* If we had a hit last time, go ahead and clear this out since likely it
       -                                   will be another hit */
       -                                for (i=sample;i<limit;i++) 
       -                                        amp[i] = 0;
       -                                *writeback = 1;
       -                        }
       -                        continue;
       -                }
       -                /* We're at the end of an MF detection block.  */
       -                /* Find the two highest energies. The spec says to look for
       -                   two tones and two tones only. Taking this literally -ie
       -                   only two tones pass the minimum threshold - doesn't work
       -                   well. The sinc function mess, due to rectangular windowing
       -                   ensure that! Find the two highest energies and ensure they
       -                   are considerably stronger than any of the others. */
       -                energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
       -                energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
       -                if (energy[0] > energy[1]) {
       -                        best = 0;
       -                        second_best = 1;
       -                } else {
       -                        best = 1;
       -                        second_best = 0;
       -                }
       -                /*endif*/
       -                for (i=2;i<6;i++) {
       -                        energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
       -                        if (energy[i] >= energy[best]) {
       -                                second_best = best;
       -                                best = i;
       -                        } else if (energy[i] >= energy[second_best]) {
       -                                second_best = i;
       -                        }
       -                }
       -                /* Basic signal level and twist tests */
       -                hit = 0;
       -                if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
       -//                    && energy[best] < energy[second_best]*BELL_MF_TWIST         // aluigi work-around
       -                    && energy[best]*BELL_MF_TWIST > energy[second_best]) {
       -                        /* Relative peak test */
       -                        hit = -1;
       -                        for (i=0;i<6;i++) {
       -                                if (i != best && i != second_best) {
       -                                        if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
       -                                                /* The best two are not clearly the best */
       -                                                hit = 0;
       -                                                break;
       -                                        }
       -                                }
       -                        }
       -                }
       -                if (hit) {
       -                        /* Get the values into ascending order */
       -                        if (second_best < best) {
       -                                i = best;
       -                                best = second_best;
       -                                second_best = i;
       -                        }
       -                        best = best*5 + second_best - 1;
       -                        hit = bell_mf_positions[best];
       -                        /* Look for two successive similar results */
       -                        /* The logic in the next test is:
       -                           For KP we need 4 successive identical clean detects, with
       -                           two blocks of something different preceeding it. For anything
       -                           else we need two successive identical clean detects, with
       -                           two blocks of something different preceeding it. */
       -                        if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
       -                           ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
       -                            (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] && 
       -                            hit != s->td.mf.hits[0]))) {
       -                                store_digit(s, hit);
       -                        }
       -                }
       -
       -
       -                if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
       -                        /* Two successive block without a hit terminate current digit */
       -                        s->td.mf.current_hit = 0;
       -                }
       -
       -                s->td.mf.hits[0] = s->td.mf.hits[1];
       -                s->td.mf.hits[1] = s->td.mf.hits[2];
       -                s->td.mf.hits[2] = s->td.mf.hits[3];
       -                s->td.mf.hits[3] = s->td.mf.hits[4];
       -                s->td.mf.hits[4] = hit;
       -                /* Reinitialise the detector for the next block */
       -                for (i = 0;  i < 6;  i++)
       -                        goertzel_reset(&s->td.mf.tone_out[i]);
       -                s->td.mf.current_sample = 0;
       -        }
       -
       -        return (s->td.mf.current_hit); /* return the debounced hit */
       -}
 (DIR) diff --git a/src/dtmf2num/dtmf2num.c b/src/dtmf2num/dtmf2num.c
       @@ -1,372 +0,0 @@
       -/*
       -    Copyright 2008 Luigi Auriemma
       -
       -    This program is free software; you can redistribute it and/or modify
       -    it under the terms of the GNU General Public License as published by
       -    the Free Software Foundation; either version 2 of the License, or
       -    (at your option) any later version.
       -
       -    This program is distributed in the hope that it will be useful,
       -    but WITHOUT ANY WARRANTY; without even the implied warranty of
       -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       -    GNU General Public License for more details.
       -
       -    You should have received a copy of the GNU General Public License
       -    along with this program; if not, write to the Free Software
       -    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
       -
       -    http://www.gnu.org/licenses/gpl.txt
       -*/
       -
       -#include <stdio.h>
       -#include <stdlib.h>
       -#include <string.h>
       -#include <stdint.h>
       -#include <sys/stat.h>
       -#include "mywav.h"
       -#include "dsp.c"
       -//#include "resample2.c"
       -
       -
       -
       -typedef int8_t      i8;
       -typedef uint8_t     u8;
       -typedef int16_t     i16;
       -typedef uint16_t    u16;
       -typedef int32_t     i32;
       -typedef uint32_t    u32;
       -
       -
       -
       -#define VER     "0.1c"
       -
       -
       -
       -int mywav_fri24(FILE *fd, uint32_t *num);
       -i16 *do_samples(FILE *fd, int wavsize, int *ret_samples, int bits);
       -int do_mono(i16 *smp, int samples, int ch);
       -void do_dcbias(i16 *smp, int samples);
       -void do_normalize(i16 *smp, int samples);
       -int do_8000(i16 *smp, int samples, int *freq);
       -void my_err(u8 *err);
       -void std_err(void);
       -
       -
       -
       -int main(int argc, char *argv[]) {
       -    digit_detect_state_t dtmf;
       -    mywav_fmtchunk  fmt;
       -    struct  stat    xstat;
       -    FILE    *fd;
       -    int     i,
       -            wavsize,
       -            samples,
       -            writeback,
       -            raw      = 0,
       -            optimize = 1;
       -    i16     *smp;
       -    u8      *fname,
       -            *outfile = NULL;
       -
       -    setbuf(stdin,  NULL);
       -    setbuf(stdout, NULL);
       -
       -    fputs("\n"
       -        "DTMF2NUM "VER"\n"
       -        "by Luigi Auriemma\n"
       -        "e-mail: aluigi@autistici.org\n"
       -        "web:    aluigi.org\n"
       -        "\n", stderr);
       -
       -    if(argc < 2) {
       -        printf("\n"
       -            "Usage: %s [options] <file.WAV>\n"
       -            "\n"
       -            "Options:\n"
       -            "-r F C B  consider the file as raw headerless PCM data, you must specify the\n"
       -            "          Frequency, Channels and Bits like -r 44100 2 16\n"
       -            "-o        disable the automatic optimizations: DC bias adjust and normalize.\n"
       -            "          use this option only if your file is already clean and normalized\n"
       -            "-w FILE   debug option for dumping the handled samples from the memory to FILE\n"
       -            "\n", argv[0]);
       -        exit(1);
       -    }
       -
       -    argc--;
       -    for(i = 1; i < argc; i++) {
       -        if(((argv[i][0] != '-') && (argv[i][0] != '/')) || (strlen(argv[i]) != 2)) {
       -            printf("\nError: wrong argument (%s)\n", argv[i]);
       -            exit(1);
       -        }
       -        switch(argv[i][1]) {
       -            case 'r': {
       -                memset(&fmt, 0, sizeof(fmt));
       -                if(!argv[++i]) exit(1);
       -                fmt.dwSamplesPerSec = atoi(argv[i]);
       -                if(!argv[++i]) exit(1);
       -                fmt.wChannels       = atoi(argv[i]);
       -                if(!argv[++i]) exit(1);
       -                fmt.wBitsPerSample  = atoi(argv[i]);
       -                fmt.wFormatTag      = 1;
       -                raw = 1;
       -                } break;
       -            case 'o': {
       -                optimize = 0;
       -                } break;
       -            case 'w': {
       -                if(!argv[++i]) exit(1);
       -                outfile = argv[i];
       -                } break;
       -            default: {
       -                printf("\nError: wrong option (%s)\n", argv[i]);
       -                exit(1);
       -            }
       -        }
       -    }
       -
       -    fname = argv[argc];
       -
       -    if(!strcmp(fname, "-")) {
       -        printf("- open stdin\n");
       -        fd = stdin;
       -    } else {
       -        printf("- open %s\n", fname);
       -        fd = fopen(fname, "rb");
       -        if(!fd) std_err();
       -    }
       -
       -    if(raw) {
       -        fstat(fileno(fd), &xstat);
       -        wavsize = xstat.st_size;
       -    } else {
       -        wavsize = mywav_data(fd, &fmt);
       -    }
       -    fprintf(stderr,
       -        "  wave size      %u\n"
       -        "  format tag     %hu\n"
       -        "  channels:      %hu\n"
       -        "  samples/sec:   %u\n"
       -        "  avg/bytes/sec: %u\n"
       -        "  block align:   %hu\n"
       -        "  bits:          %hu\n",
       -        wavsize,
       -        fmt.wFormatTag,
       -        fmt.wChannels,
       -        fmt.dwSamplesPerSec,
       -        fmt.dwAvgBytesPerSec,
       -        fmt.wBlockAlign,
       -        fmt.wBitsPerSample);
       -
       -    if(wavsize <= 0) my_err("corrupted WAVE file");
       -    if(fmt.wFormatTag != 1) my_err("only the classical PCM WAVE files are supported");
       -
       -    smp = do_samples(fd, wavsize, &samples, fmt.wBitsPerSample);
       -    fprintf(stderr, "  samples:       %d\n", samples);
       -    if(fd != stdin) fclose(fd);
       -
       -    samples = do_mono(smp, samples, fmt.wChannels);
       -    if(optimize) {
       -        do_dcbias(smp, samples);
       -        do_normalize(smp, samples);
       -    }
       -    samples = do_8000(smp, samples, &fmt.dwSamplesPerSec);
       -
       -    fmt.wFormatTag       = 0x0001;
       -    fmt.wChannels        = 1;
       -    fmt.wBitsPerSample   = 16;
       -    fmt.wBlockAlign      = (fmt.wBitsPerSample >> 3) * fmt.wChannels;
       -    fmt.dwAvgBytesPerSec = fmt.dwSamplesPerSec * fmt.wBlockAlign;
       -    wavsize              = samples * sizeof(* smp);
       -
       -    if(outfile) {
       -        fprintf(stderr, "- dump %s\n", outfile);
       -        fd = fopen(outfile, "wb");
       -        if(!fd) std_err();
       -        mywav_writehead(fd, &fmt, wavsize, NULL, 0);
       -        fwrite(smp, 1, wavsize, fd);
       -        fclose(fd);
       -    }
       -
       -    SAMPLE_RATE = fmt.dwSamplesPerSec;
       -
       -    ast_digit_detect_init(&dtmf, DSP_DIGITMODE_MF);
       -    mf_detect(&dtmf, smp, samples, DSP_DIGITMODE_NOQUELCH, &writeback);
       -    printf("\n- MF numbers:    %s\n", dtmf.digits[0] ? dtmf.digits : "none");
       -
       -    ast_digit_detect_init(&dtmf, DSP_DIGITMODE_DTMF);
       -    dtmf_detect(&dtmf, smp, samples, DSP_DIGITMODE_NOQUELCH, &writeback);
       -    printf("\n- DTMF numbers:  %s\n", dtmf.digits[0] ? dtmf.digits : "none");
       -
       -    return(0);
       -}
       -
       -
       -
       -int mywav_fri24(FILE *fd, uint32_t *num) {
       -    uint32_t    ret;
       -    uint8_t     tmp;
       -
       -    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret = tmp;
       -    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret |= (tmp << 8);
       -    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret |= (tmp << 16);
       -    *num = ret;
       -    return(0);
       -}
       -
       -
       -
       -i16 *do_samples(FILE *fd, int wavsize, int *ret_samples, int bits) {
       -    i32     tmp32;
       -    int     i   = 0,
       -            samples;
       -    i16     *smp;
       -    i8      tmp8;
       -
       -    samples = wavsize / (bits >> 3);
       -    smp = malloc(sizeof(* smp) * samples);
       -    if(!smp) std_err();
       -
       -    if(bits == 8) {
       -        for(i = 0; i < samples; i++) {
       -            if(mywav_fri08(fd, &tmp8) < 0) break;
       -            smp[i] = (tmp8 << 8) - 32768;
       -        }
       -
       -    } else if(bits == 16) {
       -        for(i = 0; i < samples; i++) {
       -            if(mywav_fri16(fd, &smp[i]) < 0) break;
       -        }
       -
       -    } else if(bits == 24) {
       -        for(i = 0; i < samples; i++) {
       -            if(mywav_fri24(fd, &tmp32) < 0) break;
       -            smp[i] = tmp32 >> 8;
       -        }
       -
       -    } else if(bits == 32) {
       -        for(i = 0; i < samples; i++) {
       -            if(mywav_fri32(fd, &tmp32) < 0) break;
       -            smp[i] = tmp32 >> 16;
       -        }
       -
       -    } else {
       -        my_err("number of bits used in the WAVE file not supported");
       -    }
       -    *ret_samples = i;
       -    return(smp);
       -}
       -
       -
       -
       -int do_mono(i16 *smp, int samples, int ch) {
       -    i32     tmp;    // max 65535 channels
       -    int     i,
       -            j;
       -
       -    if(!ch) my_err("the WAVE file doesn't have channels");
       -    if(ch == 1) return(samples);
       -
       -    for(i = 0; samples > 0; i++) {
       -        tmp = 0;
       -        for(j = 0; j < ch; j++) {
       -            tmp += smp[(i * ch) + j];
       -        }
       -        smp[i] = tmp / ch;
       -        samples -= ch;
       -    }
       -    return(i);
       -}
       -
       -
       -
       -void do_dcbias(i16 *smp, int samples) {
       -    int     i;
       -    i16     bias,
       -            maxneg,
       -            maxpos;
       -
       -    maxneg = 32767;
       -    maxpos = -32768;
       -    for(i = 0; i < samples; i++) {
       -        if(smp[i] < maxneg) {
       -            maxneg = smp[i];
       -        } else if(smp[i] > maxpos) {
       -            maxpos = smp[i];
       -        }
       -    }
       -
       -    bias = (maxneg + maxpos) / 2;
       -    fprintf(stderr, "  bias adjust:   %d\n", bias);
       -
       -    for(i = 0; i < samples; i++) {
       -        smp[i] -= bias;
       -    }
       -}
       -
       -
       -
       -void do_normalize(i16 *smp, int samples) {
       -    int     i;
       -    i16     bias,
       -            maxneg,
       -            maxpos;
       -
       -    maxneg = 0;
       -    maxpos = 0;
       -    for(i = 0; i < samples; i++) {
       -        if(smp[i] < maxneg) {
       -            maxneg = smp[i];
       -        } else if(smp[i] > maxpos) {
       -            maxpos = smp[i];
       -        }
       -    }
       -
       -    fprintf(stderr, "  volume peaks:  %d %d\n", maxneg, maxpos);
       -
       -    if(maxneg < 0) maxneg = (-maxneg) - 1;
       -    if(maxneg > maxpos) {
       -        bias = maxneg;
       -    } else {
       -        bias = maxpos;
       -    }
       -    if(bias == 32767) return;
       -
       -    fprintf(stderr, "  normalize:     %d\n", 32767 - bias);
       -
       -    for(i = 0; i < samples; i++) {
       -        smp[i] = (smp[i] * 32767) / bias;
       -    }
       -}
       -
       -
       -
       -int do_8000(i16 *smp, int samples, int *freq) {
       -    void    *res;
       -    int     consumed;
       -
       -    if(*freq <= 8000) return(samples);
       -
       -    fprintf(stderr, "  resampling to: 8000hz\n");
       -    res = av_resample_init(8000, *freq, 16, 10, 0, 0.8);
       -    samples = av_resample(res, smp, smp, &consumed, samples, samples, 1);
       -    av_resample_close(res);
       -
       -    *freq = 8000;
       -    return(samples);
       -}
       -
       -
       -
       -void my_err(u8 *err) {
       -    fprintf(stderr, "\nError: %s\n", err);
       -    exit(1);
       -}
       -
       -
       -
       -void std_err(void) {
       -    perror("\nError");
       -    exit(1);
       -}
       -
       -
 (DIR) diff --git a/src/dtmf2num/mywav.h b/src/dtmf2num/mywav.h
       @@ -1,244 +0,0 @@
       -/*
       -  MyWAV 0.1.1
       -  by Luigi Auriemma
       -  e-mail: aluigi@autistici.org
       -  web:    aluigi.org
       -
       -    Copyright 2005,2006 Luigi Auriemma
       -
       -    This program is free software; you can redistribute it and/or modify
       -    it under the terms of the GNU General Public License as published by
       -    the Free Software Foundation; either version 2 of the License, or
       -    (at your option) any later version.
       -
       -    This program is distributed in the hope that it will be useful,
       -    but WITHOUT ANY WARRANTY; without even the implied warranty of
       -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       -    GNU General Public License for more details.
       -
       -    You should have received a copy of the GNU General Public License
       -    along with this program; if not, write to the Free Software
       -    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
       -
       -    http://www.gnu.org/licenses/gpl.txt
       -*/
       -
       -#include <string.h>
       -#include <stdint.h>
       -
       -
       -
       -/*
       -the functions return ever 0 if success, other values (-1) if error
       -note that these functions have been written with compatibility in mind
       -so don't worry if you see useless instructions
       -*/
       -
       -
       -
       -typedef struct {
       -    uint8_t     id[4];
       -    uint32_t    size;
       -} mywav_chunk;
       -
       -typedef struct {
       -    int16_t     wFormatTag;
       -    uint16_t    wChannels;
       -    uint32_t    dwSamplesPerSec;
       -    uint32_t    dwAvgBytesPerSec;
       -    uint16_t    wBlockAlign;
       -    uint16_t    wBitsPerSample;
       -} mywav_fmtchunk;
       -
       -
       -
       -    /* FILE WRITING */
       -
       -    // 8 bit
       -int mywav_fwi08(FILE *fd, int num) {
       -    if(fputc((num      ) & 0xff, fd) < 0) return(-1);
       -    return(0);
       -}
       -
       -
       -
       -    // 16 bit
       -int mywav_fwi16(FILE *fd, int num) {
       -    if(fputc((num      ) & 0xff, fd) < 0) return(-1);
       -    if(fputc((num >>  8) & 0xff, fd) < 0) return(-1);
       -    return(0);
       -}
       -
       -
       -
       -    // 32 bit
       -int mywav_fwi32(FILE *fd, int num) {
       -    if(fputc((num      ) & 0xff, fd) < 0) return(-1);
       -    if(fputc((num >>  8) & 0xff, fd) < 0) return(-1);
       -    if(fputc((num >> 16) & 0xff, fd) < 0) return(-1);
       -    if(fputc((num >> 24) & 0xff, fd) < 0) return(-1);
       -    return(0);
       -}
       -
       -
       -
       -    // data
       -int mywav_fwmem(FILE *fd, uint8_t *mem, int size) {
       -    if(size) {
       -        if(fwrite(mem, size, 1, fd) != 1) return(-1);
       -    }
       -    return(0);
       -}
       -
       -
       -
       -    // chunk
       -int mywav_fwchunk(FILE *fd, mywav_chunk *chunk) {
       -    if(mywav_fwmem(fd, chunk->id, 4)) return(-1);
       -    if(mywav_fwi32(fd, chunk->size))  return(-1);
       -    return(0);
       -}
       -
       -
       -
       -  // fmtchunk
       -int mywav_fwfmtchunk(FILE *fd, mywav_fmtchunk *fmtchunk) {
       -    if(mywav_fwi16(fd, fmtchunk->wFormatTag))       return(-1);
       -    if(mywav_fwi16(fd, fmtchunk->wChannels))        return(-1);
       -    if(mywav_fwi32(fd, fmtchunk->dwSamplesPerSec))  return(-1);
       -    if(mywav_fwi32(fd, fmtchunk->dwAvgBytesPerSec)) return(-1);
       -    if(mywav_fwi16(fd, fmtchunk->wBlockAlign))      return(-1);
       -    if(mywav_fwi16(fd, fmtchunk->wBitsPerSample))   return(-1);
       -    return(0);
       -}
       -
       -
       -
       -    /* FILE READING */
       -
       -    // 8 bit
       -int mywav_fri08(FILE *fd, uint8_t *num) {
       -    if(fread(num, 1, 1, fd) != 1)  return(-1);
       -    return(0);
       -}
       -
       -
       -
       -    // 16 bit
       -int mywav_fri16(FILE *fd, uint16_t *num) {
       -    uint16_t    ret;
       -    uint8_t     tmp;
       -
       -    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret = tmp;
       -    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret |= (tmp << 8);
       -    *num = ret;
       -    return(0);
       -}
       -
       -
       -
       -    // 32 bit
       -int mywav_fri32(FILE *fd, uint32_t *num) {
       -    uint32_t    ret;
       -    uint8_t     tmp;
       -
       -    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret = tmp;
       -    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret |= (tmp << 8);
       -    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret |= (tmp << 16);
       -    if(fread(&tmp, 1, 1, fd) != 1) return(-1);  ret |= (tmp << 24);
       -    *num = ret;
       -    return(0);
       -}
       -
       -
       -
       -    // data
       -int mywav_frmem(FILE *fd, uint8_t *mem, int size) {
       -    if(size) {
       -        if(fread(mem, size, 1, fd) != 1) return(-1);
       -    }
       -    return(0);
       -}
       -
       -
       -
       -    // chunk
       -int mywav_frchunk(FILE *fd, mywav_chunk *chunk) {
       -    if(mywav_frmem(fd, (void *)&chunk->id, 4)) return(-1);
       -    if(mywav_fri32(fd, (void *)&chunk->size))  return(-1);
       -    return(0);
       -}
       -
       -
       -
       -  // fmtchunk
       -int mywav_frfmtchunk(FILE *fd, mywav_fmtchunk *fmtchunk) {
       -    if(mywav_fri16(fd, (void *)&fmtchunk->wFormatTag))       return(-1);
       -    if(mywav_fri16(fd, (void *)&fmtchunk->wChannels))        return(-1);
       -    if(mywav_fri32(fd, (void *)&fmtchunk->dwSamplesPerSec))  return(-1);
       -    if(mywav_fri32(fd, (void *)&fmtchunk->dwAvgBytesPerSec)) return(-1);
       -    if(mywav_fri16(fd, (void *)&fmtchunk->wBlockAlign))      return(-1);
       -    if(mywav_fri16(fd, (void *)&fmtchunk->wBitsPerSample))   return(-1);
       -    return(0);
       -}
       -
       -
       -    /* MYWAV MAIN FUNCTIONS */
       -
       -int mywav_seekchunk(FILE *fd, uint8_t *find) {
       -    mywav_chunk chunk;
       -
       -    if(fseek(fd, sizeof(mywav_chunk) + 4, SEEK_SET) < 0) return(-1);
       -
       -    while(!mywav_frchunk(fd, &chunk)) {
       -        if(!memcmp(chunk.id, find, 4)) return(chunk.size);
       -        if(fseek(fd, chunk.size, SEEK_CUR) < 0) break;
       -    }
       -    return(-1);
       -}
       -
       -
       -
       -int mywav_data(FILE *fd, mywav_fmtchunk *fmt) {
       -    mywav_chunk chunk;
       -    uint8_t     type[4];
       -
       -    if(mywav_frchunk(fd, &chunk)   < 0) return(-1);
       -    if(mywav_frmem(fd, type, 4)    < 0) return(-1);
       -    if(memcmp(type, "WAVE", 4))         return(-1);
       -
       -    if(mywav_seekchunk(fd, "fmt ") < 0) return(-1);
       -    if(mywav_frfmtchunk(fd, fmt)   < 0) return(-1);
       -
       -    return(mywav_seekchunk(fd, "data"));
       -}
       -
       -
       -
       -int mywav_writehead(FILE *fd, mywav_fmtchunk *fmt, uint32_t data_size, uint8_t *more, int morelen) {
       -    mywav_chunk chunk;
       -
       -    memcpy(chunk.id, "RIFF", 4);
       -    chunk.size =
       -        4                      +
       -        sizeof(mywav_chunk)    +
       -        sizeof(mywav_fmtchunk) +
       -        morelen                +
       -        sizeof(mywav_chunk)    +
       -        data_size;
       -
       -    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
       -    if(mywav_fwmem(fd, "WAVE", 4)     < 0) return(-1);
       -
       -    memcpy(chunk.id, "fmt ", 4);
       -    chunk.size = sizeof(mywav_fmtchunk) + morelen;
       -    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
       -    if(mywav_fwfmtchunk(fd, fmt)      < 0) return(-1);
       -    if(mywav_fwmem(fd, more, morelen) < 0) return(-1);
       -
       -    memcpy(chunk.id, "data", 4);
       -    chunk.size = data_size;
       -    if(mywav_fwchunk(fd, &chunk)      < 0) return(-1);
       -    return(0);
       -}
       -
 (DIR) diff --git a/src/dtmf2num/resample2.c b/src/dtmf2num/resample2.c
       @@ -1,342 +0,0 @@
       -/*
       - * audio resampling
       - * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
       - *
       - * This file is part of FFmpeg.
       - *
       - * FFmpeg is free software; you can redistribute it and/or
       - * modify it under the terms of the GNU Lesser General Public
       - * License as published by the Free Software Foundation; either
       - * version 2.1 of the License, or (at your option) any later version.
       - *
       - * FFmpeg is distributed in the hope that it will be useful,
       - * but WITHOUT ANY WARRANTY; without even the implied warranty of
       - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       - * Lesser General Public License for more details.
       - *
       - * You should have received a copy of the GNU Lesser General Public
       - * License along with FFmpeg; if not, write to the Free Software
       - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
       - */
       -
       -/**
       - * @file resample2.c
       - * audio resampling
       - * @author Michael Niedermayer <michaelni@gmx.at>
       - */
       -
       -#include <stdio.h>
       -#include <stdlib.h>
       -#include <string.h>
       -#include <stdint.h>
       -#include <math.h>
       -#include <malloc.h>
       -
       -#define FFABS(a) ((a) >= 0 ? (a) : (-(a)))
       -#define FFSIGN(a) ((a) > 0 ? 1 : -1)
       -#define FFMAX(a,b) ((a) > (b) ? (a) : (b))
       -#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
       -#define av_mallocz  malloc
       -#define av_freep    free
       -
       -#ifndef CONFIG_RESAMPLE_HP
       -#define FILTER_SHIFT 15
       -
       -#define FELEM int16_t
       -#define FELEM2 int32_t
       -#define FELEML int64_t
       -#define FELEM_MAX INT16_MAX
       -#define FELEM_MIN INT16_MIN
       -#define WINDOW_TYPE 9
       -#elif !defined(CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE)
       -#define FILTER_SHIFT 30
       -
       -#define FELEM int32_t
       -#define FELEM2 int64_t
       -#define FELEML int64_t
       -#define FELEM_MAX INT32_MAX
       -#define FELEM_MIN INT32_MIN
       -#define WINDOW_TYPE 12
       -#else
       -#define FILTER_SHIFT 0
       -
       -#define FELEM double
       -#define FELEM2 double
       -#define FELEML double
       -#define WINDOW_TYPE 24
       -#endif
       -
       -
       -typedef struct AVResampleContext{
       -    FELEM *filter_bank;
       -    int filter_length;
       -    int ideal_dst_incr;
       -    int dst_incr;
       -    int index;
       -    int frac;
       -    int src_incr;
       -    int compensation_distance;
       -    int phase_shift;
       -    int phase_mask;
       -    int linear;
       -}AVResampleContext;
       -
       -/**
       - * 0th order modified bessel function of the first kind.
       - */
       -static double bessel(double x){
       -    double v=1;
       -    double t=1;
       -    int i;
       -
       -    x= x*x/4;
       -    for(i=1; i<50; i++){
       -        t *= x/(i*i);
       -        v += t;
       -    }
       -    return v;
       -}
       -
       -static inline int av_clip(int a, int amin, int amax)
       -{
       -    if (a < amin)      return amin;
       -    else if (a > amax) return amax;
       -    else               return a;
       -}
       -
       -/**
       - * builds a polyphase filterbank.
       - * @param factor resampling factor
       - * @param scale wanted sum of coefficients for each filter
       - * @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16
       - */
       -void av_build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){
       -    int ph, i;
       -    double x, y, w, tab[tap_count];
       -    const int center= (tap_count-1)/2;
       -
       -    /* if upsampling, only need to interpolate, no filter */
       -    if (factor > 1.0)
       -        factor = 1.0;
       -
       -    for(ph=0;ph<phase_count;ph++) {
       -        double norm = 0;
       -        for(i=0;i<tap_count;i++) {
       -            x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
       -            if (x == 0) y = 1.0;
       -            else        y = sin(x) / x;
       -            switch(type){
       -            case 0:{
       -                const float d= -0.5; //first order derivative = -0.5
       -                x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
       -                if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*(            -x*x + x*x*x);
       -                else      y=                       d*(-4 + 8*x - 5*x*x + x*x*x);
       -                break;}
       -            case 1:
       -                w = 2.0*x / (factor*tap_count) + M_PI;
       -                y *= 0.3635819 - 0.4891775 * cos(w) + 0.1365995 * cos(2*w) - 0.0106411 * cos(3*w);
       -                break;
       -            default:
       -                w = 2.0*x / (factor*tap_count*M_PI);
       -                y *= bessel(type*sqrt(FFMAX(1-w*w, 0)));
       -                break;
       -            }
       -
       -            tab[i] = y;
       -            norm += y;
       -        }
       -
       -        /* normalize so that an uniform color remains the same */
       -        for(i=0;i<tap_count;i++) {
       -#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE
       -            filter[ph * tap_count + i] = tab[i] / norm;
       -#else
       -            filter[ph * tap_count + i] = av_clip(lrintf(tab[i] * scale / norm), FELEM_MIN, FELEM_MAX);
       -#endif
       -        }
       -    }
       -#if 0
       -    {
       -#define LEN 1024
       -        int j,k;
       -        double sine[LEN + tap_count];
       -        double filtered[LEN];
       -        double maxff=-2, minff=2, maxsf=-2, minsf=2;
       -        for(i=0; i<LEN; i++){
       -            double ss=0, sf=0, ff=0;
       -            for(j=0; j<LEN+tap_count; j++)
       -                sine[j]= cos(i*j*M_PI/LEN);
       -            for(j=0; j<LEN; j++){
       -                double sum=0;
       -                ph=0;
       -                for(k=0; k<tap_count; k++)
       -                    sum += filter[ph * tap_count + k] * sine[k+j];
       -                filtered[j]= sum / (1<<FILTER_SHIFT);
       -                ss+= sine[j + center] * sine[j + center];
       -                ff+= filtered[j] * filtered[j];
       -                sf+= sine[j + center] * filtered[j];
       -            }
       -            ss= sqrt(2*ss/LEN);
       -            ff= sqrt(2*ff/LEN);
       -            sf= 2*sf/LEN;
       -            maxff= FFMAX(maxff, ff);
       -            minff= FFMIN(minff, ff);
       -            maxsf= FFMAX(maxsf, sf);
       -            minsf= FFMIN(minsf, sf);
       -            if(i%11==0){
       -                //av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf);
       -                minff=minsf= 2;
       -                maxff=maxsf= -2;
       -            }
       -        }
       -    }
       -#endif
       -}
       -
       -/**
       - * Initializes an audio resampler.
       - * Note, if either rate is not an integer then simply scale both rates up so they are.
       - */
       -AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){
       -    AVResampleContext *c= av_mallocz(sizeof(AVResampleContext));
       -    double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
       -    int phase_count= 1<<phase_shift;
       -
       -    c->phase_shift= phase_shift;
       -    c->phase_mask= phase_count-1;
       -    c->linear= linear;
       -
       -    c->filter_length= FFMAX((int)ceil(filter_size/factor), 1);
       -    c->filter_bank= av_mallocz(c->filter_length*(phase_count+1)*sizeof(FELEM));
       -    av_build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<<FILTER_SHIFT, WINDOW_TYPE);
       -    memcpy(&c->filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM));
       -    c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1];
       -
       -    c->src_incr= out_rate;
       -    c->ideal_dst_incr= c->dst_incr= in_rate * phase_count;
       -    c->index= -phase_count*((c->filter_length-1)/2);
       -
       -    return c;
       -}
       -
       -void av_resample_close(AVResampleContext *c){
       -    av_freep(&c->filter_bank);
       -    av_freep(&c);
       -}
       -
       -/**
       - * Compensates samplerate/timestamp drift. The compensation is done by changing
       - * the resampler parameters, so no audible clicks or similar distortions ocur
       - * @param compensation_distance distance in output samples over which the compensation should be performed
       - * @param sample_delta number of output samples which should be output less
       - *
       - * example: av_resample_compensate(c, 10, 500)
       - * here instead of 510 samples only 500 samples would be output
       - *
       - * note, due to rounding the actual compensation might be slightly different,
       - * especially if the compensation_distance is large and the in_rate used during init is small
       - */
       -void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){
       -//    sample_delta += (c->ideal_dst_incr - c->dst_incr)*(int64_t)c->compensation_distance / c->ideal_dst_incr;
       -    c->compensation_distance= compensation_distance;
       -    c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance;
       -}
       -
       -/**
       - * resamples.
       - * @param src an array of unconsumed samples
       - * @param consumed the number of samples of src which have been consumed are returned here
       - * @param src_size the number of unconsumed samples available
       - * @param dst_size the amount of space in samples available in dst
       - * @param update_ctx if this is 0 then the context wont be modified, that way several channels can be resampled with the same context
       - * @return the number of samples written in dst or -1 if an error occured
       - */
       -int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx){
       -    int dst_index, i;
       -    int index= c->index;
       -    int frac= c->frac;
       -    int dst_incr_frac= c->dst_incr % c->src_incr;
       -    int dst_incr=      c->dst_incr / c->src_incr;
       -    int compensation_distance= c->compensation_distance;
       -
       -  if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){
       -        int64_t index2= ((int64_t)index)<<32;
       -        int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;
       -        dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr);
       -
       -        for(dst_index=0; dst_index < dst_size; dst_index++){
       -            dst[dst_index] = src[index2>>32];
       -            index2 += incr;
       -        }
       -        frac += dst_index * dst_incr_frac;
       -        index += dst_index * dst_incr;
       -        index += frac / c->src_incr;
       -        frac %= c->src_incr;
       -  }else{
       -    for(dst_index=0; dst_index < dst_size; dst_index++){
       -        FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask);
       -        int sample_index= index >> c->phase_shift;
       -        FELEM2 val=0;
       -
       -        if(sample_index < 0){
       -            for(i=0; i<c->filter_length; i++)
       -                val += src[FFABS(sample_index + i) % src_size] * filter[i];
       -        }else if(sample_index + c->filter_length > src_size){
       -            break;
       -        }else if(c->linear){
       -            FELEM2 v2=0;
       -            for(i=0; i<c->filter_length; i++){
       -                val += src[sample_index + i] * (FELEM2)filter[i];
       -                v2  += src[sample_index + i] * (FELEM2)filter[i + c->filter_length];
       -            }
       -            val+=(v2-val)*(FELEML)frac / c->src_incr;
       -        }else{
       -            for(i=0; i<c->filter_length; i++){
       -                val += src[sample_index + i] * (FELEM2)filter[i];
       -            }
       -        }
       -
       -#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE
       -        dst[dst_index] = av_clip_int16(lrintf(val));
       -#else
       -        val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;
       -        dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val;
       -#endif
       -
       -        frac += dst_incr_frac;
       -        index += dst_incr;
       -        if(frac >= c->src_incr){
       -            frac -= c->src_incr;
       -            index++;
       -        }
       -
       -        if(dst_index + 1 == compensation_distance){
       -            compensation_distance= 0;
       -            dst_incr_frac= c->ideal_dst_incr % c->src_incr;
       -            dst_incr=      c->ideal_dst_incr / c->src_incr;
       -        }
       -    }
       -  }
       -    *consumed= FFMAX(index, 0) >> c->phase_shift;
       -    if(index>=0) index &= c->phase_mask;
       -
       -    if(compensation_distance){
       -        compensation_distance -= dst_index;
       -        if(!(compensation_distance > 0)) return(-1);
       -    }
       -    if(update_ctx){
       -        c->frac= frac;
       -        c->index= index;
       -        c->dst_incr= dst_incr_frac + c->src_incr*dst_incr;
       -        c->compensation_distance= compensation_distance;
       -    }
       -#if 0
       -    if(update_ctx && !c->compensation_distance){
       -#undef rand
       -        av_resample_compensate(c, rand() % (8000*2) - 8000, 8000*2);
       -//av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c->dst_incr, c->ideal_dst_incr, c->compensation_distance);
       -    }
       -#endif
       -
       -    return dst_index;
       -}