home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Multimed / Multimed.zip / rxwavsrc.zip / RxWavFilter.c < prev    next >
C/C++ Source or Header  |  2000-03-06  |  7KB  |  266 lines

  1. /*  RxWav
  2.    Copyright (C) 1999  Giorgio Vicario
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA     */
  17.  
  18. #define INCL_REXXSAA
  19. #include <os2emx.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <regexp.h>
  24. #include <math.h>
  25. #include <float.h>
  26. #include "RxWav.h"
  27.  
  28. /***********************************************************************
  29. Filtro passa banda:
  30. ***********************************************************************/
  31.  
  32.  
  33. ULONG
  34. WavFilterBand (PCSZ name, LONG argc, const RXSTRING * argv,
  35.            PCSZ queuename, PRXSTRING retstr)
  36. {
  37.   PSHORT pFrom = NULL;
  38.   PSHORT pTo = NULL;
  39.   ULONG nCamp, i;
  40.   APIRET rc;
  41.   double d;
  42.   float centro, larghezza, amp;
  43.   double A, B, C;
  44.   double out1, out2;
  45.   long l;
  46.  
  47.   if (argc != 5)
  48.     {
  49.       SendMsg (FUNC_FILTER_BAND, ERR_NUMERO_PARAMETRI);
  50.       return INVALID_ROUTINE;
  51.     }
  52.  
  53.   if (!sscanf (argv[0].strptr, "%d", &pFrom))
  54.     {
  55.       SendMsg (FUNC_FILTER_BAND, ERR_PUNTATORE_ERRATO);
  56.       return INVALID_ROUTINE;
  57.     }
  58.  
  59.   nCamp = atol (argv[1].strptr);
  60.   if (!nCamp)
  61.     {
  62.       SendMsg (FUNC_FILTER_BAND, ERR_NUMERO_CAMPIONI);
  63.       return INVALID_ROUTINE;
  64.     }
  65.  
  66.   centro = atof (argv[2].strptr);
  67.   if ((centro < 1) || (centro > (FreqCamp / 2)))
  68.     {
  69.       SendMsg (FUNC_FILTER_BAND, ERR_FREQUENZA_CENTRALE);
  70.       return INVALID_ROUTINE;
  71.     }
  72.  
  73.   larghezza = atof (argv[3].strptr);
  74.   if ((larghezza < 1) || (larghezza > centro))
  75.     {
  76.       SendMsg (FUNC_FILTER_BAND, ERR_LARGHEZZA_BANDA);
  77.       return INVALID_ROUTINE;
  78.     }
  79.  
  80.   amp = atof (argv[4].strptr);
  81.   if ((amp > 1) || (amp < 0))
  82.     {
  83.       SendMsg (FUNC_FILTER_BAND, ERR_AMPIEZZA_FILTRO);
  84.       return INVALID_ROUTINE;
  85.     }
  86.  
  87.   pFrom = AllineaCh (pFrom, nCamp, FUNC_FILTER_BAND);
  88.   if (!pFrom)
  89.     return INVALID_ROUTINE;
  90.   pTo = pFrom;
  91.  
  92.  
  93.   C = exp (-2 * M_PI * larghezza / FreqCamp);
  94.   B = -4 * C / (1 + C) * cos (2 * M_PI * centro / FreqCamp);
  95.   A = sqrt (((1 + C) * (1 + C) - B * B) * (1 - C) / (1 + C));
  96.   out1 = out2 = 0.0;
  97.  
  98.   for (i = nCamp; i != 0; i--)
  99.     {
  100.       l = *pFrom++;
  101.       d = (A * l - B * out1) - C * out2;
  102.       out2 = out1;
  103.       out1 = d;
  104.       *pTo = d * amp + l * (1 - amp);
  105.       *pTo++;
  106.     }
  107.  
  108.   sprintf (retstr->strptr, "%i", ERR_OK);
  109.   retstr->strlength = strlen (retstr->strptr);
  110.   return VALID_ROUTINE;
  111. }
  112.  
  113.  
  114.  
  115. /***********************************************************************
  116. Filtro passa alto:
  117. ***********************************************************************/
  118.  
  119.  
  120. ULONG
  121. WavFilterHigh (PCSZ name, LONG argc, const RXSTRING * argv,
  122.            PCSZ queuename, PRXSTRING retstr)
  123. {
  124.   PSHORT pFrom = NULL;
  125.   PSHORT pTo = NULL;
  126.   ULONG nCamp, i;
  127.   APIRET rc;
  128.   float centro, amp;
  129.   double A, B, d, t1;
  130.   long l1;
  131.  
  132.   if (argc != 4)
  133.     {
  134.       SendMsg (FUNC_FILTER_HIGH, ERR_NUMERO_PARAMETRI);
  135.       return INVALID_ROUTINE;
  136.     }
  137.  
  138.   if (!sscanf (argv[0].strptr, "%d", &pFrom))
  139.     {
  140.       SendMsg (FUNC_FILTER_HIGH, ERR_PUNTATORE_ERRATO);
  141.       return INVALID_ROUTINE;
  142.     }
  143.  
  144.   nCamp = atol (argv[1].strptr);
  145.   if (!nCamp)
  146.     {
  147.       SendMsg (FUNC_FILTER_HIGH, ERR_NUMERO_CAMPIONI);
  148.       return INVALID_ROUTINE;
  149.     }
  150.  
  151.   centro = atof (argv[2].strptr);
  152.   if ((centro < 1) || (centro > (FreqCamp / 2)))
  153.     {
  154.       SendMsg (FUNC_FILTER_HIGH, ERR_FREQUENZA_CENTRALE);
  155.       return INVALID_ROUTINE;
  156.     }
  157.  
  158.   amp = atof (argv[3].strptr);
  159.   if ((amp > 1) || (amp < -1))
  160.     {
  161.       SendMsg (FUNC_FILTER_HIGH, ERR_AMPIEZZA_FILTRO);
  162.       return INVALID_ROUTINE;
  163.     }
  164.  
  165.   pFrom = AllineaCh (pFrom, nCamp, FUNC_FILTER_HIGH);
  166.   if (!pFrom)
  167.     return INVALID_ROUTINE;
  168.   pTo = pFrom;
  169.   A = (M_PI * 2.0 * centro) / FreqCamp;
  170.   B = exp (-A / FreqCamp);
  171.  
  172.   for (i = nCamp; i != 0; i--)
  173.     {
  174.       l1 = *pFrom++;
  175.       d = (B * ((d - t1) + (double) l1)) / 65536.0;
  176.       d *= 0.8;
  177.       if (d > MAX_CAMPIONE)
  178.     d = MAX_CAMPIONE;
  179.       if (d < -MAX_CAMPIONE)
  180.     d = -MAX_CAMPIONE;
  181.       t1 = l1;
  182.       *pTo++ = (d * 65536.0) + amp + (*pTo * (1 - amp));
  183.     }
  184.  
  185.   sprintf (retstr->strptr, "%i", ERR_OK);
  186.   retstr->strlength = strlen (retstr->strptr);
  187.   return VALID_ROUTINE;
  188. }
  189.  
  190.  
  191.  
  192. /***********************************************************************
  193. Filtro passa basso:
  194. ***********************************************************************/
  195.  
  196.  
  197. ULONG
  198. WavFilterLow (PCSZ name, LONG argc, const RXSTRING * argv,
  199.           PCSZ queuename, PRXSTRING retstr)
  200. {
  201.   PSHORT pFrom = NULL;
  202.   PSHORT pTo = NULL;
  203.   ULONG nCamp, i;
  204.   APIRET rc;
  205.   float centro, amp;
  206.   double A, B, t1, d;
  207.   long l1;
  208.  
  209.   if (argc != 4)
  210.     {
  211.       SendMsg (FUNC_FILTER_LOW, ERR_NUMERO_PARAMETRI);
  212.       return INVALID_ROUTINE;
  213.     }
  214.  
  215.   if (!sscanf (argv[0].strptr, "%d", &pFrom))
  216.     {
  217.       SendMsg (FUNC_FILTER_LOW, ERR_PUNTATORE_ERRATO);
  218.       return INVALID_ROUTINE;
  219.     }
  220.  
  221.   nCamp = atol (argv[1].strptr);
  222.   if (!nCamp)
  223.     {
  224.       SendMsg (FUNC_FILTER_LOW, ERR_NUMERO_CAMPIONI);
  225.       return INVALID_ROUTINE;
  226.     }
  227.  
  228.   centro = atof (argv[2].strptr);
  229.   if ((centro < 1) || (centro > (FreqCamp / 2)))
  230.     {
  231.       SendMsg (FUNC_FILTER_LOW, ERR_FREQUENZA_CENTRALE);
  232.       return INVALID_ROUTINE;
  233.     }
  234.  
  235.   amp = atof (argv[3].strptr);
  236.   if ((amp > 1) || (amp < -1))
  237.     {
  238.       SendMsg (FUNC_FILTER_LOW, ERR_AMPIEZZA_FILTRO);
  239.       return INVALID_ROUTINE;
  240.     }
  241.  
  242.   pFrom = AllineaCh (pFrom, nCamp, FUNC_FILTER_LOW);
  243.   if (!pFrom)
  244.     return INVALID_ROUTINE;
  245.   pTo = pFrom;
  246.   A = (M_PI * 2.0 * centro) / FreqCamp;
  247.   B = exp (-A / FreqCamp);
  248.  
  249.   for (i = nCamp; i != 0; i--)
  250.     {
  251.       l1 = *pFrom++;
  252.       d = A * (l1 / 65536) + B * (t1 / 65536);
  253.       d *= 0.8;
  254.       if (d > MAX_CAMPIONE)
  255.     d = MAX_CAMPIONE;
  256.       if (d < -MAX_CAMPIONE)
  257.     d = -MAX_CAMPIONE;
  258.       t1 = l1;
  259.       *pTo++ = (d * 65536.0) + amp + (*pTo * (1 - amp));
  260.     }
  261.  
  262.   sprintf (retstr->strptr, "%i", ERR_OK);
  263.   retstr->strlength = strlen (retstr->strptr);
  264.   return VALID_ROUTINE;
  265. }
  266.