Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Device / effectinit.c
blobc33998874ec94140ed5b30ed9c1af2f8499eadb0
1 /*
2 AHI - Hardware independent audio subsystem
3 Copyright (C) 1996-2005 Martin Blom <martin@blom.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
18 MA 02139, USA.
21 #include <config.h>
23 #include <exec/memory.h>
24 #include <proto/exec.h>
25 #define __NOLIBBASE__
26 #define __NOGLOBALIFACE__
27 #include <proto/ahi.h>
28 #undef __NOLIBBASE__
29 #undef __NOGLOBALIFACE__
30 #include <proto/ahi_sub.h>
32 #include "ahi_def.h"
33 #include "dsp.h"
34 #include "dspecho.h"
35 #include "effectinit.h"
36 #include "header.h"
37 #include "misc.h"
38 #include "mixer.h"
40 #ifdef __AMIGAOS4__
41 #define IAHIsub audioctrl->ahiac_IAHIsub
42 #endif
44 /***********************************************
45 ***** NOTE: The mixing routine might execute while we are inside these
46 ***** functions!
47 ***********************************************/
50 /******************************************************************************
51 ** MASTERVOLUME ***************************************************************
52 ******************************************************************************/
54 BOOL
55 update_MasterVolume ( struct AHIPrivAudioCtrl *audioctrl )
57 struct Library *AHIsubBase;
58 struct AHIChannelData *cd;
59 Fixed volume;
60 int i;
62 /* In V5, clipping is always used:
64 * if(audioctrl->ac.ahiac_Flags & AHIACF_CLIPPING)
65 * {
66 * volume = 0x10000;
67 * }
68 * else
69 * {
70 * volume = audioctrl->ahiac_SetMasterVolume;
71 * }
74 volume = 0x10000;
76 /* Scale to what the echo effect think is best... */
77 volume = (volume * (audioctrl->ahiac_EchoMasterVolume >> 8)) >> 8;
79 /* This is the actual master volume in use */
80 audioctrl->ahiac_MasterVolume = volume;
82 /* Update volume for channels */
84 AHIsubBase = audioctrl->ahiac_SubLib;
86 AHIsub_Disable(&audioctrl->ac);
88 for(i = audioctrl->ac.ahiac_Channels, cd = audioctrl->ahiac_ChannelDatas;
89 i > 0;
90 i--, cd++)
92 SelectAddRoutine(cd->cd_VolumeLeft, cd->cd_VolumeRight, cd->cd_Type, audioctrl,
93 &cd->cd_ScaleLeft, &cd->cd_ScaleRight, (ADDFUNC**) &cd->cd_AddRoutine);
94 SelectAddRoutine(cd->cd_NextVolumeLeft, cd->cd_NextVolumeRight, cd->cd_NextType, audioctrl,
95 &cd->cd_NextScaleLeft, &cd->cd_NextScaleRight, (ADDFUNC**) &cd->cd_NextAddRoutine);
98 AHIsub_Enable(&audioctrl->ac);
100 return TRUE;
104 /******************************************************************************
105 ** DSPECHO ********************************************************************
106 ******************************************************************************/
108 #define mode_stereo 1
109 #define mode_32bit 2
110 #define mode_multi 4
112 BOOL
113 update_DSPEcho ( struct AHIEffDSPEcho *echo,
114 struct AHIPrivAudioCtrl *audioctrl )
116 ULONG size, samplesize;
117 struct Echo *es;
119 ULONG data_flags = MEMF_ANY;
121 switch( MixBackend )
123 case MB_NATIVE:
124 data_flags = MEMF_PUBLIC | MEMF_CLEAR;
125 break;
127 #if defined( ENABLE_WARPUP )
128 case MB_WARPUP:
129 // Non-cached from both the PPC and m68k side
130 data_flags = MEMF_PUBLIC | MEMF_CLEAR | MEMF_CHIP;
131 break;
132 #endif
135 /* Set up the delay buffer format */
137 switch(audioctrl->ac.ahiac_BuffType)
139 case AHIST_M16S:
140 case AHIST_M32S:
141 samplesize = 2;
142 break;
144 case AHIST_S16S:
145 case AHIST_S32S:
146 samplesize = 4;
147 break;
149 case AHIST_L7_1:
150 samplesize = 16;
151 break;
153 default:
154 return FALSE; // Panic
157 size = samplesize * (echo->ahiede_Delay + audioctrl->ac.ahiac_MaxBuffSamples);
159 es = AHIAllocVec( sizeof(struct Echo) + size,
160 data_flags );
162 if(es)
164 ULONG mode = 0;
166 es->ahiecho_Offset = 0;
167 es->ahiecho_SrcPtr = es->ahiecho_Buffer;
168 es->ahiecho_DstPtr = es->ahiecho_Buffer + (samplesize * echo->ahiede_Delay);
169 es->ahiecho_EndPtr = es->ahiecho_Buffer + size;
170 es->ahiecho_BufferLength = echo->ahiede_Delay + audioctrl->ac.ahiac_MaxBuffSamples;
171 es->ahiecho_BufferSize = size;
173 switch(audioctrl->ac.ahiac_BuffType)
175 case AHIST_M16S:
176 echo->ahiede_Cross = 0;
177 break;
178 case AHIST_S16S:
179 mode |= mode_stereo;
180 break;
181 case AHIST_M32S:
182 echo->ahiede_Cross = 0;
183 mode |= mode_32bit;
184 break;
185 case AHIST_S32S:
186 mode |= (mode_32bit | mode_stereo);
187 break;
188 case AHIST_L7_1:
189 mode |= (mode_32bit | mode_multi);
190 break;
193 es->ahiecho_Delay = echo->ahiede_Delay;
194 es->ahiecho_MixD = echo->ahiede_Mix;
195 es->ahiecho_MixN = 0x10000 - echo->ahiede_Mix;
196 es->ahiecho_FeedbackDO = (echo->ahiede_Feedback >> 8) *
197 (echo->ahiede_Cross >> 8);
198 es->ahiecho_FeedbackDS = (echo->ahiede_Feedback >> 8) *
199 ((0x10000 - echo->ahiede_Cross) >> 8);
200 es->ahiecho_FeedbackNO = ((0x10000 - echo->ahiede_Feedback) >> 8) *
201 (echo->ahiede_Cross >> 8);
202 es->ahiecho_FeedbackNS = ((0x10000 - echo->ahiede_Feedback) >> 8) *
203 ((0x10000 - echo->ahiede_Cross) >> 8);
205 audioctrl->ahiac_EchoMasterVolume = 0x10000;
207 update_MasterVolume( audioctrl );
209 switch(mode)
211 // 16 bit
212 case 0:
213 es->ahiecho_Code = do_DSPEchoMono16;
214 break;
216 // stereo 16 bit
217 case 1:
218 es->ahiecho_Code = do_DSPEchoStereo16;
219 break;
221 // 32 bit
222 case 2:
223 es->ahiecho_Code = do_DSPEchoMono32;
224 break;
226 // stereo 32 bit
227 case 3:
228 es->ahiecho_Code = do_DSPEchoStereo32;
229 break;
231 // multichannel 32 bit
232 case 6:
233 es->ahiecho_Code = do_DSPEchoMulti32;
234 break;
236 // Should not happen!
237 default:
238 AHIFreeVec(es);
239 return FALSE;
242 // Structure filled, make it available to the mixing routine
244 audioctrl->ahiac_EffDSPEchoStruct = es;
246 return TRUE;
249 return FALSE;
253 void
254 free_DSPEcho ( struct AHIPrivAudioCtrl *audioctrl )
256 void *p = audioctrl->ahiac_EffDSPEchoStruct;
258 // Hide it from mixing routine before freeing it!
259 audioctrl->ahiac_EffDSPEchoStruct = NULL;
260 AHIFreeVec(p);
262 audioctrl->ahiac_EchoMasterVolume = 0x10000;
263 update_MasterVolume( audioctrl );
269 /******************************************************************************
270 ** DSPMASK ********************************************************************
271 ******************************************************************************/
273 static void
274 addchannel ( struct AHIChannelData **list, struct AHIChannelData *cd )
276 struct AHIChannelData *ptr;
278 if(*list == NULL)
280 *list = cd;
282 else
284 ptr = *list;
285 while(ptr->cd_Succ != NULL)
287 ptr = ptr->cd_Succ;
289 ptr->cd_Succ = cd;
292 cd->cd_Succ = NULL;
295 BOOL
296 update_DSPMask ( struct AHIEffDSPMask *mask,
297 struct AHIPrivAudioCtrl *audioctrl )
299 struct AHIChannelData *cd, *wet = NULL, *dry = NULL;
300 struct Library *AHIsubBase;
301 int i;
302 UBYTE *flag;
304 if(mask->ahiedm_Channels != audioctrl->ac.ahiac_Channels)
306 return FALSE;
309 cd = audioctrl->ahiac_ChannelDatas;
311 flag = mask->ahiedm_Mask;
313 AHIsubBase = audioctrl->ahiac_SubLib;
315 AHIsub_Disable(&audioctrl->ac);
317 for(i = 0; i < audioctrl->ac.ahiac_Channels; i++)
319 if(*flag == AHIEDM_WET)
321 addchannel(&wet, cd);
323 else
325 addchannel(&dry, cd);
328 flag++;
329 cd++;
332 audioctrl->ahiac_WetList = wet;
333 audioctrl->ahiac_DryList = dry;
335 AHIsub_Enable(&audioctrl->ac);
337 return TRUE;
341 void
342 clear_DSPMask ( struct AHIPrivAudioCtrl *audioctrl )
344 struct AHIChannelData *cd;
345 struct Library *AHIsubBase;
346 int i;
348 // Make all channels wet
350 cd = audioctrl->ahiac_ChannelDatas;
352 audioctrl->ahiac_WetList = cd;
353 audioctrl->ahiac_DryList = NULL;
355 AHIsubBase = audioctrl->ahiac_SubLib;
357 AHIsub_Disable(&audioctrl->ac);
359 for(i = 0; i < audioctrl->ac.ahiac_Channels - 1; i++)
361 // Set link to next channel
362 cd->cd_Succ = cd + 1;
363 cd++;
366 // Clear the last link;
367 cd->cd_Succ = NULL;
369 AHIsub_Enable(&audioctrl->ac);