home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 106 / EnigmaAmiga106CD.iso / software / sviluppo / ahisrc / device / effectinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-04-22  |  11.0 KB  |  472 lines

  1. /* $Id: effectinit.c,v 4.16 1999/04/22 19:42:13 lcs Exp $ */
  2.  
  3. /*
  4.      AHI - Hardware independent audio subsystem
  5.      Copyright (C) 1996-1999 Martin Blom <martin@blom.org>
  6.      
  7.      This library is free software; you can redistribute it and/or
  8.      modify it under the terms of the GNU Library General Public
  9.      License as published by the Free Software Foundation; either
  10.      version 2 of the License, or (at your option) any later version.
  11.      
  12.      This library is distributed in the hope that it will be useful,
  13.      but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.      Library General Public License for more details.
  16.      
  17.      You should have received a copy of the GNU Library General Public
  18.      License along with this library; if not, write to the
  19.      Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
  20.      MA 02139, USA.
  21. */
  22.  
  23. #include <config.h>
  24. #include <CompilerSpecific.h>
  25.  
  26. #include <exec/memory.h>
  27. #include <powerup/ppclib/memory.h>
  28. #include <proto/exec.h>
  29. #include <clib/ahi_protos.h>
  30. #include <pragmas/ahi_pragmas.h>
  31. #include <proto/ahi_sub.h>
  32.  
  33. #include "ahi_def.h"
  34. #include "dsp.h"
  35. #include "dspecho.h"
  36. #include "effectinit.h"
  37. #include "misc.h"
  38. #include "mixer.h"
  39.  
  40.  
  41. /***********************************************
  42. ***** NOTE: The mixing routine might execute while we are inside these
  43. ***** functions!
  44. ***********************************************/
  45.  
  46.  
  47. /******************************************************************************
  48. ** MASTERVOLUME ***************************************************************
  49. ******************************************************************************/
  50.  
  51. BOOL 
  52. update_MasterVolume ( struct AHIPrivAudioCtrl *audioctrl )
  53. {
  54.   struct Library        *AHIsubBase;
  55.   struct AHIChannelData *cd;
  56.   Fixed                  volume;
  57.   int                    i;
  58.  
  59.   if(audioctrl->ac.ahiac_Flags & AHIACF_CLIPPING)
  60.   {
  61.     volume = 0x10000;
  62.   }
  63.   else
  64.   {
  65.     volume = audioctrl->ahiac_SetMasterVolume;
  66.   }
  67.  
  68.   /* Scale to what the echo effect think is best... */
  69.   volume = (volume * (audioctrl->ahiac_EchoMasterVolume >> 8)) >> 8;
  70.  
  71.   /* This is the actual master volume in use */
  72.   audioctrl->ahiac_MasterVolume = volume;
  73.  
  74.   /* Update the mastervolume table, and the volume tables */
  75.   calcMasterVolumeTable( audioctrl );
  76.   calcSignedTable( audioctrl );
  77.   calcUnsignedTable( audioctrl );
  78.  
  79.   /* Update volume for channels */
  80.  
  81.   AHIsubBase = audioctrl->ahiac_SubLib;
  82.  
  83.   AHIsub_Disable(&audioctrl->ac);
  84.  
  85.   for(i = audioctrl->ac.ahiac_Channels, cd = audioctrl->ahiac_ChannelDatas;
  86.       i > 0;
  87.       i--, cd++)
  88.   {
  89.     SelectAddRoutine(cd->cd_VolumeLeft, cd->cd_VolumeRight, cd->cd_Type, audioctrl,
  90.                      &cd->cd_ScaleLeft, &cd->cd_ScaleRight, (ADDFUNC**) &cd->cd_AddRoutine);
  91.     SelectAddRoutine(cd->cd_NextVolumeLeft, cd->cd_NextVolumeRight, cd->cd_NextType, audioctrl,
  92.                      &cd->cd_NextScaleLeft, &cd->cd_NextScaleRight, (ADDFUNC**) &cd->cd_NextAddRoutine);
  93.   }
  94.  
  95.   AHIsub_Enable(&audioctrl->ac);
  96.  
  97.   return TRUE;
  98. }
  99.  
  100.  
  101. /******************************************************************************
  102. ** DSPECHO ********************************************************************
  103. ******************************************************************************/
  104.  
  105. #define mode_stereo 1
  106. #define mode_32bit  2
  107. #define mode_ncnm   4       // No cross, no mix
  108. #define mode_fast   8
  109.  
  110. BOOL
  111. update_DSPEcho ( struct AHIEffDSPEcho *echo,
  112.                  struct AHIPrivAudioCtrl *audioctrl )
  113. {
  114.   ULONG size, samplesize;
  115.   struct Echo *es;
  116.  
  117.   free_DSPEcho( audioctrl );
  118.  
  119.  
  120.   /* Set up the delay buffer format */
  121.  
  122.   switch(audioctrl->ac.ahiac_BuffType)
  123.   {
  124.     case AHIST_M16S:
  125.     case AHIST_M32S:
  126.       samplesize = 2;
  127.       break;
  128.  
  129.     case AHIST_S16S:
  130.     case AHIST_S32S:
  131.       samplesize = 4;
  132.       break;
  133.  
  134.     default:
  135.       return FALSE; // Panic
  136.   }
  137.  
  138.   size = samplesize * (echo->ahiede_Delay + audioctrl->ac.ahiac_MaxBuffSamples);
  139.  
  140.   es = AHIAllocVec( sizeof(struct Echo) + size,
  141.                     MEMF_PUBLIC | MEMF_CLEAR |
  142.                     MEMF_NOCACHESYNCPPC | MEMF_NOCACHESYNCM68K );
  143.   
  144.   if(es)
  145.   {
  146.     ULONG mode = 0;
  147.  
  148.     es->ahiecho_Offset       = 0;
  149.     es->ahiecho_SrcPtr       = es->ahiecho_Buffer;
  150.     es->ahiecho_DstPtr       = es->ahiecho_Buffer + (samplesize * echo->ahiede_Delay);
  151.     es->ahiecho_EndPtr       = es->ahiecho_Buffer + size;
  152.     es->ahiecho_BufferLength = echo->ahiede_Delay + audioctrl->ac.ahiac_MaxBuffSamples;
  153.     es->ahiecho_BufferSize   = size;
  154.  
  155.     switch(audioctrl->ac.ahiac_BuffType)
  156.     {
  157.       case AHIST_M16S:
  158.         echo->ahiede_Cross = 0;
  159.         break;
  160.       case AHIST_S16S:
  161.         mode |= mode_stereo;
  162.         break;
  163.       case AHIST_M32S:
  164.         echo->ahiede_Cross = 0;
  165.         mode |= mode_32bit;
  166.         break;
  167.       case AHIST_S32S:
  168.         mode |= (mode_32bit | mode_stereo);
  169.         break;
  170.     }
  171.  
  172.     es->ahiecho_Delay      = echo->ahiede_Delay;
  173.     es->ahiecho_MixD       = echo->ahiede_Mix;
  174.     es->ahiecho_MixN       = 0x10000 - echo->ahiede_Mix;
  175.     es->ahiecho_FeedbackDO = (echo->ahiede_Feedback >> 8) *
  176.                              (echo->ahiede_Cross >> 8);
  177.     es->ahiecho_FeedbackDS = (echo->ahiede_Feedback >> 8) *
  178.                              ((0x10000 - echo->ahiede_Cross) >> 8);
  179.     es->ahiecho_FeedbackNO = ((0x10000 - echo->ahiede_Feedback) >> 8) *
  180.                              (echo->ahiede_Cross >> 8);
  181.     es->ahiecho_FeedbackNS = ((0x10000 - echo->ahiede_Feedback) >> 8) *
  182.                              ((0x10000 - echo->ahiede_Cross) >> 8);
  183.  
  184.  
  185. #ifndef VERSION68K
  186.  
  187.     audioctrl->ahiac_EchoMasterVolume = 0x10000;
  188.  
  189. #else
  190.  
  191.     if((echo->ahiede_Cross == 0) && (echo->ahiede_Mix == 0x10000))
  192.     {
  193.       mode |= mode_ncnm;
  194.       audioctrl->ahiac_EchoMasterVolume = es->ahiecho_FeedbackNS;
  195.     }
  196.     else
  197.     {
  198.       audioctrl->ahiac_EchoMasterVolume = 0x10000;
  199.     }
  200.  
  201. #endif
  202.  
  203.     update_MasterVolume( audioctrl );
  204.  
  205. #ifdef VERSION68K
  206.  
  207.     /* No fast echo in generic or PPC version*/
  208.  
  209.     // No fast echo in 32 bit (HiFi) modes!
  210.     switch(audioctrl->ac.ahiac_BuffType)
  211.     {
  212.       case AHIST_M16S:
  213.       case AHIST_S16S:
  214.         if((AHIBase->ahib_Flags & AHIBF_FASTECHO))
  215.         {
  216.           es->ahiecho_MixD = Fixed2Shift(es->ahiecho_MixD);
  217.           es->ahiecho_MixN = Fixed2Shift(es->ahiecho_MixN);
  218.           es->ahiecho_FeedbackDO = Fixed2Shift(es->ahiecho_FeedbackDO);
  219.           es->ahiecho_FeedbackDS = Fixed2Shift(es->ahiecho_FeedbackDS);
  220.           es->ahiecho_FeedbackNO = Fixed2Shift(es->ahiecho_FeedbackNO);
  221.           es->ahiecho_FeedbackNS = Fixed2Shift(es->ahiecho_FeedbackNS);
  222.           mode |= mode_fast;
  223.         }
  224.         break;
  225.  
  226.       default:
  227.         break;
  228.     }
  229.  
  230. #endif
  231.  
  232. #ifndef VERSION68K
  233.  
  234.     switch(mode)
  235.     {
  236.       // 32bit
  237.       case 2:
  238.         es->ahiecho_Code   = do_DSPEchoMono32;
  239.         break;
  240.  
  241.       // stereo 32bit
  242.       case 3:
  243.         es->ahiecho_Code   = do_DSPEchoStereo32;
  244.         break;
  245.  
  246.       // Should not happen!
  247.       default:
  248.         AHIFreeVec(es);
  249.         return FALSE;
  250.     }
  251.  
  252. #else
  253.  
  254.     switch(mode)
  255.     {
  256.       case 0:
  257.         es->ahiecho_Code   = do_DSPEchoMono16;
  258.         break;
  259.  
  260.       // stereo
  261.       case 1:
  262.         es->ahiecho_Code   = do_DSPEchoStereo16;
  263.         break;
  264.  
  265.       // 32bit
  266.       case 2:
  267.         es->ahiecho_Code   = do_DSPEchoMono32;
  268.         break;
  269.  
  270.       // stereo 32bit
  271.       case 3:
  272.         es->ahiecho_Code   = do_DSPEchoStereo32;
  273.         break;
  274.  
  275.       // ncnm
  276.       case 4:
  277.         es->ahiecho_Code   = do_DSPEchoMono16NCFM;
  278.         break;
  279.  
  280.       // stereo ncnm
  281.       case 5:
  282.         es->ahiecho_Code   = do_DSPEchoStereo16NCFM;
  283.         break;
  284.  
  285.       // 32bit ncnm
  286.       case 6:
  287.         es->ahiecho_Code   = do_DSPEchoMono32;
  288.         break;
  289.  
  290.       // stereo 32bit ncnm
  291.       case 7:
  292.         es->ahiecho_Code   = do_DSPEchoStereo32;
  293.         break;
  294.  
  295.       // fast
  296.       case 8:
  297.         es->ahiecho_Code   = do_DSPEchoMono16Fast;
  298.         break;
  299.  
  300.       // stereo fast
  301.       case 9:
  302.         es->ahiecho_Code   = do_DSPEchoStereo16Fast;
  303.         break;
  304.  
  305.       // 32bit fast
  306.       case 10:
  307.         es->ahiecho_Code   = do_DSPEchoMono32;
  308.         break;
  309.  
  310.       // stereo 32bit fast
  311.       case 11:
  312.         es->ahiecho_Code   = do_DSPEchoStereo32;
  313.         break;
  314.  
  315.       // ncnm fast
  316.       case 12:
  317.         es->ahiecho_Code   = do_DSPEchoMono16NCFMFast;
  318.         break;
  319.  
  320.       // stereo ncnm fast
  321.       case 13:
  322.         es->ahiecho_Code   = do_DSPEchoStereo16NCFMFast;
  323.         break;
  324.  
  325.       // 32bit ncnm fast
  326.       case 14:
  327.         es->ahiecho_Code   = do_DSPEchoMono32;
  328.         break;
  329.  
  330.       // stereo 32bit ncnm fast
  331.       case 15:
  332.         es->ahiecho_Code   = do_DSPEchoStereo32;
  333.         break;
  334.  
  335.       // Should not happen!
  336.       default:
  337.         AHIFreeVec(es);
  338.         return FALSE;
  339.     }
  340.  
  341. #endif
  342.  
  343.     // Structure filled, make it available to the mixing routine
  344.  
  345.     audioctrl->ahiac_EffDSPEchoStruct = es;
  346.  
  347.     return TRUE;
  348.   }
  349.  
  350.   return FALSE;
  351. }
  352.  
  353.  
  354. void
  355. free_DSPEcho ( struct AHIPrivAudioCtrl *audioctrl )
  356. {
  357.   void *p = audioctrl->ahiac_EffDSPEchoStruct;
  358.  
  359.   // Hide it from mixing routine before freeing it!
  360.   audioctrl->ahiac_EffDSPEchoStruct = NULL;
  361.   AHIFreeVec(p);
  362.  
  363.   audioctrl->ahiac_EchoMasterVolume = 0x10000;
  364.   update_MasterVolume( audioctrl );
  365. }
  366.  
  367.  
  368.  
  369.  
  370. /******************************************************************************
  371. ** DSPMASK ********************************************************************
  372. ******************************************************************************/
  373.  
  374. static void
  375. addchannel ( struct AHIChannelData **list, struct AHIChannelData *cd )
  376. {
  377.   struct AHIChannelData *ptr;
  378.  
  379.   if(*list == NULL)
  380.   {
  381.     *list = cd;
  382.   }
  383.   else
  384.   {
  385.     ptr = *list;
  386.     while(ptr->cd_Succ != NULL)
  387.     {
  388.       ptr = ptr->cd_Succ;
  389.     }
  390.     ptr->cd_Succ = cd;
  391.   }
  392.  
  393.   cd->cd_Succ = NULL;
  394. }
  395.  
  396. BOOL 
  397. update_DSPMask ( struct AHIEffDSPMask *mask,
  398.                  struct AHIPrivAudioCtrl *audioctrl )
  399. {
  400.   struct AHIChannelData *cd, *wet = NULL, *dry = NULL;
  401.   struct Library        *AHIsubBase;
  402.   int                    i;
  403.   UBYTE                 *flag;
  404.  
  405.   if(mask->ahiedm_Channels != audioctrl->ac.ahiac_Channels)
  406.   {
  407.     return FALSE;
  408.   }
  409.  
  410.   cd = audioctrl->ahiac_ChannelDatas;
  411.  
  412.   flag = mask->ahiedm_Mask;
  413.  
  414.   AHIsubBase = audioctrl->ahiac_SubLib;
  415.  
  416.   AHIsub_Disable(&audioctrl->ac);
  417.  
  418.   for(i = 0; i < audioctrl->ac.ahiac_Channels; i++)
  419.   {
  420.     if(*flag == AHIEDM_WET)
  421.     {
  422.       addchannel(&wet, cd);
  423.     }
  424.     else
  425.     {
  426.       addchannel(&dry, cd);
  427.     }
  428.     
  429.     flag++;
  430.     cd++;
  431.   }
  432.  
  433.   audioctrl->ahiac_WetList = wet;
  434.   audioctrl->ahiac_DryList = dry;
  435.  
  436.   AHIsub_Enable(&audioctrl->ac);
  437.  
  438.   return TRUE;
  439. }
  440.  
  441.  
  442. void
  443. clear_DSPMask ( struct AHIPrivAudioCtrl *audioctrl )
  444. {
  445.   struct AHIChannelData *cd;
  446.   struct Library        *AHIsubBase;
  447.   int                    i;
  448.  
  449.   // Make all channels wet
  450.  
  451.   cd = audioctrl->ahiac_ChannelDatas;
  452.  
  453.   audioctrl->ahiac_WetList = cd;
  454.   audioctrl->ahiac_DryList = NULL;
  455.  
  456.   AHIsubBase = audioctrl->ahiac_SubLib;
  457.  
  458.   AHIsub_Disable(&audioctrl->ac);
  459.  
  460.   for(i = 0; i < audioctrl->ac.ahiac_Channels - 1; i++)
  461.   {
  462.     // Set link to next channel
  463.     cd->cd_Succ = cd + 1;
  464.     cd++;
  465.   }
  466.  
  467.   // Clear the last link;
  468.   cd->cd_Succ = NULL;
  469.  
  470.   AHIsub_Enable(&audioctrl->ac);
  471. }
  472.