home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 13 / MA_Cover_13.bin / source / c / ahisrc / device / effectinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-18  |  8.2 KB  |  335 lines

  1. /* $Id: effectinit.c,v 4.18 1999/09/18 09:16:25 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 <inline/ahi.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.     audioctrl->ahiac_EchoMasterVolume = 0x10000;
  185.  
  186.     update_MasterVolume( audioctrl );
  187.  
  188.     switch(mode)
  189.     {
  190.       // 32bit
  191.       case 2:
  192.         es->ahiecho_Code   = do_DSPEchoMono32;
  193.         break;
  194.  
  195.       // stereo 32bit
  196.       case 3:
  197.         es->ahiecho_Code   = do_DSPEchoStereo32;
  198.         break;
  199.  
  200.       // Should not happen!
  201.       default:
  202.         AHIFreeVec(es);
  203.         return FALSE;
  204.     }
  205.  
  206.     // Structure filled, make it available to the mixing routine
  207.  
  208.     audioctrl->ahiac_EffDSPEchoStruct = es;
  209.  
  210.     return TRUE;
  211.   }
  212.  
  213.   return FALSE;
  214. }
  215.  
  216.  
  217. void
  218. free_DSPEcho ( struct AHIPrivAudioCtrl *audioctrl )
  219. {
  220.   void *p = audioctrl->ahiac_EffDSPEchoStruct;
  221.  
  222.   // Hide it from mixing routine before freeing it!
  223.   audioctrl->ahiac_EffDSPEchoStruct = NULL;
  224.   AHIFreeVec(p);
  225.  
  226.   audioctrl->ahiac_EchoMasterVolume = 0x10000;
  227.   update_MasterVolume( audioctrl );
  228. }
  229.  
  230.  
  231.  
  232.  
  233. /******************************************************************************
  234. ** DSPMASK ********************************************************************
  235. ******************************************************************************/
  236.  
  237. static void
  238. addchannel ( struct AHIChannelData **list, struct AHIChannelData *cd )
  239. {
  240.   struct AHIChannelData *ptr;
  241.  
  242.   if(*list == NULL)
  243.   {
  244.     *list = cd;
  245.   }
  246.   else
  247.   {
  248.     ptr = *list;
  249.     while(ptr->cd_Succ != NULL)
  250.     {
  251.       ptr = ptr->cd_Succ;
  252.     }
  253.     ptr->cd_Succ = cd;
  254.   }
  255.  
  256.   cd->cd_Succ = NULL;
  257. }
  258.  
  259. BOOL 
  260. update_DSPMask ( struct AHIEffDSPMask *mask,
  261.                  struct AHIPrivAudioCtrl *audioctrl )
  262. {
  263.   struct AHIChannelData *cd, *wet = NULL, *dry = NULL;
  264.   struct Library        *AHIsubBase;
  265.   int                    i;
  266.   UBYTE                 *flag;
  267.  
  268.   if(mask->ahiedm_Channels != audioctrl->ac.ahiac_Channels)
  269.   {
  270.     return FALSE;
  271.   }
  272.  
  273.   cd = audioctrl->ahiac_ChannelDatas;
  274.  
  275.   flag = mask->ahiedm_Mask;
  276.  
  277.   AHIsubBase = audioctrl->ahiac_SubLib;
  278.  
  279.   AHIsub_Disable(&audioctrl->ac);
  280.  
  281.   for(i = 0; i < audioctrl->ac.ahiac_Channels; i++)
  282.   {
  283.     if(*flag == AHIEDM_WET)
  284.     {
  285.       addchannel(&wet, cd);
  286.     }
  287.     else
  288.     {
  289.       addchannel(&dry, cd);
  290.     }
  291.     
  292.     flag++;
  293.     cd++;
  294.   }
  295.  
  296.   audioctrl->ahiac_WetList = wet;
  297.   audioctrl->ahiac_DryList = dry;
  298.  
  299.   AHIsub_Enable(&audioctrl->ac);
  300.  
  301.   return TRUE;
  302. }
  303.  
  304.  
  305. void
  306. clear_DSPMask ( struct AHIPrivAudioCtrl *audioctrl )
  307. {
  308.   struct AHIChannelData *cd;
  309.   struct Library        *AHIsubBase;
  310.   int                    i;
  311.  
  312.   // Make all channels wet
  313.  
  314.   cd = audioctrl->ahiac_ChannelDatas;
  315.  
  316.   audioctrl->ahiac_WetList = cd;
  317.   audioctrl->ahiac_DryList = NULL;
  318.  
  319.   AHIsubBase = audioctrl->ahiac_SubLib;
  320.  
  321.   AHIsub_Disable(&audioctrl->ac);
  322.  
  323.   for(i = 0; i < audioctrl->ac.ahiac_Channels - 1; i++)
  324.   {
  325.     // Set link to next channel
  326.     cd->cd_Succ = cd + 1;
  327.     cd++;
  328.   }
  329.  
  330.   // Clear the last link;
  331.   cd->cd_Succ = NULL;
  332.  
  333.   AHIsub_Enable(&audioctrl->ac);
  334. }
  335.