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

  1. /* RxWav
  2.    Copyright (C) 1999 2000  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. Legge un file WAV Stereo.
  30. Vuole il nome del file e due puntatori a traccie gia' allocate e di
  31. dimensioni sufficienti
  32. ***********************************************************************/
  33. ULONG
  34. WavReadStereo (PCSZ name, LONG argc, const RXSTRING * argv,
  35.            PCSZ queuename, PRXSTRING retstr)
  36. {
  37.   FILE *StereoFile;
  38.   UCHAR NomeFile[256];
  39.   PBYTE pChSX = NULL;
  40.   PBYTE pChDX = NULL;
  41.   PSHORT pChSX16 = NULL;
  42.   PSHORT pChDX16 = NULL;
  43.   struct wav DatiWAV;
  44.   INT i, ch, c2;
  45.   ULONG TipoCopia = COPIA_NOMIX;
  46.   ULONG nSkip = 0, nCamp = 67108864;
  47.   APIRET rc;
  48.  
  49.   if ((argc < 3) | (argc > 6))
  50.     {
  51.       SendMsg (FUNC_READ_STEREO, ERR_NUMERO_PARAMETRI);
  52.       return INVALID_ROUTINE;
  53.     }
  54.  
  55.   strcpy (NomeFile, argv[0].strptr);
  56.   if (!sscanf (argv[1].strptr, "%d", &pChSX))
  57.     {
  58.       SendMsg (FUNC_READ_STEREO, ERR_PUNTATORE_ERRATO);
  59.       return INVALID_ROUTINE;
  60.     }
  61.  
  62.   if (!sscanf (argv[2].strptr, "%d", &pChDX))
  63.     {
  64.       SendMsg (FUNC_READ_STEREO, ERR_PUNTATORE_ERRATO);
  65.       return INVALID_ROUTINE;
  66.     }
  67.  
  68.   if (argc > 3)
  69.     {
  70.       if (!strncmp (argv[3].strptr, "MIX", 3))
  71.     TipoCopia = COPIA_MIX;
  72.       if (!strncmp (argv[3].strptr, "NOMIX", 5))
  73.     TipoCopia = COPIA_NOMIX;
  74.     }
  75.  
  76.   if (argc > 4)
  77.     {
  78.       nSkip = atol (argv[4].strptr);
  79.       if (!nSkip)
  80.     {
  81.       SendMsg (FUNC_READ_STEREO, ERR_NUMERO_CAMPIONI);
  82.       return INVALID_ROUTINE;
  83.     }
  84.  
  85.       nCamp = atol (argv[5].strptr);
  86.       if (!nCamp)
  87.     {
  88.       SendMsg (FUNC_READ_STEREO, ERR_NUMERO_CAMPIONI);
  89.       return INVALID_ROUTINE;
  90.     }
  91.     }
  92.  
  93.   if ((StereoFile = fopen (NomeFile, "rb")) == NULL)
  94.     {
  95.       SendMsg (FUNC_READ_STEREO, ERR_OPEN_FILE);
  96.       sprintf (retstr->strptr, "%i", ERR_OPEN_FILE);
  97.       retstr->strlength = strlen (retstr->strptr);
  98.       return VALID_ROUTINE;
  99.     }
  100.  
  101.   if (!(fread (&DatiWAV, sizeof (struct wav), 1, StereoFile)))
  102.     {
  103.       SendMsg (FUNC_READ_STEREO, ERR_READ_WAV_STRUCT);
  104.       sprintf (retstr->strptr, "%i", ERR_READ_WAV_STRUCT);
  105.       retstr->strlength = strlen (retstr->strptr);
  106.       return VALID_ROUTINE;
  107.     }
  108.  
  109.   if (strncmp (DatiWAV.w_riff, "RIFF", 4) & strncmp (DatiWAV.w_wave, "WAVE", 4))
  110.     {
  111.       SendMsg (FUNC_READ_STEREO, ERR_FILE_NOWAV);
  112.       sprintf (retstr->strptr, "%i", ERR_FILE_NOWAV);
  113.       retstr->strlength = strlen (retstr->strptr);
  114.       return VALID_ROUTINE;
  115.     }
  116.  
  117.  
  118.   if (nSkip > 0)
  119.     fseek (StereoFile, nSkip, SEEK_SET);
  120.  
  121.   pChSX = AllineaCh (pChSX, (ULONG) DatiWAV.w_len_data / 4, FUNC_READ_STEREO);
  122.   if (!pChSX)
  123.     return INVALID_ROUTINE;
  124.  
  125.   pChDX = AllineaCh (pChDX, (ULONG) DatiWAV.w_len_data / 4, FUNC_READ_STEREO);
  126.   if (!pChDX)
  127.     return INVALID_ROUTINE;
  128.  
  129.   pChSX16 = pChSX;
  130.   pChDX16 = pChDX;
  131.   for (i = nCamp; ((ch = fgetc (StereoFile)) != EOF) & (i != 0); i++)
  132.     {
  133.       switch (DatiWAV.w_bit_camp)
  134.     {
  135.     case 8:
  136.       if (TipoCopia == COPIA_NOMIX)
  137.         {
  138.           *pChSX16++ = (BYTE) ch *128;
  139.           ch = fgetc (StereoFile);
  140.           *pChDX16++ = (BYTE) ch *128;
  141.         }
  142.       else
  143.         {
  144.           *pChSX16++ = *pChSX16 + (BYTE) ch *128;
  145.           ch = fgetc (StereoFile);
  146.           *pChDX16++ = *pChSX16 + (BYTE) ch *128;
  147.         }
  148.       break;
  149.     case 16:
  150.       if (TipoCopia == COPIA_NOMIX)
  151.         {
  152.           *pChSX++ = (BYTE) ch;
  153.           ch = fgetc (StereoFile);
  154.           *pChSX++ = (BYTE) ch;
  155.           ch = fgetc (StereoFile);
  156.           *pChDX++ = (BYTE) ch;
  157.           ch = fgetc (StereoFile);
  158.           *pChDX++ = (BYTE) ch;
  159.         }
  160.       else
  161.         {
  162.           c2 = fgetc (StereoFile);
  163.           *pChSX16++ = (BYTE) ch + (SHORT) ((BYTE) c2 * 256) + *pChSX16;
  164.           ch = fgetc (StereoFile);
  165.  
  166.           c2 = fgetc (StereoFile);
  167.           *pChDX16++ = (BYTE) ch + (SHORT) ((BYTE) c2 * 256) + *pChDX16;
  168.         }
  169.       break;
  170.     default:
  171.       SendMsg (FUNC_READ_STEREO, ERR_RISOLUZIONE);
  172.       sprintf (retstr->strptr, "%i", ERR_RISOLUZIONE);
  173.       retstr->strlength = strlen (retstr->strptr);
  174.       break;
  175.     }
  176.     }
  177.  
  178.   rc = fclose (StereoFile);
  179.   if (rc)
  180.     {
  181.       SendMsg (FUNC_READ_STEREO, ERR_CLOSE_FILE);
  182.       sprintf (retstr->strptr, "%i", ERR_CLOSE_FILE);
  183.       retstr->strlength = strlen (retstr->strptr);
  184.       return VALID_ROUTINE;
  185.     }
  186.  
  187.   sprintf (retstr->strptr, "%i", ERR_OK);
  188.   retstr->strlength = strlen (retstr->strptr);
  189.   return VALID_ROUTINE;
  190. }
  191.  
  192.  
  193. /***********************************************************************
  194. Scrive un file WAV Stereo.
  195. Vuole il nome del file e due puntatori a traccie gia' allocate e il
  196. numero di campioni da scaricare
  197. ***********************************************************************/
  198. ULONG
  199. WavWriteStereo (PCSZ name, LONG argc, const RXSTRING * argv,
  200.         PCSZ queuename, PRXSTRING retstr)
  201. {
  202.   FILE *StereoFile;
  203.   UCHAR NomeFile[256];
  204.   PBYTE pChSX = NULL;
  205.   PBYTE pChDX = NULL;
  206.   struct wav DatiWAV;
  207.   ULONG nCamp, i;
  208.   APIRET rc;
  209.  
  210.   if (argc != 4)
  211.     {
  212.       SendMsg (FUNC_WRITE_STEREO, ERR_NUMERO_PARAMETRI);
  213.       return INVALID_ROUTINE;
  214.     }
  215.  
  216.   strcpy (NomeFile, argv[0].strptr);
  217.  
  218.   if (!sscanf (argv[1].strptr, "%d", &pChSX))
  219.     {
  220.       SendMsg (FUNC_WRITE_STEREO, ERR_PUNTATORE_ERRATO);
  221.       return INVALID_ROUTINE;
  222.     }
  223.  
  224.   if (!sscanf (argv[2].strptr, "%d", &pChDX))
  225.     {
  226.       SendMsg (FUNC_WRITE_STEREO, ERR_PUNTATORE_ERRATO);
  227.       return INVALID_ROUTINE;
  228.     }
  229.  
  230.   nCamp = atol (argv[3].strptr);
  231.   if (!nCamp)
  232.     {
  233.       SendMsg (FUNC_WRITE_STEREO, ERR_NUMERO_CAMPIONI);
  234.       return INVALID_ROUTINE;
  235.     }
  236.  
  237.   if ((StereoFile = fopen (NomeFile, "wb")) == NULL)
  238.     {
  239.       SendMsg (FUNC_WRITE_STEREO, ERR_OPEN_FILE);
  240.       sprintf (retstr->strptr, "%i", ERR_OPEN_FILE);
  241.       retstr->strlength = strlen (retstr->strptr);
  242.       return VALID_ROUTINE;
  243.     }
  244.  
  245.   strcpy (DatiWAV.w_riff, "RIFF");
  246.   strcpy (DatiWAV.w_wave, "WAVE");
  247.   strcpy (DatiWAV.w_fmt, "fmt ");
  248.   strcpy (DatiWAV.w_data, "data");
  249.   DatiWAV.w_len_tot = (nCamp * NBit / 4) + sizeof (struct wav) - 8;
  250.   DatiWAV.w_len_fmt = 16;
  251.   DatiWAV.w_stereo = 2;
  252.   DatiWAV.w_freq_camp = FreqCamp;
  253.   DatiWAV.w_byte_sec = FreqCamp * (NBit / 8) * 2;
  254.   DatiWAV.w_block_align = 4;
  255.   DatiWAV.w_bit_camp = NBit;
  256.   DatiWAV.w_len_data = (nCamp * 4) + sizeof (struct wav) - 44;
  257.   DatiWAV.w_format_tag = 1;
  258.  
  259.   if (!(fwrite (&DatiWAV, sizeof (struct wav), 1, StereoFile)))
  260.     {
  261.       SendMsg (FUNC_WRITE_STEREO, ERR_WRITE_WAV_STRUCT);
  262.       sprintf (retstr->strptr, "%i", ERR_WRITE_WAV_STRUCT);
  263.       retstr->strlength = strlen (retstr->strptr);
  264.       return VALID_ROUTINE;
  265.     }
  266.  
  267.   pChSX = AllineaCh (pChSX, nCamp, FUNC_WRITE_STEREO);
  268.   if (!pChSX)
  269.     return INVALID_ROUTINE;
  270.  
  271.   pChDX = AllineaCh (pChDX, nCamp, FUNC_WRITE_STEREO);
  272.   if (!pChDX)
  273.     return INVALID_ROUTINE;
  274.  
  275.   for (i = nCamp; i != 0; i--)
  276.     {
  277.       putc (*pChDX++, StereoFile);
  278.       putc (*pChDX++, StereoFile);
  279.       putc (*pChSX++, StereoFile);
  280.       putc (*pChSX++, StereoFile);
  281.     }
  282.  
  283.   rc = 0;
  284.   rc = fclose (StereoFile);
  285. /*
  286.    if (rc)
  287.    { SendMsg(FUNC_WRITE_STEREO, ERR_CLOSE_FILE);
  288.    sprintf(retstr->strptr, "%i", ERR_CLOSE_FILE);
  289.    retstr->strlength = strlen(retstr->strptr);
  290.    return VALID_ROUTINE; }
  291.  */
  292.  
  293.   sprintf (retstr->strptr, "%i", ERR_OK);
  294.   retstr->strlength = strlen (retstr->strptr);
  295.   return VALID_ROUTINE;
  296. }
  297.  
  298.  
  299. /***********************************************************************
  300. Legge un file WAV Mono.
  301. Vuole il nome del file e due puntatori a traccie gia' allocate e di
  302. dimensioni sufficienti
  303. ***********************************************************************/
  304. ULONG
  305. WavReadMono (PCSZ name, LONG argc, const RXSTRING * argv,
  306.          PCSZ queuename, PRXSTRING retstr)
  307. {
  308.   FILE *MonoFile;
  309.   UCHAR NomeFile[256];
  310.   PBYTE pCh = NULL;
  311.   PSHORT pCh16 = NULL;
  312.   struct wav DatiWAV;
  313.   ULONG TipoCopia = COPIA_NOMIX;
  314.   ULONG nSkip = 0, nCamp = 67108864;
  315.   INT i, ch;
  316.   APIRET rc;
  317.  
  318.   if ((argc < 2) | (argc > 5))
  319.     {
  320.       SendMsg (FUNC_READ_MONO, ERR_NUMERO_PARAMETRI);
  321.       return INVALID_ROUTINE;
  322.     }
  323.  
  324.   strcpy (NomeFile, argv[0].strptr);
  325.   if (!sscanf (argv[1].strptr, "%d", &pCh))
  326.     {
  327.       SendMsg (FUNC_READ_MONO, ERR_PUNTATORE_ERRATO);
  328.       return INVALID_ROUTINE;
  329.     }
  330.  
  331.   if (argc > 2)
  332.     {
  333.       if (!strncmp (argv[2].strptr, "MIX", 3))
  334.     TipoCopia = COPIA_MIX;
  335.       if (!strncmp (argv[2].strptr, "NOMIX", 5))
  336.     TipoCopia = COPIA_NOMIX;
  337.     }
  338.  
  339.   if (argc > 3)
  340.     {
  341.       nSkip = atol (argv[3].strptr);
  342.       if (!nSkip)
  343.     {
  344.       SendMsg (FUNC_READ_STEREO, ERR_NUMERO_CAMPIONI);
  345.       return INVALID_ROUTINE;
  346.     }
  347.  
  348.       nCamp = atol (argv[4].strptr);
  349.       if (!nCamp)
  350.     {
  351.       SendMsg (FUNC_READ_STEREO, ERR_NUMERO_CAMPIONI);
  352.       return INVALID_ROUTINE;
  353.     }
  354.     }
  355.  
  356.  
  357.  
  358.   if ((MonoFile = fopen (NomeFile, "rb")) == NULL)
  359.     {
  360.       SendMsg (FUNC_READ_MONO, ERR_OPEN_FILE);
  361.       sprintf (retstr->strptr, "%i", ERR_OPEN_FILE);
  362.       retstr->strlength = strlen (retstr->strptr);
  363.       return VALID_ROUTINE;
  364.     }
  365.  
  366.   if (!(fread (&DatiWAV, sizeof (struct wav), 1, MonoFile)))
  367.     {
  368.       SendMsg (FUNC_READ_MONO, ERR_READ_WAV_STRUCT);
  369.       sprintf (retstr->strptr, "%i", ERR_READ_WAV_STRUCT);
  370.       retstr->strlength = strlen (retstr->strptr);
  371.       return VALID_ROUTINE;
  372.     }
  373.  
  374.   if (strncmp (DatiWAV.w_riff, "RIFF", 4) & strncmp (DatiWAV.w_wave, "WAVE", 4))
  375.     {
  376.       SendMsg (FUNC_READ_MONO, ERR_FILE_NOWAV);
  377.       sprintf (retstr->strptr, "%i", ERR_FILE_NOWAV);
  378.       retstr->strlength = strlen (retstr->strptr);
  379.       return VALID_ROUTINE;
  380.     }
  381.  
  382.  
  383.   if (nSkip > 0)
  384.     fseek (MonoFile, nSkip, SEEK_SET);
  385.  
  386.   pCh = AllineaCh (pCh, DatiWAV.w_len_data / 2, FUNC_READ_MONO);
  387.   if (!pCh)
  388.     return INVALID_ROUTINE;
  389.  
  390.   pCh16 = pCh;
  391.   for (i = nCamp; ((ch = fgetc (MonoFile)) != EOF) & (i != 0); i++)
  392.     {
  393.       switch (DatiWAV.w_bit_camp)
  394.     {
  395.     case 8:
  396.       if (TipoCopia == COPIA_NOMIX)
  397.         *pCh16++ = (BYTE) ch *128;
  398.       else
  399.         *pCh16++ = *pCh16 + (BYTE) ch *128;
  400.       break;
  401.     case 16:
  402.       if (TipoCopia == COPIA_NOMIX)
  403.         {
  404.           *pCh++ = (BYTE) ch;
  405.           ch = fgetc (MonoFile);
  406.           *pCh++ = (BYTE) ch;
  407.         }
  408.       else
  409.         {
  410.           *pCh++ = *pCh + (BYTE) ch;
  411.           ch = fgetc (MonoFile);
  412.           *pCh++ = *pCh + (BYTE) ch;
  413.         }
  414.       break;
  415.     default:
  416.       SendMsg (FUNC_READ_MONO, ERR_RISOLUZIONE);
  417.       sprintf (retstr->strptr, "%i", ERR_RISOLUZIONE);
  418.       retstr->strlength = strlen (retstr->strptr);
  419.       break;
  420.     }
  421.     }
  422.  
  423.   rc = fclose (MonoFile);
  424.   if (rc)
  425.     {
  426.       SendMsg (FUNC_READ_MONO, ERR_CLOSE_FILE);
  427.       sprintf (retstr->strptr, "%i", ERR_CLOSE_FILE);
  428.       retstr->strlength = strlen (retstr->strptr);
  429.       return VALID_ROUTINE;
  430.     }
  431.  
  432.   sprintf (retstr->strptr, "%i", ERR_OK);
  433.   retstr->strlength = strlen (retstr->strptr);
  434.   return VALID_ROUTINE;
  435. }
  436.  
  437.  
  438. /***********************************************************************
  439. Scrive un file WAV Mono.
  440. Vuole il nome del file e due puntatori a traccie gia' allocate e il
  441. numero di campioni da scaricare
  442. ***********************************************************************/
  443. ULONG
  444. WavWriteMono (PCSZ name, LONG argc, const RXSTRING * argv,
  445.           PCSZ queuename, PRXSTRING retstr)
  446. {
  447.   FILE *MonoFile;
  448.   UCHAR NomeFile[256];
  449.   PBYTE pCh = NULL;
  450.   struct wav DatiWAV;
  451.   ULONG nCamp, i;
  452.   APIRET rc;
  453.  
  454.   if (argc != 3)
  455.     {
  456.       SendMsg (FUNC_WRITE_MONO, ERR_NUMERO_PARAMETRI);
  457.       return INVALID_ROUTINE;
  458.     }
  459.  
  460.   strcpy (NomeFile, argv[0].strptr);
  461.  
  462.   if (!sscanf (argv[1].strptr, "%d", &pCh))
  463.     {
  464.       SendMsg (FUNC_WRITE_MONO, ERR_PUNTATORE_ERRATO);
  465.       return INVALID_ROUTINE;
  466.     }
  467.  
  468.   nCamp = atol (argv[2].strptr);
  469.   if (!nCamp)
  470.     {
  471.       SendMsg (FUNC_WRITE_MONO, ERR_NUMERO_CAMPIONI);
  472.       return INVALID_ROUTINE;
  473.     }
  474.  
  475.   if ((MonoFile = fopen (NomeFile, "wb")) == NULL)
  476.     {
  477.       SendMsg (FUNC_WRITE_MONO, ERR_OPEN_FILE);
  478.       sprintf (retstr->strptr, "%i", ERR_OPEN_FILE);
  479.       retstr->strlength = strlen (retstr->strptr);
  480.       return VALID_ROUTINE;
  481.     }
  482.  
  483.   strcpy (DatiWAV.w_riff, "RIFF");
  484.   strcpy (DatiWAV.w_wave, "WAVE");
  485.   strcpy (DatiWAV.w_fmt, "fmt ");
  486.   strcpy (DatiWAV.w_data, "data");
  487.   DatiWAV.w_len_tot = (nCamp * NBit / 8) + sizeof (struct wav) - 8;
  488.   DatiWAV.w_len_fmt = 16;
  489.   DatiWAV.w_stereo = 1;
  490.   DatiWAV.w_freq_camp = FreqCamp;
  491.   DatiWAV.w_byte_sec = FreqCamp * (NBit / 8);
  492.   DatiWAV.w_block_align = 4;
  493.   DatiWAV.w_bit_camp = NBit;
  494.   DatiWAV.w_len_data = (nCamp * 2) + sizeof (struct wav) - 44;
  495.   DatiWAV.w_format_tag = 1;
  496.  
  497.   if (!(fwrite (&DatiWAV, sizeof (struct wav), 1, MonoFile)))
  498.     {
  499.       SendMsg (FUNC_WRITE_MONO, ERR_WRITE_WAV_STRUCT);
  500.       sprintf (retstr->strptr, "%i", ERR_WRITE_WAV_STRUCT);
  501.       retstr->strlength = strlen (retstr->strptr);
  502.       return VALID_ROUTINE;
  503.     }
  504.  
  505.   pCh = AllineaCh (pCh, nCamp, FUNC_WRITE_MONO);
  506.   if (!pCh)
  507.     return INVALID_ROUTINE;
  508.  
  509.   for (i = nCamp; i; i--)
  510.     {
  511.       putc (*pCh++, MonoFile);
  512.       putc (*pCh++, MonoFile);
  513.     }
  514.  
  515.   rc = fclose (MonoFile);
  516.   if (rc)
  517.     {
  518.       SendMsg (FUNC_WRITE_MONO, ERR_CLOSE_FILE);
  519.       sprintf (retstr->strptr, "%i", ERR_CLOSE_FILE);
  520.       retstr->strlength = strlen (retstr->strptr);
  521.       return VALID_ROUTINE;
  522.     }
  523.  
  524.   sprintf (retstr->strptr, "%i", ERR_OK);
  525.   retstr->strlength = strlen (retstr->strptr);
  526.   return VALID_ROUTINE;
  527. }
  528.  
  529.  
  530. /***********************************************************************
  531. Copia una traccia su di un'altra
  532. Vuole i puntatori alla traccie di origine e di destinazione ed il numero
  533. di campioni da copiare;
  534. Opzionalmente l'ampiezza iniziale e quella finale da 0 a 1 ed il tipo di
  535. inviluppo, lin(eare) o log(aritmico), ed il tipo di copia, mix o over
  536. il parametro 'D'ither permette l'aggiunta di rumore di ampiezza pari a
  537. 1/2 bit meno significativo
  538. ***********************************************************************/
  539. ULONG
  540. WavCopyTrac (PCSZ name, LONG argc, const RXSTRING * argv,
  541.          PCSZ queuename, PRXSTRING retstr)
  542. {
  543.   PSHORT pFrom = NULL;
  544.   PSHORT pTo = NULL;
  545.   ULONG nCamp, i;
  546.   double AmpInizio = 1;
  547.   double AmpFine = 1;
  548.   INT TipoInviluppo = 0, dither;
  549.   ULONG TipoCopia = COPIA_NOMIX;
  550.   APIRET rc;
  551.  
  552.   if ((argc < 3) || (argc > 8))
  553.     {
  554.       SendMsg (FUNC_COPY_TRAC, ERR_NUMERO_PARAMETRI);
  555.       return INVALID_ROUTINE;
  556.     }
  557.  
  558.   if (!sscanf (argv[0].strptr, "%d", &pFrom))
  559.     {
  560.       SendMsg (FUNC_COPY_TRAC, ERR_PUNTATORE_ERRATO);
  561.       return INVALID_ROUTINE;
  562.     }
  563.  
  564.   if (!sscanf (argv[1].strptr, "%d", &pTo))
  565.     {
  566.       SendMsg (FUNC_COPY_TRAC, ERR_PUNTATORE_ERRATO);
  567.       return INVALID_ROUTINE;
  568.     }
  569.  
  570.   nCamp = atol (argv[2].strptr);
  571.   if (nCamp < 0)
  572.     {
  573.       SendMsg (FUNC_COPY_TRAC, ERR_NUMERO_CAMPIONI);
  574.       return INVALID_ROUTINE;
  575.     }
  576.  
  577.   if (argc > 3)
  578.     {
  579.       AmpInizio = atof (argv[3].strptr);
  580.       if ((AmpInizio < -9) || (AmpInizio > 9))
  581.     {
  582.       SendMsg (FUNC_COPY_TRAC, ERR_AMPIEZZA);
  583.       return INVALID_ROUTINE;
  584.     }
  585.     }
  586.  
  587.   if (argc > 4)
  588.     {
  589.       AmpFine = atof (argv[4].strptr);
  590.       if ((AmpFine < -9) || (AmpFine > 9))
  591.     {
  592.       SendMsg (FUNC_COPY_TRAC, ERR_AMPIEZZA);
  593.       return INVALID_ROUTINE;
  594.     }
  595.     }
  596.  
  597.   if (argc > 5)
  598.     {
  599.       if (!strncmp (argv[5].strptr, "COST", 4))
  600.     TipoInviluppo = 0;
  601.       if (!strncmp (argv[5].strptr, "LIN", 3))
  602.     TipoInviluppo = 1;
  603.       if (!strncmp (argv[5].strptr, "LOG", 3))
  604.     TipoInviluppo = 2;
  605.     }
  606.  
  607.   if (argc > 6)
  608.     {
  609.       if (!strncmp (argv[6].strptr, "MIX", 3))
  610.     TipoCopia = COPIA_MIX;
  611.       if (!strncmp (argv[6].strptr, "NOMIX", 5))
  612.     TipoCopia = COPIA_NOMIX;
  613.       if (!strncmp (argv[6].strptr, "INV_MIX", 7))
  614.     TipoCopia = COPIA_INV_MIX;
  615.       if (!strncmp (argv[6].strptr, "INV_NOMIX", 9))
  616.     TipoCopia = COPIA_INV_NOMIX;
  617.     }
  618.  
  619.   if (argc > 7)
  620.     {
  621.       if (strncmp (argv[7].strptr, "D", 1))
  622.     dither = TRUE;
  623.       else
  624.     dither = FALSE;
  625.     }
  626.  
  627.   pFrom = AllineaCh (pFrom, nCamp, FUNC_COPY_TRAC);
  628.   if (!pFrom)
  629.     return INVALID_ROUTINE;
  630.  
  631.   pTo = AllineaCh (pTo, nCamp, FUNC_COPY_TRAC);
  632.   if (!pTo)
  633.     return INVALID_ROUTINE;
  634.  
  635.   if ((AmpInizio == 1) & (AmpFine == 1))
  636.     TipoInviluppo = 0;
  637.  
  638.   switch (TipoInviluppo)
  639.     {
  640.     case INVILUPPO_COSTANTE:
  641.       switch (TipoCopia)
  642.     {
  643.     case COPIA_NOMIX:
  644.       CopyTrk (pFrom, pTo, nCamp, 0);
  645.       break;
  646.     case COPIA_MIX:
  647.       MixTrk (pFrom, pTo, nCamp, 0);
  648.       break;
  649.     case COPIA_INV_NOMIX:
  650.       CopyTrk (pFrom, pTo, nCamp, 1);
  651.       break;
  652.     case COPIA_INV_MIX:
  653.       MixTrk (pFrom, pTo, nCamp, 1);
  654.       break;
  655.     default:
  656.       SendMsg (FUNC_COPY_TRAC, ERR_INVILUPPO);
  657.       sprintf (retstr->strptr, "%i", ERR_INVILUPPO);
  658.       retstr->strlength = strlen (retstr->strptr);
  659.       return INVALID_ROUTINE;
  660.       break;
  661.     }
  662.       break;
  663.     case INVILUPPO_LINEARE:
  664.       switch (TipoCopia)
  665.     {
  666.     case COPIA_NOMIX:
  667.       CopyLin (pFrom, pTo, nCamp, AmpInizio, AmpFine, 0, dither);
  668.       break;
  669.     case COPIA_MIX:
  670.       MixLin (pFrom, pTo, nCamp, AmpInizio, AmpFine, 0, dither);
  671.       break;
  672.     case COPIA_INV_NOMIX:
  673.       CopyLin (pFrom, pTo, nCamp, AmpInizio, AmpFine, 1, dither);
  674.       break;
  675.     case COPIA_INV_MIX:
  676.       MixLin (pFrom, pTo, nCamp, AmpInizio, AmpFine, 1, dither);
  677.       break;
  678.     default:
  679.       SendMsg (FUNC_COPY_TRAC, ERR_INVILUPPO);
  680.       sprintf (retstr->strptr, "%i", ERR_INVILUPPO);
  681.       retstr->strlength = strlen (retstr->strptr);
  682.       return INVALID_ROUTINE;
  683.       break;
  684.     }
  685.       break;
  686.     case INVILUPPO_LOGARITMICO:
  687.       switch (TipoCopia)
  688.     {
  689.     case COPIA_NOMIX:
  690.       CopyLog (pFrom, pTo, nCamp, AmpInizio, AmpFine, 0, dither);
  691.       break;
  692.     case COPIA_MIX:
  693.       MixLog (pFrom, pTo, nCamp, AmpInizio, AmpFine, 0, dither);
  694.       break;
  695.     case COPIA_INV_NOMIX:
  696.       CopyLog (pFrom, pTo, nCamp, AmpInizio, AmpFine, 1, dither);
  697.       break;
  698.     case COPIA_INV_MIX:
  699.       MixLog (pFrom, pTo, nCamp, AmpInizio, AmpFine, 1, dither);
  700.       break;
  701.     default:
  702.       SendMsg (FUNC_COPY_TRAC, ERR_INVILUPPO);
  703.       sprintf (retstr->strptr, "%i", ERR_INVILUPPO);
  704.       retstr->strlength = strlen (retstr->strptr);
  705.       return INVALID_ROUTINE;
  706.       break;
  707.     }
  708.       break;
  709.     default:
  710.       SendMsg (FUNC_COPY_TRAC, ERR_INVILUPPO);
  711.       sprintf (retstr->strptr, "%i", ERR_INVILUPPO);
  712.       retstr->strlength = strlen (retstr->strptr);
  713.       return INVALID_ROUTINE;
  714.       break;
  715.     }
  716.  
  717.  
  718.   sprintf (retstr->strptr, "%i", ERR_OK);
  719.   retstr->strlength = strlen (retstr->strptr);
  720.   return VALID_ROUTINE;
  721. }
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730. /***********************************************************************
  731.          ********* Funzioni di copia tra tracce ***********
  732. ***********************************************************************/
  733. CopyTrk (SHORT * pFrom, SHORT * pTo, INT nCampioni, int inverti)
  734. {
  735.   INT i;
  736.  
  737.   if (inverti)
  738.     {
  739.       for (i = nCampioni; i != 0; i--)
  740.     {
  741.       *pTo = -*pFrom;
  742.       pFrom++;
  743.       pTo++;
  744.     }
  745.     }
  746.   else
  747.     {
  748.       for (i = nCampioni; i != 0; i--)
  749.     {
  750.       *pTo = *pFrom;
  751.       pFrom++;
  752.       pTo++;
  753.     }
  754.     }
  755. }
  756.  
  757.  
  758. MixTrk (SHORT * pFrom, SHORT * pTo, INT nCampioni, int inverti)
  759. {
  760.   INT i;
  761.  
  762.   if (inverti)
  763.     {
  764.       for (i = nCampioni; i != 0; i--)
  765.     {
  766.       *pTo = *pTo - *pFrom;
  767.       pFrom++;
  768.       pTo++;
  769.     }
  770.     }
  771.   else
  772.     {
  773.       for (i = nCampioni; i != 0; i--)
  774.     {
  775.       *pTo = *pTo + *pFrom;
  776.       pFrom++;
  777.       pTo++;
  778.     }
  779.     }
  780. }
  781.  
  782.  
  783.  
  784. CopyLin (SHORT * pFrom, SHORT * pTo, INT nCampioni, float AmpInizio, float AmpFine, int inverti, int dither)
  785. {
  786.   INT i;
  787.   double ki, kf, kd;
  788.   ki = AmpInizio;
  789.   kf = AmpFine;
  790.   kd = (kf - ki) / nCampioni;
  791.  
  792.   if (dither)
  793.     {
  794.       if (inverti)
  795.     {
  796.       for (i = nCampioni; i != 0; i--)
  797.         {
  798.           *pTo = -*pFrom * ki + (rand () - rand ()) / MAX_CAMPIONE;
  799.           ki = ki + kd;
  800.           pFrom++;
  801.           pTo++;
  802.         }
  803.     }
  804.       else
  805.     {
  806.       for (i = nCampioni; i != 0; i--)
  807.         {
  808.           *pTo = *pFrom * ki + (rand () - rand ()) / MAX_CAMPIONE;
  809.           ki = ki + kd;
  810.           pFrom++;
  811.           pTo++;
  812.         }
  813.     }
  814.     }
  815.   else
  816.     {
  817.       if (inverti)
  818.     {
  819.       for (i = nCampioni; i != 0; i--)
  820.         {
  821.           *pTo = -*pFrom * ki;
  822.           ki = ki + kd;
  823.           pFrom++;
  824.           pTo++;
  825.         }
  826.     }
  827.       else
  828.     {
  829.       for (i = nCampioni; i != 0; i--)
  830.         {
  831.           *pTo = *pFrom * ki;
  832.           ki = ki + kd;
  833.           pFrom++;
  834.           pTo++;
  835.         }
  836.     }
  837.     }
  838. }
  839.  
  840.  
  841. MixLin (SHORT * pFrom, SHORT * pTo, INT nCampioni, double AmpInizio, double AmpFine, int inverti, int dither)
  842. {
  843.   INT i;
  844.   double ki, kf, kd;
  845.   ki = AmpInizio;
  846.   kf = AmpFine;
  847.   kd = (kf - ki) / nCampioni;
  848.  
  849.   if (dither)
  850.     {
  851.       if (inverti)
  852.     {
  853.       for (i = nCampioni; i != 0; i--)
  854.         {
  855.           *pTo = *pTo - *pFrom * ki + (rand () - rand ()) / MAX_CAMPIONE;
  856.           ki = ki + kd;
  857.           pFrom++;
  858.           pTo++;
  859.         }
  860.     }
  861.       else
  862.     {
  863.       for (i = nCampioni; i != 0; i--)
  864.         {
  865.           *pTo = *pTo + *pFrom * ki + (rand () - rand ()) / MAX_CAMPIONE;
  866.           ki = ki + kd;
  867.           pFrom++;
  868.           pTo++;
  869.         }
  870.     }
  871.     }
  872.   else
  873.     {
  874.       if (inverti)
  875.     {
  876.       for (i = nCampioni; i != 0; i--)
  877.         {
  878.           *pTo = *pTo - *pFrom * ki;
  879.           ki = ki + kd;
  880.           pFrom++;
  881.           pTo++;
  882.         }
  883.     }
  884.       else
  885.     {
  886.       for (i = nCampioni; i != 0; i--)
  887.         {
  888.           *pTo = *pTo + *pFrom * ki;
  889.           ki = ki + kd;
  890.           pFrom++;
  891.           pTo++;
  892.         }
  893.     }
  894.     }
  895. }
  896.  
  897.  
  898. CopyLog (SHORT * pFrom, SHORT * pTo, INT nCampioni, double AmpInizio, double AmpFine, int inverti, int dither)
  899. {
  900.   INT i;
  901.   double ki, kf, kd, kz;
  902.   ki = AmpInizio;
  903.   kf = AmpFine;
  904.   kd = (kf - ki) / nCampioni;
  905.   kz = exp (1);
  906.  
  907.   if (dither)
  908.     {
  909.       if (inverti)
  910.     {
  911.       for (i = nCampioni; i != 0; i--)
  912.         {
  913.           *pTo = -*pFrom * ki * (exp (ki) / kz) + (rand () - rand ()) / MAX_CAMPIONE;
  914.           ki = ki + kd;
  915.           pFrom++;
  916.           pTo++;
  917.         }
  918.     }
  919.       else
  920.     {
  921.       for (i = nCampioni; i != 0; i--)
  922.         {
  923.           *pTo = *pFrom * ki * (exp (ki) / kz) + (rand () - rand ()) / MAX_CAMPIONE;
  924.           ki = ki + kd;
  925.           pFrom++;
  926.           pTo++;
  927.         }
  928.     }
  929.     }
  930.   else
  931.     {
  932.       if (inverti)
  933.     {
  934.       for (i = nCampioni; i != 0; i--)
  935.         {
  936.           *pTo = -*pFrom * ki * (exp (ki) / kz);
  937.           ki = ki + kd;
  938.           pFrom++;
  939.           pTo++;
  940.         }
  941.     }
  942.       else
  943.     {
  944.       for (i = nCampioni; i != 0; i--)
  945.         {
  946.           *pTo = *pFrom * ki * (exp (ki) / kz);
  947.           ki = ki + kd;
  948.           pFrom++;
  949.           pTo++;
  950.         }
  951.     }
  952.     }
  953. }
  954.  
  955.  
  956. MixLog (SHORT * pFrom, SHORT * pTo, INT nCampioni, double AmpInizio, double AmpFine, int inverti, int dither)
  957. {
  958.   INT i;
  959.   double ki, kf, kd, kz;
  960.   ki = AmpInizio;
  961.   kf = AmpFine;
  962.   kd = (kf - ki) / nCampioni;
  963.   kz = exp (1);
  964.  
  965.   if (dither)
  966.     {
  967.       if (inverti)
  968.     {
  969.       for (i = nCampioni; i != 0; i--)
  970.         {
  971.           *pTo = *pTo - *pFrom * ki * exp (ki) / kz + (rand () - rand ()) / MAX_CAMPIONE;
  972.           ki = ki + kd;
  973.           pFrom++;
  974.           pTo++;
  975.         }
  976.     }
  977.       else
  978.     {
  979.       for (i = nCampioni; i != 0; i--)
  980.         {
  981.           *pTo = *pTo + *pFrom * ki * exp (ki) / kz + (rand () - rand ()) / MAX_CAMPIONE;
  982.           ki = ki + kd;
  983.           pFrom++;
  984.           pTo++;
  985.         }
  986.     }
  987.     }
  988.   else
  989.     {
  990.       if (inverti)
  991.     {
  992.       for (i = nCampioni; i != 0; i--)
  993.         {
  994.           *pTo = *pTo - *pFrom * ki * exp (ki) / kz;
  995.           ki = ki + kd;
  996.           pFrom++;
  997.           pTo++;
  998.         }
  999.     }
  1000.       else
  1001.     {
  1002.       for (i = nCampioni; i != 0; i--)
  1003.         {
  1004.           *pTo = *pTo + *pFrom * ki * exp (ki) / kz;
  1005.           ki = ki + kd;
  1006.           pFrom++;
  1007.           pTo++;
  1008.         }
  1009.     }
  1010.     }
  1011. }
  1012.