Mercurial > mplayer.hg
changeset 14389:7c9df87a2694
unused parts removed
author | alex |
---|---|
date | Thu, 06 Jan 2005 11:01:28 +0000 |
parents | da2a938eb976 |
children | 8f6bd2869325 |
files | libao2/ao_plugin.c libao2/audio_plugin.h libao2/audio_plugin_internal.h libao2/eq.h libao2/filter.h libao2/fir.h libao2/firfilter.c libao2/pl_delay.c libao2/pl_eq.c libao2/pl_extrastereo.c libao2/pl_format.c libao2/pl_resample.c libao2/pl_surround.c libao2/pl_volnorm.c libao2/pl_volume.c libao2/remez.c libao2/remez.h |
diffstat | 17 files changed, 0 insertions(+), 3463 deletions(-) [+] |
line wrap: on
line diff
--- a/libao2/ao_plugin.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,289 +0,0 @@ -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "mp_msg.h" -#include "help_mp.h" -#include "libaf/af_format.h" -#include "audio_out.h" -#include "audio_out_internal.h" - -#include "audio_plugin.h" - -static ao_info_t info = -{ - "Plugin audio output", - "plugin", - "Anders", - "" -}; - -LIBAO_EXTERN(plugin) - -#define plugin(i) (ao_plugin_local_data.plugins[i]) -#define driver() (ao_plugin_local_data.driver) - -// local data -typedef struct ao_plugin_local_data_s -{ - void* buf; // Output data buffer - int len; // Amount of data in buffer - int channels; - int format; - int bpm; //bit of format - float bps; // Bytes per second out - ao_functions_t* driver; // Output driver - ao_plugin_functions_t** plugins; // List of used plugins - ao_plugin_functions_t* available_plugins[NPL]; // List of available plugins -} ao_plugin_local_data_t; - -static ao_plugin_local_data_t ao_plugin_local_data={NULL,0,0,0,0,0.0,NULL,NULL,AO_PLUGINS}; - -// global data -volatile ao_plugin_data_t ao_plugin_data; // Data used by the plugins -ao_plugin_cfg_t ao_plugin_cfg=CFG_DEFAULTS; // Set in cfg-mplayer.h - -// to set/get/query special features/parameters -static int control(int cmd,void *arg){ - switch(cmd){ - case AOCONTROL_SET_PLUGIN_DRIVER: - ao_plugin_local_data.driver=arg; - return CONTROL_OK; - case AOCONTROL_GET_VOLUME: - case AOCONTROL_SET_VOLUME: - { - int r=audio_plugin_volume.control(cmd,arg); - if(CONTROL_OK != r) - return driver()->control(cmd,arg); - else - return r; - } - default: - return driver()->control(cmd,arg); - } - return CONTROL_UNKNOWN; -} - -// Recursive function for adding plugins -// return 1 for success and 0 for error -int add_plugin(int i,char* cfg){ - int cnt=0; - // Find end of plugin name - while((cfg[cnt]!=',')&&(cfg[cnt]!='\0')&&(cnt<100)) cnt++; - if(cnt >= 100) - return 0; - - // Is this the last iteration or just another plugin - if(cfg[cnt]=='\0'){ - ao_plugin_local_data.plugins=malloc((i+2)*sizeof(ao_plugin_functions_t*)); - if(ao_plugin_local_data.plugins){ - ao_plugin_local_data.plugins[i+1]=NULL; - // Find the plugin matching the cfg string name - cnt=0; - while(ao_plugin_local_data.available_plugins[cnt] && cnt<20){ - if(0==strcmp(ao_plugin_local_data.available_plugins[cnt]->info->short_name,cfg)){ - ao_plugin_local_data.plugins[i]=ao_plugin_local_data.available_plugins[cnt]; - return 1; - } - cnt++; - } - mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_PLUGIN_InvalidPlugin,cfg); - return 0; - } - else - return 0; - } else { - cfg[cnt]='\0'; - if(add_plugin(i+1,&cfg[cnt+1])){ - cnt=0; - // Find the plugin matching the cfg string name - while(ao_plugin_local_data.available_plugins[cnt] && cnt < 20){ - if(0==strcmp(ao_plugin_local_data.available_plugins[cnt]->info->short_name,cfg)){ - ao_plugin_local_data.plugins[i]=ao_plugin_local_data.available_plugins[cnt]; - return 1; - } - cnt++; - } - mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_PLUGIN_InvalidPlugin,cfg); - return 0; - } - else - return 0; - } - return 0; // Will never happen... -} - -// open & setup audio device and plugins -// return: 1=success 0=fail -static int init(int rate,int channels,int format,int flags){ - int use_plugin[NPL]; - int x,npl,unused=0; - int ok=1; - char *config; - - // Create list of plugins from cfg option - int i=0; - if(ao_plugin_cfg.plugin_list){ - config = malloc(strlen(ao_plugin_cfg.plugin_list)+1); - if(!config) return 0; - if(!strcpy(config, ao_plugin_cfg.plugin_list) || !add_plugin(i,config)){ - free(config); - return 0; - } - free(config); - } - - /* Set input parameters and itterate through plugins each plugin - changes the parameters according to its output */ - - ao_plugin_local_data.format=format; - ao_plugin_local_data.channels=channels; - ao_plugin_local_data.bpm=af_fmt2bits(format); - - ao_plugin_data.rate=rate; - ao_plugin_data.channels=channels; - ao_plugin_data.format=format; - ao_plugin_data.sz_mult=1; - ao_plugin_data.sz_fix=0; - ao_plugin_data.delay_mult=1; - ao_plugin_data.delay_fix=0; - - for(i=0;i<NPL && plugin(i);i++){ - use_plugin[i]=plugin(i)->init(); - if(!use_plugin[i]) plugin(i)->uninit(); - } - npl=i; - for(i=0;i<npl && plugin(i);i++) - if(!use_plugin[i+unused]){ - unused++; - for(x=i;x<npl && plugin(x+1);x++) plugin(x)=plugin(x+1); - plugin(x)=NULL; - npl--; - i--; - } - i=npl; - - // Calculate bps - ao_plugin_local_data.bps=(float)(ao_plugin_data.rate * - ao_plugin_data.channels); - ao_plugin_local_data.bps*=af_fmt2bits(ao_plugin_data.format)/8; - - // This should never happen but check anyway - if(NULL==ao_plugin_local_data.driver) - return 0; - - ok = driver()->init(ao_plugin_data.rate, - ao_plugin_data.channels, - ao_plugin_data.format, - flags); - if(!ok) return 0; - - /* Now that the driver is initialized we can calculate and set the - input and output buffers for each plugin */ - ao_plugin_data.len=driver()->get_space(); - while((i>0) && ok) - ok=plugin(--i)->control(AOCONTROL_PLUGIN_SET_LEN,0); - - if(!ok) return 0; - - // Allocate output buffer - if(ao_plugin_local_data.buf) - free(ao_plugin_local_data.buf); - ao_plugin_local_data.buf=malloc(MAX_OUTBURST); - - if(!ao_plugin_local_data.buf) return 0; - - return 1; -} - -// close audio device -static void uninit(int immed){ - int i=0; - driver()->uninit(immed); - while(plugin(i)) - plugin(i++)->uninit(); - if(ao_plugin_local_data.plugins) - free(ao_plugin_local_data.plugins); - ao_plugin_local_data.plugins=NULL; - if(ao_plugin_local_data.buf) - free(ao_plugin_local_data.buf); - ao_plugin_local_data.buf=NULL; -} - -// stop playing and empty buffers (for seeking/pause) -static void reset(){ - int i=0; - driver()->reset(); - while(plugin(i)) - plugin(i++)->reset(); - ao_plugin_local_data.len=0; -} - -// stop playing, keep buffers (for pause) -static void audio_pause(){ - driver()->pause(); -} - -// resume playing, after audio_pause() -static void audio_resume(){ - driver()->resume(); -} - -// return: how many bytes can be played without blocking -static int get_space(){ -double sz; -int isz; - sz=(double)(driver()->get_space()); - if(sz+(double)ao_plugin_local_data.len > (double)MAX_OUTBURST) - sz=(double)MAX_OUTBURST-(double)ao_plugin_local_data.len; - sz*=ao_plugin_data.sz_mult; - sz+=ao_plugin_data.sz_fix; - isz=(int)(sz); - isz-=isz%(ao_plugin_local_data.channels*ao_plugin_local_data.bpm/8); - return isz; -} - -// plays 'len' bytes of 'data' -// return: number of bytes played -static int play(void* data,int len,int flags){ - int l,i=0; - // Limit length to avoid over flow in plugins - int tmp = get_space(); - int ret_len =(tmp<len)?tmp:len; - // keep all channels of each sample together - ret_len -= ret_len % (ao_plugin_local_data.channels*ao_plugin_local_data.bpm/8); - if(ret_len){ - // Filter data - ao_plugin_data.len=ret_len; - ao_plugin_data.data=data; - - while(plugin(i)) - plugin(i++)->play(); - // Copy data to output buffer - memcpy(ao_plugin_local_data.buf+ao_plugin_local_data.len, - ao_plugin_data.data,ao_plugin_data.len); - // Send data to output - l=driver()->play(ao_plugin_local_data.buf, - ao_plugin_data.len+ao_plugin_local_data.len,flags); - // Save away unsent data - ao_plugin_local_data.len=ao_plugin_data.len+ao_plugin_local_data.len-l; - memcpy(ao_plugin_local_data.buf,ao_plugin_local_data.buf+l, - ao_plugin_local_data.len); - } - return ret_len; -} - -// return: delay in seconds between first and last sample in buffer -static float get_delay(){ - float delay=driver()->get_delay(); - delay+=(float)ao_plugin_local_data.len/ao_plugin_local_data.bps; - delay*=ao_plugin_data.delay_mult; - delay+=ao_plugin_data.delay_fix; - return delay; -} - - - -
--- a/libao2/audio_plugin.h Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -#ifndef __audio_plugin_h__ -#define __audio_plugin_h__ - -// Functions supplied by plugins -typedef struct ao_plugin_functions_s -{ - ao_info_t *info; - int (*control)(int cmd, void *arg); - int (*init)(); - void (*uninit)(); - void (*reset)(); - int (*play)(); -} ao_plugin_functions_t; - -// Global data for all audio plugins -typedef struct ao_plugin_data_s -{ - void* data; /* current data block read only ok to change */ - int len; /* setup and current buffer length */ - int rate; /* setup data rate */ - int channels; /* setup number of channels */ - int format; /* setup format */ - double sz_mult; /* Buffer size multiplier */ - double sz_fix; /* Fix (as in static) extra buffer size */ - float delay_mult; /* Delay multiplier */ - float delay_fix; /* Fix delay */ -}ao_plugin_data_t; - -extern volatile ao_plugin_data_t ao_plugin_data; - -// Plugin confuguration data set by cmd-line parameters -typedef struct ao_plugin_cfg_s -{ - char* plugin_list; // List of used plugins read from cfg - int pl_format_type; // Output format - int pl_delay_len; // Number of samples to delay sound output - int pl_resample_fout; // Output frequency from resampling - int pl_volume_volume; // Initial volume setting - float pl_extrastereo_mul; // Stereo enhancer multiplier - int pl_volume_softclip; // Enable soft clipping -} ao_plugin_cfg_t; - -extern ao_plugin_cfg_t ao_plugin_cfg; - -// Configuration defaults -#define CFG_DEFAULTS { \ - NULL, \ - AF_FORMAT_S16_LE, \ - 0, \ - 48000, \ - 101, \ - 2.5, \ - 0 \ -}; - -// This block should not be available in the pl_xxxx files -// due to compilation issues -#ifndef PLUGIN -#define NPL 8+1 // Number of PLugins ( +1 list ends with NULL ) -// List of plugins -extern ao_plugin_functions_t audio_plugin_delay; -extern ao_plugin_functions_t audio_plugin_format; -extern ao_plugin_functions_t audio_plugin_surround; -extern ao_plugin_functions_t audio_plugin_resample; -extern ao_plugin_functions_t audio_plugin_volume; -extern ao_plugin_functions_t audio_plugin_extrastereo; -extern ao_plugin_functions_t audio_plugin_volnorm; -extern ao_plugin_functions_t audio_plugin_eq; - -#define AO_PLUGINS { \ - &audio_plugin_delay, \ - &audio_plugin_format, \ - &audio_plugin_surround, \ - &audio_plugin_resample, \ - &audio_plugin_volume, \ - &audio_plugin_extrastereo, \ - &audio_plugin_volnorm, \ - &audio_plugin_eq, \ - NULL \ -} -#endif /* PLUGIN */ - - -// Control parameters used by the plugins -#define AOCONTROL_PLUGIN_SET_LEN 1 // All plugins must respond to this parameter -#define AOCONTROL_PLUGIN_ES_SET 4 // set extra stereo coefficient -#define AOCONTROL_PLUGIN_ES_GET 5 // get extra stereo coefficient - -#endif -
--- a/libao2/audio_plugin_internal.h Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -// prototypes: -static int control(int cmd, void *arg); -static int init(); -static void uninit(); -static void reset(); -static int play(); - -#define LIBAO_PLUGIN_EXTERN(x) ao_plugin_functions_t audio_plugin_##x =\ -{\ - &info,\ - control,\ - init,\ - uninit,\ - reset,\ - play,\ -};
--- a/libao2/eq.h Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/*============================================================================= -// -// This software has been released under the terms of the GNU Public -// license. See http://www.gnu.org/copyleft/gpl.html for details. -// -// Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au -// -//============================================================================= -*/ - -/* Equalizer plugin header file defines struct used for setting or - getting the gain of a specific channel and frequency */ - -typedef struct equalizer_s -{ - float gain; // Gain in dB -15 - 15 - int channel; // Channel number 0 - 5 - int band; // Frequency band 0 - 9 -}equalizer_t; - -/* The different frequency bands are: -nr. center frequency -0 31.25 Hz -1 62.50 Hz -2 125.0 Hz -3 250.0 Hz -4 500.0 Hz -5 1.000 kHz -6 2.000 kHz -7 4.000 kHz -8 8.000 kHz -9 16.00 kHz -*/ - -#define AOCONTROL_PLUGIN_EQ_SET_GAIN 2 // Use this to set the gain -#define AOCONTROL_PLUGIN_EQ_GET_GAIN 3 // Use this to get the gain
--- a/libao2/filter.h Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,341 +0,0 @@ -/*============================================================================= -// -// This software has been released under the terms of the GNU Public -// license. See http://www.gnu.org/copyleft/gpl.html for details. -// -// Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au -// -//============================================================================= -*/ - -/* Polyphase filters. Designed using window method and kaiser window - with beta=10. */ - -#define W4 { \ -0, 36, 32767, -35, 0, 113, 32756, -103, \ -0, 193, 32733, -167, 0, 278, 32699, -227, \ -0, 367, 32654, -282, -1, 461, 32597, -335, \ --1, 560, 32530, -383, -1, 664, 32451, -429, \ --1, 772, 32361, -470, -2, 886, 32260, -509, \ --2, 1004, 32148, -544, -2, 1128, 32026, -577, \ --3, 1257, 31892, -606, -4, 1392, 31749, -633, \ --4, 1532, 31594, -657, -5, 1677, 31430, -678, \ --6, 1828, 31255, -697, -7, 1985, 31070, -713, \ --8, 2147, 30876, -727, -9, 2315, 30671, -739, \ --10, 2489, 30457, -749, -11, 2668, 30234, -756, \ --13, 2854, 30002, -762, -14, 3045, 29761, -766, \ --16, 3243, 29511, -769, -18, 3446, 29252, -769, \ --20, 3656, 28985, -769, -22, 3871, 28710, -766, \ --25, 4093, 28427, -763, -27, 4320, 28137, -758, \ --30, 4553, 27839, -752, -33, 4793, 27534, -745, \ --36, 5038, 27222, -737, -39, 5290, 26904, -727, \ --43, 5547, 26579, -717, -47, 5811, 26248, -707, \ --51, 6080, 25911, -695, -55, 6355, 25569, -683, \ --60, 6636, 25221, -670, -65, 6922, 24868, -657, \ --70, 7214, 24511, -643, -76, 7512, 24149, -628, \ --81, 7815, 23782, -614, -87, 8124, 23412, -599, \ --94, 8437, 23038, -583, -101, 8757, 22661, -568, \ --108, 9081, 22281, -552, -115, 9410, 21898, -537, \ --123, 9744, 21513, -521, -131, 10082, 21125, -505, \ --139, 10425, 20735, -489, -148, 10773, 20344, -473, \ --157, 11125, 19951, -457, -166, 11481, 19557, -441, \ --176, 11841, 19162, -426, -186, 12205, 18767, -410, \ --197, 12572, 18372, -395, -208, 12942, 17976, -380, \ --219, 13316, 17581, -365, -231, 13693, 17186, -350, \ --243, 14073, 16791, -336, -255, 14455, 16398, -321, \ --268, 14840, 16006, -307, -281, 15227, 15616, -294, \ --294, 15616, 15227, -281, -307, 16006, 14840, -268, \ --321, 16398, 14455, -255, -336, 16791, 14073, -243, \ --350, 17186, 13693, -231, -365, 17581, 13316, -219, \ --380, 17976, 12942, -208, -395, 18372, 12572, -197, \ --410, 18767, 12205, -186, -426, 19162, 11841, -176, \ --441, 19557, 11481, -166, -457, 19951, 11125, -157, \ --473, 20344, 10773, -148, -489, 20735, 10425, -139, \ --505, 21125, 10082, -131, -521, 21513, 9744, -123, \ --537, 21898, 9410, -115, -552, 22281, 9081, -108, \ --568, 22661, 8757, -101, -583, 23038, 8437, -94, \ --599, 23412, 8124, -87, -614, 23782, 7815, -81, \ --628, 24149, 7512, -76, -643, 24511, 7214, -70, \ --657, 24868, 6922, -65, -670, 25221, 6636, -60, \ --683, 25569, 6355, -55, -695, 25911, 6080, -51, \ --707, 26248, 5811, -47, -717, 26579, 5547, -43, \ --727, 26904, 5290, -39, -737, 27222, 5038, -36, \ --745, 27534, 4793, -33, -752, 27839, 4553, -30, \ --758, 28137, 4320, -27, -763, 28427, 4093, -25, \ --766, 28710, 3871, -22, -769, 28985, 3656, -20, \ --769, 29252, 3446, -18, -769, 29511, 3243, -16, \ --766, 29761, 3045, -14, -762, 30002, 2854, -13, \ --756, 30234, 2668, -11, -749, 30457, 2489, -10, \ --739, 30671, 2315, -9, -727, 30876, 2147, -8, \ --713, 31070, 1985, -7, -697, 31255, 1828, -6, \ --678, 31430, 1677, -5, -657, 31594, 1532, -4, \ --633, 31749, 1392, -4, -606, 31892, 1257, -3, \ --577, 32026, 1128, -2, -544, 32148, 1004, -2, \ --509, 32260, 886, -2, -470, 32361, 772, -1, \ --429, 32451, 664, -1, -383, 32530, 560, -1, \ --335, 32597, 461, -1, -282, 32654, 367, 0, \ --227, 32699, 278, 0, -167, 32733, 193, 0, \ --103, 32756, 113, 0, -35, 32767, 36, 0, \ -} - -#define W8 { \ -0, 2, -18, 95, 32767, -94, 18, -2, \ -0, 6, -55, 289, 32759, -279, 53, -5, \ -0, 9, -93, 488, 32744, -458, 87, -8, \ -0, 13, -132, 692, 32720, -633, 120, -11, \ -0, 18, -173, 900, 32689, -804, 151, -14, \ -0, 22, -214, 1113, 32651, -969, 182, -17, \ -0, 27, -256, 1331, 32604, -1130, 212, -20, \ -0, 31, -299, 1553, 32550, -1286, 241, -22, \ -0, 36, -343, 1780, 32488, -1437, 268, -25, \ -0, 41, -389, 2011, 32419, -1583, 295, -27, \ --1, 47, -435, 2247, 32342, -1724, 320, -29, \ --1, 52, -482, 2488, 32257, -1861, 345, -31, \ --1, 58, -530, 2733, 32165, -1993, 368, -32, \ --1, 64, -579, 2982, 32066, -2121, 391, -34, \ --1, 70, -629, 3236, 31959, -2243, 412, -36, \ --1, 76, -679, 3494, 31844, -2361, 433, -37, \ --1, 82, -731, 3756, 31723, -2475, 452, -38, \ --1, 89, -783, 4022, 31594, -2583, 471, -40, \ --2, 96, -837, 4293, 31458, -2688, 488, -41, \ --2, 102, -891, 4567, 31315, -2787, 505, -42, \ --2, 110, -946, 4846, 31164, -2883, 521, -42, \ --2, 117, -1001, 5128, 31007, -2973, 535, -43, \ --2, 124, -1057, 5414, 30843, -3060, 549, -44, \ --3, 132, -1114, 5704, 30672, -3142, 562, -44, \ --3, 140, -1172, 5998, 30495, -3219, 574, -45, \ --3, 148, -1230, 6295, 30311, -3292, 585, -45, \ --3, 156, -1289, 6596, 30120, -3362, 596, -46, \ --4, 164, -1349, 6900, 29923, -3426, 605, -46, \ --4, 173, -1408, 7208, 29719, -3487, 614, -46, \ --4, 181, -1469, 7519, 29509, -3544, 621, -46, \ --4, 190, -1530, 7832, 29294, -3597, 628, -46, \ --5, 199, -1591, 8149, 29072, -3645, 635, -46, \ --5, 208, -1652, 8469, 28844, -3690, 640, -46, \ --6, 217, -1714, 8792, 28610, -3731, 645, -46, \ --6, 227, -1777, 9118, 28371, -3768, 649, -45, \ --6, 236, -1839, 9446, 28126, -3801, 652, -45, \ --7, 246, -1902, 9776, 27875, -3831, 655, -45, \ --7, 255, -1964, 10109, 27620, -3857, 657, -44, \ --8, 265, -2027, 10445, 27359, -3880, 658, -44, \ --8, 275, -2090, 10782, 27092, -3899, 659, -43, \ --9, 285, -2153, 11121, 26821, -3915, 659, -43, \ --9, 295, -2216, 11463, 26546, -3927, 658, -42, \ --10, 306, -2278, 11806, 26265, -3936, 657, -42, \ --10, 316, -2341, 12151, 25980, -3942, 655, -41, \ --11, 326, -2403, 12497, 25690, -3945, 653, -40, \ --11, 337, -2465, 12845, 25396, -3945, 650, -40, \ --12, 347, -2526, 13194, 25098, -3941, 647, -39, \ --12, 358, -2588, 13544, 24796, -3935, 643, -38, \ --13, 368, -2648, 13896, 24490, -3926, 639, -38, \ --14, 379, -2708, 14248, 24181, -3914, 634, -37, \ --14, 389, -2768, 14601, 23867, -3900, 629, -36, \ --15, 400, -2827, 14954, 23551, -3883, 623, -35, \ --16, 410, -2885, 15308, 23231, -3863, 617, -34, \ --16, 421, -2943, 15662, 22908, -3841, 611, -34, \ --17, 431, -2999, 16016, 22581, -3817, 604, -33, \ --18, 442, -3055, 16371, 22252, -3790, 597, -32, \ --19, 452, -3109, 16725, 21921, -3761, 590, -31, \ --19, 462, -3163, 17079, 21587, -3730, 582, -30, \ --20, 472, -3215, 17432, 21250, -3697, 574, -29, \ --21, 483, -3266, 17785, 20911, -3662, 566, -28, \ --22, 492, -3316, 18138, 20570, -3624, 558, -28, \ --23, 502, -3365, 18489, 20227, -3585, 549, -27, \ --23, 512, -3412, 18839, 19883, -3545, 540, -26, \ --24, 522, -3458, 19188, 19536, -3502, 531, -25, \ --25, 531, -3502, 19536, 19188, -3458, 522, -24, \ --26, 540, -3545, 19883, 18839, -3412, 512, -23, \ --27, 549, -3585, 20227, 18489, -3365, 502, -23, \ --28, 558, -3624, 20570, 18138, -3316, 492, -22, \ --28, 566, -3662, 20911, 17785, -3266, 483, -21, \ --29, 574, -3697, 21250, 17432, -3215, 472, -20, \ --30, 582, -3730, 21587, 17079, -3163, 462, -19, \ --31, 590, -3761, 21921, 16725, -3109, 452, -19, \ --32, 597, -3790, 22252, 16371, -3055, 442, -18, \ --33, 604, -3817, 22581, 16016, -2999, 431, -17, \ --34, 611, -3841, 22908, 15662, -2943, 421, -16, \ --34, 617, -3863, 23231, 15308, -2885, 410, -16, \ --35, 623, -3883, 23551, 14954, -2827, 400, -15, \ --36, 629, -3900, 23867, 14601, -2768, 389, -14, \ --37, 634, -3914, 24181, 14248, -2708, 379, -14, \ --38, 639, -3926, 24490, 13896, -2648, 368, -13, \ --38, 643, -3935, 24796, 13544, -2588, 358, -12, \ --39, 647, -3941, 25098, 13194, -2526, 347, -12, \ --40, 650, -3945, 25396, 12845, -2465, 337, -11, \ --40, 653, -3945, 25690, 12497, -2403, 326, -11, \ --41, 655, -3942, 25980, 12151, -2341, 316, -10, \ --42, 657, -3936, 26265, 11806, -2278, 306, -10, \ --42, 658, -3927, 26546, 11463, -2216, 295, -9, \ --43, 659, -3915, 26821, 11121, -2153, 285, -9, \ --43, 659, -3899, 27092, 10782, -2090, 275, -8, \ --44, 658, -3880, 27359, 10445, -2027, 265, -8, \ --44, 657, -3857, 27620, 10109, -1964, 255, -7, \ --45, 655, -3831, 27875, 9776, -1902, 246, -7, \ --45, 652, -3801, 28126, 9446, -1839, 236, -6, \ --45, 649, -3768, 28371, 9118, -1777, 227, -6, \ --46, 645, -3731, 28610, 8792, -1714, 217, -6, \ --46, 640, -3690, 28844, 8469, -1652, 208, -5, \ --46, 635, -3645, 29072, 8149, -1591, 199, -5, \ --46, 628, -3597, 29294, 7832, -1530, 190, -4, \ --46, 621, -3544, 29509, 7519, -1469, 181, -4, \ --46, 614, -3487, 29719, 7208, -1408, 173, -4, \ --46, 605, -3426, 29923, 6900, -1349, 164, -4, \ --46, 596, -3362, 30120, 6596, -1289, 156, -3, \ --45, 585, -3292, 30311, 6295, -1230, 148, -3, \ --45, 574, -3219, 30495, 5998, -1172, 140, -3, \ --44, 562, -3142, 30672, 5704, -1114, 132, -3, \ --44, 549, -3060, 30843, 5414, -1057, 124, -2, \ --43, 535, -2973, 31007, 5128, -1001, 117, -2, \ --42, 521, -2883, 31164, 4846, -946, 110, -2, \ --42, 505, -2787, 31315, 4567, -891, 102, -2, \ --41, 488, -2688, 31458, 4293, -837, 96, -2, \ --40, 471, -2583, 31594, 4022, -783, 89, -1, \ --38, 452, -2475, 31723, 3756, -731, 82, -1, \ --37, 433, -2361, 31844, 3494, -679, 76, -1, \ --36, 412, -2243, 31959, 3236, -629, 70, -1, \ --34, 391, -2121, 32066, 2982, -579, 64, -1, \ --32, 368, -1993, 32165, 2733, -530, 58, -1, \ --31, 345, -1861, 32257, 2488, -482, 52, -1, \ --29, 320, -1724, 32342, 2247, -435, 47, -1, \ --27, 295, -1583, 32419, 2011, -389, 41, 0, \ --25, 268, -1437, 32488, 1780, -343, 36, 0, \ --22, 241, -1286, 32550, 1553, -299, 31, 0, \ --20, 212, -1130, 32604, 1331, -256, 27, 0, \ --17, 182, -969, 32651, 1113, -214, 22, 0, \ --14, 151, -804, 32689, 900, -173, 18, 0, \ --11, 120, -633, 32720, 692, -132, 13, 0, \ --8, 87, -458, 32744, 488, -93, 9, 0, \ --5, 53, -279, 32759, 289, -55, 6, 0, \ --2, 18, -94, 32767, 95, -18, 2, 0, \ -} - -#define W16 {\ -0, 0, -1, 3, -9, 21, -47, 119,32764, -118, 47, -21, 9, -3, 1, 0, \ -0, 0, -3, 10, -27, 65, -143, 361,32757, -352, 141, -63, 27, -10, 3, 0, \ -0, 1, -5, 17, -46, 108, -240, 607,32743, -581, 233, -105, 44, -16, 4, -1, \ -0, 1, -6, 23, -65, 153, -338, 857,32722, -805, 324, -146, 61, -22, 6, -1, \ -0, 1, -8, 30, -84, 197, -438, 1112,32695, -1025, 413, -187, 78, -28, 8, -1, \ -0, 2, -10, 37, -103, 243, -538, 1370,32661, -1241, 502, -226, 95, -34, 9, -2, \ -0, 2, -12, 44, -122, 288, -639, 1632,32620, -1452, 588, -265, 111, -40, 11, -2, \ -0, 3, -14, 52, -142, 334, -740, 1898,32572, -1659, 674, -304, 127, -45, 12, -2, \ -0, 3, -17, 59, -162, 381, -843, 2168,32517, -1861, 758, -342, 143, -51, 14, -2, \ -0, 3, -19, 66, -182, 427, -947, 2442,32455, -2058, 840, -379, 158, -56, 15, -2, \ -0, 4, -21, 74, -202, 474, -1051, 2720,32387, -2251, 921, -415, 173, -61, 16, -3, \ -0, 4, -23, 81, -222, 521, -1156, 3001,32312, -2440, 1000, -451, 188, -66, 18, -3, \ -0, 5, -25, 89, -243, 569, -1261, 3285,32230, -2623, 1077, -486, 202, -71, 19, -3, \ -0, 5, -28, 97, -263, 617, -1367, 3574,32142, -2802, 1153, -520, 216, -76, 20, -3, \ -0, 5, -30, 104, -284, 665, -1474, 3865,32047, -2976, 1228, -553, 230, -81, 21, -3, \ -0, 6, -32, 112, -305, 713, -1581, 4160,31945, -3145, 1300, -586, 243, -85, 22, -4, \ -0, 6, -34, 120, -326, 761, -1688, 4458,31837, -3310, 1371, -617, 256, -90, 24, -4, \ -0, 7, -37, 128, -347, 810, -1796, 4760,31722, -3470, 1440, -648, 269, -94, 25, -4, \ -0, 7, -39, 136, -368, 858, -1903, 5064,31601, -3625, 1507, -679, 281, -98, 26, -4, \ -0, 8, -42, 144, -389, 907, -2011, 5371,31474, -3775, 1573, -708, 293, -102, 27, -4, \ --1, 8, -44, 152, -410, 955, -2119, 5682,31340, -3921, 1637, -737, 305, -106, 27, -4, \ --1, 9, -47, 160, -431, 1004, -2228, 5995,31200, -4061, 1699, -764, 316, -109, 28, -4, \ --1, 9, -49, 168, -453, 1052, -2336, 6311,31053, -4197, 1759, -791, 326, -113, 29, -4, \ --1, 10, -52, 176, -474, 1101, -2444, 6629,30901, -4329, 1817, -817, 337, -116, 30, -4, \ --1, 10, -54, 185, -495, 1149, -2552, 6951,30742, -4455, 1873, -842, 347, -119, 31, -5, \ --1, 11, -57, 193, -516, 1197, -2659, 7274,30577, -4576, 1928, -866, 356, -123, 31, -5, \ --1, 12, -59, 201, -537, 1245, -2767, 7600,30406, -4693, 1980, -890, 366, -125, 32, -5, \ --1, 12, -62, 209, -558, 1293, -2874, 7928,30229, -4805, 2031, -912, 374, -128, 33, -5, \ --1, 13, -64, 217, -579, 1341, -2980, 8259,30047, -4912, 2080, -934, 383, -131, 33, -5, \ --1, 13, -67, 225, -600, 1388, -3086, 8591,29858, -5015, 2126, -955, 391, -133, 34, -5, \ --1, 14, -69, 234, -621, 1435, -3192, 8925,29664, -5113, 2171, -974, 399, -136, 34, -5, \ --1, 14, -72, 242, -642, 1482, -3297, 9261,29464, -5206, 2214, -993, 406, -138, 35, -5, \ --1, 15, -75, 250, -662, 1528, -3401, 9599,29259, -5294, 2255, -1012, 413, -140, 35, -5, \ --1, 15, -77, 258, -683, 1574, -3504, 9939,29048, -5378, 2294, -1029, 419, -142, 36, -5, \ --1, 16, -80, 266, -703, 1619, -3607, 10280,28831, -5457, 2332, -1045, 426, -144, 36, -5, \ --1, 17, -82, 274, -723, 1664, -3708, 10622,28610, -5531, 2367, -1060, 431, -146, 36, -5, \ --1, 17, -85, 282, -743, 1709, -3808, 10966,28383, -5601, 2400, -1075, 437, -147, 37, -5, \ --1, 18, -87, 290, -762, 1753, -3908, 11311,28151, -5666, 2431, -1089, 442, -149, 37, -5, \ --1, 18, -90, 297, -782, 1796, -4006, 11657,27914, -5727, 2461, -1101, 447, -150, 37, -5, \ --2, 19, -93, 305, -801, 1839, -4103, 12004,27672, -5783, 2488, -1113, 451, -151, 37, -5, \ --2, 20, -95, 313, -820, 1881, -4198, 12352,27425, -5835, 2514, -1124, 455, -152, 37, -5, \ --2, 20, -98, 320, -838, 1922, -4293, 12701,27173, -5882, 2538, -1134, 458, -153, 37, -5, \ --2, 21, -100, 328, -857, 1963, -4385, 13050,26917, -5925, 2559, -1144, 462, -154, 37, -5, \ --2, 21, -103, 335, -875, 2003, -4476, 13399,26656, -5964, 2579, -1152, 465, -155, 37, -5, \ --2, 22, -105, 342, -892, 2042, -4566, 13749,26390, -5998, 2597, -1160, 467, -155, 38, -5, \ --2, 23, -107, 349, -910, 2080, -4654, 14100,26121, -6028, 2613, -1166, 469, -156, 37, -5, \ --2, 23, -110, 356, -927, 2117, -4740, 14450,25847, -6054, 2628, -1172, 471, -156, 37, -5, \ --2, 24, -112, 363, -943, 2154, -4824, 14801,25568, -6075, 2640, -1177, 473, -156, 37, -5, \ --2, 24, -114, 370, -959, 2189, -4906, 15151,25286, -6093, 2651, -1182, 474, -156, 37, -5, \ --2, 25, -117, 377, -975, 2224, -4986, 15501,25000, -6106, 2659, -1185, 474, -156, 37, -5, \ --2, 26, -119, 383, -991, 2257, -5064, 15851,24710, -6115, 2666, -1187, 475, -156, 37, -5, \ --2, 26, -121, 389, -1005, 2290, -5140, 16200,24416, -6121, 2672, -1189, 475, -156, 37, -4, \ --3, 27, -123, 395, -1020, 2321, -5214, 16549,24118, -6122, 2675, -1190, 475, -155, 37, -4, \ --3, 27, -125, 401, -1034, 2352, -5285, 16897,23817, -6120, 2677, -1190, 474, -155, 36, -4, \ --3, 28, -128, 407, -1047, 2381, -5354, 17244,23513, -6114, 2677, -1190, 474, -154, 36, -4, \ --3, 28, -130, 413, -1060, 2409, -5421, 17590,23205, -6104, 2675, -1188, 472, -154, 36, -4, \ --3, 29, -132, 418, -1073, 2435, -5485, 17935,22895, -6090, 2672, -1186, 471, -153, 35, -4, \ --3, 29, -133, 423, -1085, 2461, -5546, 18279,22581, -6073, 2666, -1183, 469, -152, 35, -4, \ --3, 30, -135, 428, -1096, 2485, -5605, 18621,22264, -6052, 2660, -1180, 467, -151, 35, -4, \ --3, 31, -137, 433, -1107, 2508, -5660, 18962,21945, -6027, 2651, -1176, 465, -150, 34, -4, \ --3, 31, -139, 437, -1117, 2530, -5713, 19301,21622, -5999, 2641, -1171, 463, -149, 34, -4, \ --3, 31, -140, 442, -1126, 2550, -5764, 19639,21297, -5968, 2630, -1165, 460, -148, 34, -4, \ --3, 32, -142, 446, -1135, 2569, -5811, 19975,20970, -5934, 2617, -1159, 457, -146, 33, -4, \ --4, 32, -144, 450, -1144, 2586, -5855, 20309,20641, -5896, 2602, -1151, 453, -145, 33, -4, \ --4, 33, -145, 453, -1151, 2602, -5896, 20641,20309, -5855, 2586, -1144, 450, -144, 32, -4, \ --4, 33, -146, 457, -1159, 2617, -5934, 20970,19975, -5811, 2569, -1135, 446, -142, 32, -3, \ --4, 34, -148, 460, -1165, 2630, -5968, 21297,19639, -5764, 2550, -1126, 442, -140, 31, -3, \ --4, 34, -149, 463, -1171, 2641, -5999, 21622,19301, -5713, 2530, -1117, 437, -139, 31, -3, \ --4, 34, -150, 465, -1176, 2651, -6027, 21945,18962, -5660, 2508, -1107, 433, -137, 31, -3, \ --4, 35, -151, 467, -1180, 2660, -6052, 22264,18621, -5605, 2485, -1096, 428, -135, 30, -3, \ --4, 35, -152, 469, -1183, 2666, -6073, 22581,18279, -5546, 2461, -1085, 423, -133, 29, -3, \ --4, 35, -153, 471, -1186, 2672, -6090, 22895,17935, -5485, 2435, -1073, 418, -132, 29, -3, \ --4, 36, -154, 472, -1188, 2675, -6104, 23205,17590, -5421, 2409, -1060, 413, -130, 28, -3, \ --4, 36, -154, 474, -1190, 2677, -6114, 23513,17244, -5354, 2381, -1047, 407, -128, 28, -3, \ --4, 36, -155, 474, -1190, 2677, -6120, 23817,16897, -5285, 2352, -1034, 401, -125, 27, -3, \ --4, 37, -155, 475, -1190, 2675, -6122, 24118,16549, -5214, 2321, -1020, 395, -123, 27, -3, \ --4, 37, -156, 475, -1189, 2672, -6121, 24416,16200, -5140, 2290, -1005, 389, -121, 26, -2, \ --5, 37, -156, 475, -1187, 2666, -6115, 24710,15851, -5064, 2257, -991, 383, -119, 26, -2, \ --5, 37, -156, 474, -1185, 2659, -6106, 25000,15501, -4986, 2224, -975, 377, -117, 25, -2, \ --5, 37, -156, 474, -1182, 2651, -6093, 25286,15151, -4906, 2189, -959, 370, -114, 24, -2, \ --5, 37, -156, 473, -1177, 2640, -6075, 25568,14801, -4824, 2154, -943, 363, -112, 24, -2, \ --5, 37, -156, 471, -1172, 2628, -6054, 25847,14450, -4740, 2117, -927, 356, -110, 23, -2, \ --5, 37, -156, 469, -1166, 2613, -6028, 26121,14100, -4654, 2080, -910, 349, -107, 23, -2, \ --5, 38, -155, 467, -1160, 2597, -5998, 26390,13749, -4566, 2042, -892, 342, -105, 22, -2, \ --5, 37, -155, 465, -1152, 2579, -5964, 26656,13399, -4476, 2003, -875, 335, -103, 21, -2, \ --5, 37, -154, 462, -1144, 2559, -5925, 26917,13050, -4385, 1963, -857, 328, -100, 21, -2, \ --5, 37, -153, 458, -1134, 2538, -5882, 27173,12701, -4293, 1922, -838, 320, -98, 20, -2, \ --5, 37, -152, 455, -1124, 2514, -5835, 27425,12352, -4198, 1881, -820, 313, -95, 20, -2, \ --5, 37, -151, 451, -1113, 2488, -5783, 27672,12004, -4103, 1839, -801, 305, -93, 19, -2, \ --5, 37, -150, 447, -1101, 2461, -5727, 27914,11657, -4006, 1796, -782, 297, -90, 18, -1, \ --5, 37, -149, 442, -1089, 2431, -5666, 28151,11311, -3908, 1753, -762, 290, -87, 18, -1, \ --5, 37, -147, 437, -1075, 2400, -5601, 28383,10966, -3808, 1709, -743, 282, -85, 17, -1, \ --5, 36, -146, 431, -1060, 2367, -5531, 28610,10622, -3708, 1664, -723, 274, -82, 17, -1, \ --5, 36, -144, 426, -1045, 2332, -5457, 28831,10280, -3607, 1619, -703, 266, -80, 16, -1, \ --5, 36, -142, 419, -1029, 2294, -5378, 29048,9939, -3504, 1574, -683, 258, -77, 15, -1, \ --5, 35, -140, 413, -1012, 2255, -5294, 29259,9599, -3401, 1528, -662, 250, -75, 15, -1, \ --5, 35, -138, 406, -993, 2214, -5206, 29464,9261, -3297, 1482, -642, 242, -72, 14, -1, \ --5, 34, -136, 399, -974, 2171, -5113, 29664,8925, -3192, 1435, -621, 234, -69, 14, -1, \ --5, 34, -133, 391, -955, 2126, -5015, 29858,8591, -3086, 1388, -600, 225, -67, 13, -1, \ --5, 33, -131, 383, -934, 2080, -4912, 30047,8259, -2980, 1341, -579, 217, -64, 13, -1, \ --5, 33, -128, 374, -912, 2031, -4805, 30229,7928, -2874, 1293, -558, 209, -62, 12, -1, \ --5, 32, -125, 366, -890, 1980, -4693, 30406,7600, -2767, 1245, -537, 201, -59, 12, -1, \ --5, 31, -123, 356, -866, 1928, -4576, 30577,7274, -2659, 1197, -516, 193, -57, 11, -1, \ --5, 31, -119, 347, -842, 1873, -4455, 30742,6951, -2552, 1149, -495, 185, -54, 10, -1, \ --4, 30, -116, 337, -817, 1817, -4329, 30901,6629, -2444, 1101, -474, 176, -52, 10, -1, \ --4, 29, -113, 326, -791, 1759, -4197, 31053,6311, -2336, 1052, -453, 168, -49, 9, -1, \ --4, 28, -109, 316, -764, 1699, -4061, 31200,5995, -2228, 1004, -431, 160, -47, 9, -1, \ --4, 27, -106, 305, -737, 1637, -3921, 31340,5682, -2119, 955, -410, 152, -44, 8, -1, \ --4, 27, -102, 293, -708, 1573, -3775, 31474,5371, -2011, 907, -389, 144, -42, 8, 0, \ --4, 26, -98, 281, -679, 1507, -3625, 31601,5064, -1903, 858, -368, 136, -39, 7, 0, \ --4, 25, -94, 269, -648, 1440, -3470, 31722,4760, -1796, 810, -347, 128, -37, 7, 0, \ --4, 24, -90, 256, -617, 1371, -3310, 31837,4458, -1688, 761, -326, 120, -34, 6, 0, \ --4, 22, -85, 243, -586, 1300, -3145, 31945,4160, -1581, 713, -305, 112, -32, 6, 0, \ --3, 21, -81, 230, -553, 1228, -2976, 32047,3865, -1474, 665, -284, 104, -30, 5, 0, \ --3, 20, -76, 216, -520, 1153, -2802, 32142,3574, -1367, 617, -263, 97, -28, 5, 0, \ --3, 19, -71, 202, -486, 1077, -2623, 32230,3285, -1261, 569, -243, 89, -25, 5, 0, \ --3, 18, -66, 188, -451, 1000, -2440, 32312,3001, -1156, 521, -222, 81, -23, 4, 0, \ --3, 16, -61, 173, -415, 921, -2251, 32387,2720, -1051, 474, -202, 74, -21, 4, 0, \ --2, 15, -56, 158, -379, 840, -2058, 32455,2442, -947, 427, -182, 66, -19, 3, 0, \ --2, 14, -51, 143, -342, 758, -1861, 32517,2168, -843, 381, -162, 59, -17, 3, 0, \ --2, 12, -45, 127, -304, 674, -1659, 32572,1898, -740, 334, -142, 52, -14, 3, 0, \ --2, 11, -40, 111, -265, 588, -1452, 32620,1632, -639, 288, -122, 44, -12, 2, 0, \ --2, 9, -34, 95, -226, 502, -1241, 32661,1370, -538, 243, -103, 37, -10, 2, 0, \ --1, 8, -28, 78, -187, 413, -1025, 32695,1112, -438, 197, -84, 30, -8, 1, 0, \ --1, 6, -22, 61, -146, 324, -805, 32722,857, -338, 153, -65, 23, -6, 1, 0, \ --1, 4, -16, 44, -105, 233, -581, 32743,607, -240, 108, -46, 17, -5, 1, 0, \ -0, 3, -10, 27, -63, 141, -352, 32757,361, -143, 65, -27, 10, -3, 0, 0, \ -0, 1, -3, 9, -21, 47, -118, 32764,119, -47, 21, -9, 3, -1, 0, 0, \ -}
--- a/libao2/fir.h Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/*============================================================================= -// -// This software has been released under the terms of the GNU Public -// license. See http://www.gnu.org/copyleft/gpl.html for details. -// -// Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au -// -//============================================================================= -*/ - -#ifndef __FIR_H__ -#define __FIR_H__ - -/* Fixpoint 16 bit FIR filter. The filter is implemented both in C and -MMX assembly. The filter consists of the two inline functions updateq -and firn, update q is used for adding new data to the circular buffer -used by the filter firn. Limitations: max length of n = 16*4 and n -must be multiple of 4 (pad fiter with zeros for other lengths). -Sometimes it works with filters longer than 4*16 (the problem is -overshoot and the acumulated energy in the filter taps). */ - -#ifdef HAVE_MMX -inline int32_t firn(int16_t* x, int16_t* w, int16_t n) -{ - register int32_t y; // Output - // Prologue - asm volatile(" pxor %mm1, %mm1;\n" ); // Clear buffer yt - // Main loop - while((n-=4)>=0){ - asm volatile( - " movq (%1), %%mm0;\n" // Load x(n:n+4) - " pmaddwd (%0), %%mm0;\n" // yt(n:n+1)=sum(x(n:n+4).*w(n:n+4)) - " psrld $16, %%mm0;\n" // yt(n:n+1)=yt(n:n+1)>>16 - " paddd %%mm0, %%mm1;\n" // yt(n:n+1)=yt(n-2:n-1)+yt(n:n+1) - :: "r" (w), "r" (x)); - w+=4; x+=4; - } - // Epilogue - asm volatile( - " movq %%mm1, %%mm0;\n" - " punpckhdq %%mm1, %%mm0;\n" - " paddd %%mm0, %%mm1;\n" //yt(n)=yt(n)+yt(n+1) - " movd %%mm1, %0 ;\n" //y=yt - " emms ;\n" - : "=&r" (y)); - return y; -} - -#else /* HAVE_MMX */ - -// Same thing as above but in C -inline int32_t firn(int16_t* x, int16_t* w, int16_t n) -{ - register int32_t y=0; - while((n-=4) >=0) - y+=w[n]*x[n]+w[n+1]*x[n+1]+w[n+2]*x[n+2]+w[n+3]*x[n+3] >> 16; - return y; -} - -#endif /* HAVE_MMX */ - -/* Add new data to circular queue designed to be used with a FIR - filter. xq is the circular queue, in pointing at the new sample, xi - current index for in xq and l the lenght of the filter */ -inline uint16_t updateq(int16_t* xq, int16_t* in, uint16_t xi, uint16_t l) -{ - xq[xi]=xq[xi+l]=*in; - return (--xi)&(l-1); \ -} - -#endif /* __FIR_H__ */ -
--- a/libao2/firfilter.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -#include <inttypes.h> -#include <math.h> - -static double desired_7kHz_lowpass[] = {1.0, 0.0}; -static double weights_7kHz_lowpass[] = {0.2, 2.0}; - -double *calc_coefficients_7kHz_lowpass(int rate) -{ - double *result = (double *)malloc(32*sizeof(double)); - double bands[4]; - - bands[0] = 0.0; bands[1] = 6800.0/rate; - bands[2] = 8500.0/rate; bands[3] = 0.5; - - remez(result, 32, 2, bands, - desired_7kHz_lowpass, weights_7kHz_lowpass, BANDPASS); - - return result; -} - -#if 0 - -static double desired_125Hz_lowpass[] = {1.0, 0.0}; -static double weights_125Hz_lowpass[] = {0.2, 2.0}; - -double *calc_coefficients_125Hz_lowpass(int rate) -{ - double *result = (double *)malloc(256*sizeof(double)); - double bands[4]; - - bands[0] = 0.0; bands[1] = 125.0/rate; - bands[2] = 175.0/rate; bands[3] = 0.5; - - remez(result, 256, 2, bands, - desired_125Hz_lowpass, weights_125Hz_lowpass, BANDPASS); - - return result; -} - -#endif - -int16_t firfilter(int16_t *buf, int pos, int len, int count, double *coefficients) -{ - double result = 0.0; - int count1, count2; - int16_t *ptr; - - if (pos >= count) { - pos -= count; - count1 = count; count2 = 0; - } - else { - count2 = pos; - count1 = count - pos; - pos = len - count1; - } - //fprintf(stderr, "pos=%d, count1=%d, count2=%d\n", pos, count1, count2); - - // high part of window - ptr = &buf[pos]; - while (count1--) result += *ptr++ * *coefficients++; - // wrapped part of window - while (count2--) result += *buf++ * *coefficients++; - return result; -} - -void dump_filter_coefficients(double *coefficients) -{ - int i; - fprintf(stderr, "pl_surround: Filter coefficients are: \n"); - for (i=0; (i<32); i++) { - fprintf(stderr, " [%2d]: %23.20f\n", i, coefficients[i]); - } -} - -#ifdef TESTING - -#define PI 3.1415926536 - -// For testing purposes, fill a buffer with some sine-wave tone -void sinewave(int16_t *output, int samples, int incr, int freq, double phase, int samplerate) -{ - double radians_per_sample = 2*PI / ((0.0+samplerate) / freq), r; - - //fprintf(stderr, "samples=%d tone freq=%d, samplerate=%d, radians/sample=%f\n", - // samples, freq, samplerate, radians_per_sample); - r = phase; - while (samples--) { - *output = sin(r)*10000; output = &output[incr]; - r += radians_per_sample; - } -} - -// Pass various frequencies through a FIR filter and report amplitudes -void testfilter(double *coefficients, int count, int samplerate) -{ - int16_t wavein[8192]; //, waveout[2048]; - int sample, samples, maxsample, minsample, totsample; - int nyquist=samplerate/2; - int freq, i; - - for (freq=25; freq<nyquist; freq+=25) { - // Make input tone - sinewave(wavein, 8192, 1, freq, 0.0, samplerate); - //for (i=0; i<32; i++) - // fprintf(stderr, "%5d\n", wavein[i]); - // Filter through the filter, measure results - maxsample=0; minsample=1000000; totsample=0; samples=0; - for (i=2048; i<8192; i++) { - //waveout[i] = wavein[i]; - sample = abs(firfilter(wavein, i, 8192, count, coefficients)); - if (sample > maxsample) maxsample=sample; - if (sample < minsample) minsample=sample; - totsample += sample; samples++; - } - // Report results - fprintf(stderr, "%5d %5d %5d %5d %f\n", freq, totsample/samples, maxsample, minsample, 10*log((totsample/samples)/6500.0)); - } -} - -#endif
--- a/libao2/pl_delay.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* Audio out plugin it doesn't really do anything useful but serves - an example of how audio plugins work. It delays the output signal - by the nuber of samples set by delay=n where n is the number of - bytes. -*/ -#define PLUGIN - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "audio_out.h" -#include "audio_plugin.h" -#include "audio_plugin_internal.h" -#include "libaf/af_format.h" - -static ao_info_t info = -{ - "Delay audio plugin", - "delay", - "Anders", - "" -}; - -LIBAO_PLUGIN_EXTERN(delay) - -// local data -typedef struct pl_delay_s -{ - void* data; // local audio data block - void* delay; // data block used for delaying audio signal - int len; // local buffer length - int rate; // local data rate - int channels; // local number of channels - int format; // local format -} pl_delay_t; - -static pl_delay_t pl_delay={NULL,NULL,0,0,0,0}; - -// to set/get/query special features/parameters -static int control(int cmd,void *arg){ - switch(cmd){ - case AOCONTROL_PLUGIN_SET_LEN: - if(pl_delay.data) - free(pl_delay.data); - pl_delay.len = ao_plugin_data.len; - pl_delay.data=(void*)malloc(ao_plugin_data.len); - if(!pl_delay.data) - return CONTROL_ERROR; - return CONTROL_OK; - } - return -1; -} - -// open & setup audio device -// return: 1=success 0=fail -static int init(){ - float time_delay; // The time in [s] this plugin delays the output data - - /* If the output format of any of the below parameters differs from - what is give it should be changed. See ao_plugin init() */ - pl_delay.rate=ao_plugin_data.rate; - pl_delay.channels=ao_plugin_data.channels; //1=mono 2=stereo - pl_delay.format=ao_plugin_data.format; - - // Tell ao_plugin how much this plugin adds to the overall time delay - time_delay=-1*(float)ao_plugin_cfg.pl_delay_len/((float)pl_delay.channels*(float)pl_delay.rate); - if(pl_delay.format != AF_FORMAT_U8 && pl_delay.format != AF_FORMAT_S8) - time_delay/=2; - ao_plugin_data.delay_fix+=time_delay; - - // Create buffer for the delayed data - pl_delay.delay=(void*)malloc(ao_plugin_cfg.pl_delay_len); - if(!pl_delay.delay) - return 0; - memset(pl_delay.delay, 0, ao_plugin_cfg.pl_delay_len); - - // Print some cool remark of what the plugin does - printf("[pl_delay] Output sound delayed by %i bytes\n",ao_plugin_cfg.pl_delay_len); - return 1; -} - -// close plugin -static void uninit(){ - if(pl_delay.delay) - free(pl_delay.delay); - if(pl_delay.data) - free(pl_delay.data); - ao_plugin_cfg.pl_delay_len=0; -} - -// empty buffers -static void reset(){ - int i = 0; - for(i=0;i<pl_delay.len;i++) - ((char*)pl_delay.data)[i]=0; - for(i=0;i<ao_plugin_cfg.pl_delay_len;i++) - ((char*)pl_delay.delay)[i]=0; -} - -// processes 'ao_plugin_data.len' bytes of 'data' -// called for every block of data -static int play(){ - // Copy end of prev block to begining of buffer - memcpy(pl_delay.data,pl_delay.delay,ao_plugin_cfg.pl_delay_len); - // Copy current block except end - memcpy(pl_delay.data+ao_plugin_cfg.pl_delay_len, - ao_plugin_data.data, - ao_plugin_data.len-ao_plugin_cfg.pl_delay_len); - // Save away end of current block for next call - memcpy(pl_delay.delay, - ao_plugin_data.data+ao_plugin_data.len-ao_plugin_cfg.pl_delay_len, - ao_plugin_cfg.pl_delay_len); - // Set output data block - ao_plugin_data.data=pl_delay.data; - return 1; -} - - - - - - - - - - - -
--- a/libao2/pl_eq.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,218 +0,0 @@ -/*============================================================================= -// -// This software has been released under the terms of the GNU Public -// license. See http://www.gnu.org/copyleft/gpl.html for details. -// -// Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au -// -//============================================================================= -*/ - -/* Equalizer plugin, implementation of a 10 band time domain graphic - equalizer using IIR filters. The IIR filters are implemented using a - Direct Form II approach. But has been modified (b1 == 0 always) to - save computation. -*/ -#define PLUGIN - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <inttypes.h> -#include <math.h> - -#include "audio_out.h" -#include "audio_plugin.h" -#include "audio_plugin_internal.h" -#include "libaf/af_format.h" -#include "eq.h" - -static ao_info_t info = -{ - "Equalizer audio plugin", - "eq", - "Anders", - "" -}; - -LIBAO_PLUGIN_EXTERN(eq) - - -#define CH 6 // Max number of channels -#define L 2 // Storage for filter taps -#define KM 10 // Max number of octaves - -#define Q 1.2247 /* Q value for band-pass filters 1.2247=(3/2)^(1/2) - gives 4dB suppression @ Fc*2 and Fc/2 */ - -// Center frequencies for band-pass filters -#define CF {31.25,62.5,125,250,500,1000,2000,4000,8000,16000} - -// local data -typedef struct pl_eq_s -{ - int16_t a[KM][L]; // A weights - int16_t b[KM][L]; // B weights - int16_t wq[CH][KM][L]; // Circular buffer for W data - int16_t g[CH][KM]; // Gain factor for each channel and band - int16_t K; // Number of used eq bands - int channels; // Number of channels -} pl_eq_t; - -static pl_eq_t pl_eq; - -// to set/get/query special features/parameters -static int control(int cmd,void *arg){ - switch(cmd){ - case AOCONTROL_PLUGIN_SET_LEN: - return CONTROL_OK; - case AOCONTROL_PLUGIN_EQ_SET_GAIN:{ - float gain = ((equalizer_t*)arg)->gain; - int ch =((equalizer_t*)arg)->channel; - int band =((equalizer_t*)arg)->band; - if(ch > CH || ch < 0 || band > KM || band < 0) - return CONTROL_ERROR; - - pl_eq.g[ch][band]=(int16_t) 4096 * (pow(10.0,gain/20.0)-1.0); - return CONTROL_OK; - } - case AOCONTROL_PLUGIN_EQ_GET_GAIN:{ - int ch =((equalizer_t*)arg)->channel; - int band =((equalizer_t*)arg)->band; - if(ch > CH || ch < 0 || band > KM || band < 0) - return CONTROL_ERROR; - - ((equalizer_t*)arg)->gain = log10((float)pl_eq.g[ch][band]/4096.0+1) * 20.0; - return CONTROL_OK; - } - } - return CONTROL_UNKNOWN; -} - -// return rounded 16bit int -static inline int16_t lround16(double n){ - return (int16_t)((n)>=0.0?(n)+0.5:(n)-0.5); -} - -// 2nd order Band-pass Filter design -void bp2(int16_t* a, int16_t* b, float fc, float q){ - double th=2*3.141592654*fc; - double C=(1 - tan(th*q/2))/(1 + tan(th*q/2)); - - a[0] = lround16( 16383.0 * (1 + C) * cos(th)); - a[1] = lround16(-16383.0 * C); - - b[0] = lround16(-16383.0 * (C - 1)/2); - b[1] = lround16(-16383.0 * 1.0050); -} - -// empty buffers -static void reset(){ - int k,l,c; - for(c=0;c<pl_eq.channels;c++) - for(k=0;k<pl_eq.K;k++) - for(l=0;l<L*2;l++) - pl_eq.wq[c][k][l]=0; -} - -// open & setup audio device -// return: 1=success 0=fail -static int init(){ - int k = 0; - float F[KM] = CF; - - // Check input format - if(ao_plugin_data.format != AF_FORMAT_S16_NE){ - fprintf(stderr,"[pl_eq] Input audio format not yet supported. \n"); - return 0; - } - - // Check number of channels - if(ao_plugin_data.channels>CH){ - fprintf(stderr,"[pl_eq] Too many channels, max is 6.\n"); - return 0; - } - pl_eq.channels=ao_plugin_data.channels; - - // Calculate number of active filters - pl_eq.K=KM; - while(F[pl_eq.K-1] > (float)ao_plugin_data.rate/2) - pl_eq.K--; - - // Generate filter taps - for(k=0;k<pl_eq.K;k++) - bp2(pl_eq.a[k],pl_eq.b[k],F[k]/((float)ao_plugin_data.rate),Q); - - // Reset buffers - reset(); - - // Tell ao_plugin how much this plugin adds to the overall time delay - ao_plugin_data.delay_fix-=2/((float)pl_eq.channels*(float)ao_plugin_data.rate); - // Print some cool remark of what the plugin does - printf("[pl_eq] Equalizer in use.\n"); - return 1; -} - -// close plugin -static void uninit(){ -} - -// processes 'ao_plugin_data.len' bytes of 'data' -// called for every block of data -static int play(){ - uint16_t ci = pl_eq.channels; // Index for channels - uint16_t nch = pl_eq.channels; // Number of channels - - while(ci--){ - int16_t* g = pl_eq.g[ci]; // Gain factor - int16_t* in = ((int16_t*)ao_plugin_data.data)+ci; - int16_t* out = ((int16_t*)ao_plugin_data.data)+ci; - int16_t* end = in+ao_plugin_data.len/2; // Block loop end - - while(in < end){ - register int16_t k = 0; // Frequency band index - register int32_t yt = 0; // Total output from filters - register int16_t x = *in; // Current input sample - in+=nch; - - // Run the filters - for(;k<pl_eq.K;k++){ - // Pointer to circular buffer wq - register int16_t* wq = pl_eq.wq[ci][k]; -#if 0 - // Calculate output from AR part of current filter - register int32_t xt = (x*pl_eq.b[k][0]) >> 4; - register int32_t w = xt + wq[0]*pl_eq.a[k][0] + wq[1]*pl_eq.a[k][1]; - // Calculate output form MA part of current filter - yt+=(((w + wq[1]*pl_eq.b[k][1]) >> 10)*g[k]) >> 12; - // Update circular buffer - wq[1] = wq[0]; wq[0] = w >> 14; - } - - // Calculate output - *out=(int16_t)(yt+x); -#else - // Calculate output from AR part of current filter - register int32_t xt = (x*pl_eq.b[k][0]) / 48; - register int32_t w = xt + wq[0]*pl_eq.a[k][0] + wq[1]*pl_eq.a[k][1]; - // Calculate output form MA part of current filter - yt+=(((w + wq[1]*pl_eq.b[k][1]) >> 10)*g[k]) >> 12; - // Update circular buffer - wq[1] = wq[0]; wq[0] = w / 24576; - } - - // Calculate output - *out=(int16_t)(yt * 0.25 + x * 0.5); -#endif - out+=nch; - } - } - return 1; -} - - - - - - -
--- a/libao2/pl_extrastereo.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* Extrastereo effect plugin - * (linearly increases difference between L&R channels) - * - * Current limitations: - * - only AFMT_S16_HE is supported currently - * - * License: GPLv2 (as a mix of pl_volume.c and - * xmms:stereo_plugin/stereo.c) - * - * Author: pl <p_l@gmx.fr> (c) 2002 and beyond... - * */ - -#define PLUGIN - -#include <stdio.h> -#include <stdlib.h> -#include <inttypes.h> - -#include "audio_out.h" -#include "audio_plugin.h" -#include "audio_plugin_internal.h" -#include "libaf/af_format.h" - -static ao_info_t info = { - "Extra stereo plugin", - "extrastereo", - "pl <p_l@gmx.fr>", - "" -}; - -LIBAO_PLUGIN_EXTERN(extrastereo) - -// local data -static struct { - float mul; // intensity - int inuse; // This plugin is in use TRUE, FALSE - int format; // sample format -} pl_extrastereo = {2.5, 0, 0}; - - -// to set/get/query special features/parameters -static int control(int cmd,void *arg){ - switch(cmd){ - case AOCONTROL_PLUGIN_SET_LEN: - return CONTROL_OK; - case AOCONTROL_PLUGIN_ES_SET: - pl_extrastereo.mul=*((float*)arg); - return CONTROL_OK; - case AOCONTROL_PLUGIN_ES_GET: - *((float*)arg)=pl_extrastereo.mul; - return CONTROL_OK; - } - return CONTROL_UNKNOWN; -} - -// open & setup audio device -// return: 1=success 0=fail -static int init(){ - switch(ao_plugin_data.format){ - case(AF_FORMAT_S16_NE): - break; - default: - fprintf(stderr,"[pl_extrastereo] Audio format not yet suported \n"); - return 0; - } - - pl_extrastereo.mul=ao_plugin_cfg.pl_extrastereo_mul; - pl_extrastereo.format=ao_plugin_data.format; - pl_extrastereo.inuse=1; - - printf("[pl_extrastereo] Extra stereo plugin in use (multiplier=%2.2f).\n", - pl_extrastereo.mul); - return 1; -} - -// close plugin -static void uninit(){ - pl_extrastereo.inuse=0; -} - -// empty buffers -static void reset(){ -} - -// processes 'ao_plugin_data.len' bytes of 'data' -// called for every block of data -static int play(){ - - switch(pl_extrastereo.format){ - case(AF_FORMAT_S16_NE): { - - int16_t* data=(int16_t*)ao_plugin_data.data; - int len=ao_plugin_data.len / 2; // 16 bits samples - - float mul = pl_extrastereo.mul; - int32_t i, avg, ltmp, rtmp; - - for (i=0; i < len ; i += 2) { - - avg = (data[i] + data[i + 1]) / 2; - - ltmp = avg + (int) (mul * (data[i] - avg)); - rtmp = avg + (int) (mul * (data[i + 1] - avg)); - - if (ltmp < -32768) { - ltmp = -32768; - } else if (ltmp > 32767) { - ltmp = 32767; - } - - if (rtmp < -32768) { - rtmp = -32768; - } else if (rtmp > 32767) { - rtmp = 32767; - } - - data[i] = ltmp; - data[i + 1] = rtmp; - } - break; - } - default: - return 0; - } - return 1; -} -
--- a/libao2/pl_format.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,316 +0,0 @@ -/* This audio output plugin changes the format of a data block. Valid - output formats are: AFMT_U8, AFMT_S8, AFMT_S16_LE, AFMT_S16_BE - AFMT_U16_LE, AFMT_U16_BE, AFMT_S32_LE and AFMT_S32_BE. The output - format is spedified using the cfg switch 'format=NR' where NR is - the number as given in libao2/afmt.h -*/ - -#define PLUGIN - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <inttypes.h> - -#include "audio_out.h" -#include "audio_plugin.h" -#include "audio_plugin_internal.h" -#include "libaf/af_format.h" - -static ao_info_t info = -{ - "Sample format conversion audio plugin", - "format", - "Anders", - "" -}; - -LIBAO_PLUGIN_EXTERN(format) - -// local data -typedef struct pl_format_s -{ - void* data; // local audio data block - int len; // local buffer length - int in; // input fomat - int out; // output fomat - double sz_mult; // data size multiplier -} pl_format_t; - -static pl_format_t pl_format={NULL,0,0,0,1}; - -// Number of bits -#define B08 (0<<0) -#define B16 (1<<0) -#define B32 (2<<0) -#define NBITS_MASK (3<<0) - -// Endianess -#define BE (0<<2) // Big Endian -#define LE (1<<2) // Little Endian -#define END_MASK (1<<2) - -// Signed -#define US (0<<3) // Un Signed -#define SI (1<<3) // SIgned -#define SIGN_MASK (1<<3) - -// to set/get/query special features/parameters -static int control(int cmd,void *arg){ - switch(cmd){ - case AOCONTROL_PLUGIN_SET_LEN: - if(pl_format.data) - free(pl_format.data); - pl_format.len = ao_plugin_data.len; - pl_format.data=(void*)malloc(ao_plugin_data.len); - if(!pl_format.data) - return CONTROL_ERROR; - ao_plugin_data.len=(int)(((double)ao_plugin_data.len)/pl_format.sz_mult); - return CONTROL_OK; - } - return -1; -} - -// open & setup audio device -// return: 1=success 0=fail -static int init(){ - char buf1[128], buf2[128]; - // Sheck input format - switch(ao_plugin_data.format){ - case(AF_FORMAT_U8): - pl_format.in=LE|B08|US; break; - case(AF_FORMAT_S8): - pl_format.in=LE|B08|SI; break; - case(AF_FORMAT_S16_LE): - pl_format.in=LE|B16|SI; break; - case(AF_FORMAT_S16_BE): - pl_format.in=BE|B16|SI; break; - case(AF_FORMAT_U16_LE): - pl_format.in=LE|B16|US; break; - case(AF_FORMAT_U16_BE): - pl_format.in=BE|B16|US; break; - case(AF_FORMAT_S32_LE): - pl_format.in=LE|B32|SI; break; - case(AF_FORMAT_S32_BE): - pl_format.in=BE|B32|SI; break; - case(AF_FORMAT_IMA_ADPCM): - case(AF_FORMAT_MU_LAW): - case(AF_FORMAT_A_LAW): - case(AF_FORMAT_MPEG2): - case(AF_FORMAT_AC3): - printf("[pl_format] Input audio format not yet suported \n"); - return 0; - default: - printf("[pl_format] Unrecognised input audio format\n"); //This can not happen .... - return 0; - } - // Sheck output format - switch(ao_plugin_cfg.pl_format_type){ - case(AF_FORMAT_U8): - pl_format.out=LE|B08|US; break; - case(AF_FORMAT_S8): - pl_format.out=LE|B08|SI; break; - case(AF_FORMAT_S16_LE): - pl_format.out=LE|B16|SI; break; - case(AF_FORMAT_S16_BE): - pl_format.out=BE|B16|SI; break; - case(AF_FORMAT_U16_LE): - pl_format.out=LE|B16|US; break; - case(AF_FORMAT_U16_BE): - pl_format.out=BE|B16|US; break; - case(AF_FORMAT_S32_LE): - pl_format.out=LE|B32|SI; break; - case(AF_FORMAT_S32_BE): - pl_format.out=BE|B32|SI; break; - case(AF_FORMAT_IMA_ADPCM): - case(AF_FORMAT_MU_LAW): - case(AF_FORMAT_A_LAW): - case(AF_FORMAT_MPEG2): - case(AF_FORMAT_AC3): - printf("[pl_format] Output audio format not yet suported \n"); - return 0; - default: - printf("[pl_format] Unrecognised audio output format\n"); - return 0; - } - - // Tell the world what we are up to - printf("[pl_format] Input format: %s, output format: %s \n", - af_fmt2str(ao_plugin_data.format, buf1, 128), - af_fmt2str(ao_plugin_cfg.pl_format_type, buf2, 128)); - - // We are changing the format - ao_plugin_data.format=ao_plugin_cfg.pl_format_type; - - // And perhaps the buffer size - pl_format.sz_mult=1; - if((pl_format.in&NBITS_MASK) > (pl_format.out&NBITS_MASK)) - pl_format.sz_mult/=(double)(1<<((pl_format.in&NBITS_MASK)-(pl_format.out&NBITS_MASK))); - if((pl_format.in&NBITS_MASK) < (pl_format.out&NBITS_MASK)) - pl_format.sz_mult*=(double)(1<<((pl_format.out&NBITS_MASK)-(pl_format.in&NBITS_MASK))); - ao_plugin_data.sz_mult/=pl_format.sz_mult; - - return 1; -} - -// close plugin -static void uninit(){ - if(pl_format.data) - free(pl_format.data); - pl_format.data=NULL; -} - -// empty buffers -static void reset(){ - memset(pl_format.data, 0, pl_format.len); -} - -// processes 'ao_plugin_data.len' bytes of 'data' -// called for every block of data -// FIXME: this routine needs to be optimized (it is probably possible to do a lot here) -static int play(){ - register int i=0; - void* in_data=ao_plugin_data.data; - void* out_data=pl_format.data; - int len=(ao_plugin_data.len)>>(pl_format.in&NBITS_MASK); - ao_plugin_data.len=(int)(((double)ao_plugin_data.len)*pl_format.sz_mult); - - // Change to little endian (Is this true for sun ?) - if((pl_format.in&END_MASK)!=LE){ - switch(pl_format.in&NBITS_MASK){ - case(B16):{ - register uint16_t s; - for(i=1;i<len;i++){ - s=((uint16_t*)in_data)[i]; - ((uint16_t*)in_data)[i]=(uint16_t)(((s&0x00FF)<<8) | (s&0xFF00)>>8); - } - } - break; - case(B32):{ - register uint32_t s; - for(i=1;i<len;i++){ - s=((uint32_t*)in_data)[i]; - ((uint32_t*)in_data)[i]=(uint32_t)(((s&0x000000FF)<<24) | ((s&0x0000FF00)<<8) | - ((s&0x00FF0000)>>8) | ((s&0xFF000000)>>24)); - } - } - break; - } - } - // Change signed/unsigned - if((pl_format.in&SIGN_MASK) != (pl_format.out&SIGN_MASK)){ - switch((pl_format.in&NBITS_MASK)){ - case(B08): - switch(pl_format.in&SIGN_MASK){ - case(US): - for(i=0;i<len;i++) - ((int8_t*)in_data)[i]=(int8_t)(-127+((int)((uint8_t*)in_data)[i])); - break; - case(SI): - for(i=0;i<len;i++) - ((uint8_t*)in_data)[i]=(uint8_t)(+128+((int)((int8_t*)in_data)[i])); - break; - } - break; - case(B16): - switch(pl_format.in&SIGN_MASK){ - case(US): - for(i=0;i<len;i++) - ((int16_t*)in_data)[i]=(int16_t)(-32767+((int)((uint16_t*)in_data)[i])); - break; - case(SI): - for(i=0;i<len;i++) - ((uint16_t*)in_data)[i]=(uint16_t)(+32768+((int)((int16_t*)in_data)[i])); - break; - } - break; - case(B32): - switch(pl_format.in&SIGN_MASK){ - case(US): - for(i=0;i<len;i++) - ((int32_t*)in_data)[i]=(int32_t)(((uint32_t*)in_data)[i]-0x80000000); - break; - case(SI): - for(i=0;i<len;i++) - ((uint32_t*)in_data)[i]=(uint32_t)(+(1<<31)+((int32_t*)in_data)[i]); - break; - } - break; - } - } - // Change the number of bits - if((pl_format.in&NBITS_MASK) == (pl_format.out&NBITS_MASK)){ - int sz=(int)((double)ao_plugin_data.len/pl_format.sz_mult); - for(i=0;i<sz;i++) - ((char*)out_data)[i]=((char*)in_data)[i]; - } else { - switch(pl_format.in&NBITS_MASK){ - case(B08): - switch(pl_format.out&NBITS_MASK){ - case(B16): - for(i=1;i<len;i++) - ((uint16_t*)out_data)[i]=((uint16_t)((uint8_t*)in_data)[i])<<8; - break; - case(B32): - for(i=1;i<len;i++) - ((uint32_t*)out_data)[i]=((uint32_t)((uint8_t*)in_data)[i])<<24; - break; - } - break; - case(B16): - switch(pl_format.out&NBITS_MASK){ - case(B08): - for(i=0;i<len;i++) - ((uint8_t*)out_data)[i]=(uint8_t)((((uint16_t*)in_data)[i])>>8); - break; - case(B32): - for(i=1;i<len;i++) - ((uint32_t*)out_data)[i]=((uint32_t)((uint16_t*)in_data)[i])<<16; - break; - } - break; - case(B32): - switch(pl_format.out&NBITS_MASK){ - case(B08): - for(i=0;i<len;i++) - ((uint8_t*)out_data)[i]=(uint8_t)((((uint32_t*)in_data)[i])>>24); - break; - case(B16): - for(i=1;i<len;i++) - ((uint16_t*)out_data)[i]=(uint16_t)((((uint32_t*)in_data)[i])>>16); - break; - } - break; - } - } - // Switch to the correct endainess (agiain the problem with sun?) - if((pl_format.out&END_MASK)!=LE){ - switch(pl_format.in&NBITS_MASK){ - case(B16):{ - register uint16_t s; - for(i=1;i<len;i++){ - s=((uint16_t*)out_data)[i]; - ((uint16_t*)out_data)[i]=(uint16_t)(((s&0x00FF)<<8) | (s&0xFF00)>>8); - } - } - break; - case(B32):{ - register uint32_t s; - for(i=1;i<len;i++){ - s=((uint32_t*)out_data)[i]; - ((uint32_t*)out_data)[i]=(uint32_t)(((s&0x000000FF)<<24) | ((s&0x0000FF00)<<8) | - ((s&0x00FF0000)>>8) | ((s&0xFF000000)>>24)); - } - } - break; - } - } - ao_plugin_data.data=out_data; - return 1; -} - - - - -
--- a/libao2/pl_resample.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,285 +0,0 @@ -/*============================================================================= -// -// This software has been released under the terms of the GNU Public -// license. See http://www.gnu.org/copyleft/gpl.html for details. -// -// Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au -// -//============================================================================= -*/ - -/* This audio output plugin changes the sample rate. The output - samplerate from this plugin is specified by using the switch - `fout=F' where F is the desired output sample frequency -*/ - -#define PLUGIN - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <inttypes.h> - -#include "audio_out.h" -#include "audio_plugin.h" -#include "audio_plugin_internal.h" -#include "libaf/af_format.h" - -static ao_info_t info = -{ - "Sample frequency conversion audio plugin", - "resample", - "Anders", - "" -}; - -LIBAO_PLUGIN_EXTERN(resample) - -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#define max(a,b) (((a) > (b)) ? (a) : (b)) - -/* Below definition selects the length of each poly phase component. - Valid definitions are L8 and L16, where the number denotes the - length of the filter. This definition affects the computational - complexity (see play()), the performance (see filter.h) and the - memory usage. The filterlenght is choosen to 8 if the machine is - slow and to 16 if the machine is fast and has MMX. -*/ - -#if !defined(HAVE_SSE) && !defined(HAVE_3DNOW) //This machine is slow - -#define W W8 // Filter bank parameters -#define L 8 // Filter length -#ifdef HAVE_MMX -#define FIR(x,w,y) *y=(int16_t)firn(x,w,8); -#else /* HAVE_MMX */ -// Unrolled loop to speed up execution -#define FIR(x,w,y){ \ - int16_t a = (w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3]) >> 16; \ - int16_t b = (w[4]*x[4]+w[5]*x[5]+w[6]*x[6]+w[7]*x[7]) >> 16; \ - y[0] = a+b; \ -} -#endif /* HAVE_MMX */ - -#else /* Fast machine */ - -#define W W16 -#define L 16 -#define FIR(x,w,y) *y=(int16_t)firn(x,w,16); - -#endif - -#define CH 6 // Max number of channels -#define UP 128 /* Up sampling factor. Increasing this value will - improve frequency accuracy. Think about the L1 - cashing of filter parameters - how big can it be? */ - -#include "fir.h" -#include "filter.h" - -// local data -typedef struct pl_resample_s -{ - int16_t* data; // Data buffer - int16_t* w; // Current filter weights - uint16_t dn; // Down sampling factor - uint16_t up; // Up sampling factor - int channels; // Number of channels - int len; // Lenght of buffer - int16_t ws[UP*L]; // List of all available filters - int16_t xs[CH][L*2]; // Circular buffers -} pl_resample_t; - -static pl_resample_t pl_resample = {NULL,NULL,1,1,1,0,W}; - -// to set/get/query special features/parameters -static int control(int cmd,void *arg){ - switch(cmd){ - case AOCONTROL_PLUGIN_SET_LEN: - if(pl_resample.data) - free(pl_resample.data); - pl_resample.len = ao_plugin_data.len; - pl_resample.data=(int16_t*)malloc(pl_resample.len); - if(!pl_resample.data) - return CONTROL_ERROR; - ao_plugin_data.len = (int)((double)ao_plugin_data.len * - ((double)pl_resample.dn)/ - ((double)pl_resample.up)); - return CONTROL_OK; - } - return -1; -} - -// open & setup audio device -// return: 1=success 0=fail -static int init(){ - int fin=ao_plugin_data.rate; - int fout=ao_plugin_cfg.pl_resample_fout; - pl_resample.w=pl_resample.ws; - pl_resample.up=UP; - - // Sheck input format - if(ao_plugin_data.format != AF_FORMAT_S16_NE){ - fprintf(stderr,"[pl_resample] Input audio format not yet suported. \n"); - return 0; - } - // Sanity check and calculate down sampling factor - if((float)max(fin,fout)/(float)min(fin,fout) > 10){ - fprintf(stderr,"[pl_resample] The difference between fin and fout is too large.\n"); - return 0; - } - pl_resample.dn=(int)(0.5+((float)(fin*pl_resample.up))/((float)fout)); - - pl_resample.channels=ao_plugin_data.channels; - if(ao_plugin_data.channels>CH){ - fprintf(stderr,"[pl_resample] Too many channels, max is 6.\n"); - return 0; - } - - // Tell the world what we are up to - printf("[pl_resample] Up=%i, Down=%i, True fout=%f\n", - pl_resample.up,pl_resample.dn, - ((float)fin*pl_resample.up)/((float)pl_resample.dn)); - - // This plugin changes buffersize and adds some delay - ao_plugin_data.sz_mult/=((float)pl_resample.up)/((float)pl_resample.dn); - ao_plugin_data.delay_fix-= ((float)L/2) * (1/fout); - ao_plugin_data.rate=fout; - return 1; -} - -// close plugin -static void uninit(){ - if(pl_resample.data) - free(pl_resample.data); - pl_resample.data=NULL; -} - -// empty buffers -static void reset(){ -} - -/* forward declarations */ -int upsample(); -int downsample(); - -// processes 'ao_plugin_data.len' bytes of 'data' -// called for every block of data -// FIXME: this routine needs to be optimized (it is probably possible to do a lot here) -static int play(){ - if(pl_resample.up==pl_resample.dn){ - register int16_t* in = ((int16_t*)ao_plugin_data.data); - register int16_t* end = in+ao_plugin_data.len/2; - while(in < end) *(in++)>>=1; - return 1; - } - if(pl_resample.up>pl_resample.dn) - return upsample(); -// if(pl_resample.up<pl_resample.dn) - return downsample(); -} - -int upsample(){ - static uint16_t pwi = 0; // Index for w - static uint16_t pxi = 0; // Index for circular queue - - uint16_t ci = pl_resample.channels; // Index for channels - uint16_t nch = pl_resample.channels; // Number of channels - uint16_t len = 0; // Number of input samples - uint16_t inc = pl_resample.up/pl_resample.dn; - uint16_t level = pl_resample.up%pl_resample.dn; - uint16_t up = pl_resample.up; - uint16_t dn = pl_resample.dn; - - register int16_t* w = pl_resample.w; - register uint16_t wi,xi; // Temporary indexes - - // Index current channel - while(ci--){ - // Temporary pointers - register int16_t* x = pl_resample.xs[ci]; - register int16_t* in = ((int16_t*)ao_plugin_data.data)+ci; - register int16_t* out = pl_resample.data+ci; - int16_t* end = in+ao_plugin_data.len/2; // Block loop end - - wi = pwi; xi = pxi; - - while(in < end){ - register uint16_t i = inc; - if(wi<level) i++; - - xi=updateq(x,in,xi,L); - in+=nch; - while(i--){ - // Run the FIR filter - FIR((&x[xi]),(&w[wi*L]),out); - len++; out+=nch; - // Update wi to point at the correct polyphase component - wi=(wi+dn)%up; - } - } - } - - // Save values that needs to be kept for next time - pwi = wi; - pxi = xi; - - // Set new data - ao_plugin_data.len=len*2; - ao_plugin_data.data=pl_resample.data; - return 1; -} - -int downsample(){ - static uint16_t pwi = 0; // Index for w - static uint16_t pxi = 0; // Index for circular queue - static uint16_t pi = 1; // Number of new samples to put in x queue - - uint16_t ci = pl_resample.channels; // Index for channels - uint16_t len = 0; // Number of input samples - uint16_t nch = pl_resample.channels; // Number of channels - uint16_t inc = pl_resample.dn/pl_resample.up; - uint16_t level = pl_resample.dn%pl_resample.up; - uint16_t up = pl_resample.up; - uint16_t dn = pl_resample.dn; - - register uint16_t i,wi,xi; // Temporary indexes - - - // Index current channel - while(ci--){ - // Temporary pointers - register int16_t* x = pl_resample.xs[ci]; - register int16_t* in = ((int16_t*)ao_plugin_data.data)+ci; - register int16_t* out = pl_resample.data+ci; - // Block loop end - register int16_t* end = in+ao_plugin_data.len/2; - i = pi; wi = pwi; xi = pxi; - - while(in < end){ - - xi=updateq(x,in,xi,L); - in+=nch; - if(!--i){ - // Run the FIR filter - FIR((&x[xi]),(&pl_resample.w[wi*L]),out); - len++; out+=nch; - - // Update wi to point at the correct polyphase component - wi=(wi+dn)%up; - - // Insert i number of new samples in queue - i = inc; - if(wi<level) i++; - } - } - } - // Save values that needs to be kept for next time - pwi = wi; - pxi = xi; - pi = i; - // Set new data - ao_plugin_data.len=len*2; - ao_plugin_data.data=pl_resample.data; - return 1; -}
--- a/libao2/pl_surround.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,251 +0,0 @@ -/* - This is an ao2 plugin to do simple decoding of matrixed surround - sound. This will provide a (basic) surround-sound effect from - audio encoded for Dolby Surround, Pro Logic etc. - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Original author: Steve Davies <steve@daviesfam.org> -*/ - -/* The principle: Make rear channels by extracting anti-phase data - from the front channels, delay by 20msec and feed to rear in anti-phase -*/ - - -// SPLITREAR: Define to decode two distinct rear channels - -// this doesn't work so well in practice because -// separation in a passive matrix is not high. -// C (dialogue) to Ls and Rs 14dB or so - -// so dialogue leaks to the rear. -// Still - give it a try and send feedback. -// comment this define for old behaviour of a single -// surround sent to rear in anti-phase -#define SPLITREAR - - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "audio_out.h" -#include "audio_plugin.h" -#include "audio_plugin_internal.h" -#include "libaf/af_format.h" - -#include "remez.h" -#include "firfilter.c" - -static ao_info_t info = -{ - "Surround decoder plugin", - "surround", - "Steve Davies <steve@daviesfam.org>", - "" -}; - -LIBAO_PLUGIN_EXTERN(surround) - -// local data -typedef struct pl_surround_s -{ - int passthrough; // Just be a "NO-OP" - int msecs; // Rear channel delay in milliseconds - int16_t* databuf; // Output audio buffer - int16_t* Ls_delaybuf; // circular buffer to be used for delaying Ls audio - int16_t* Rs_delaybuf; // circular buffer to be used for delaying Rs audio - int delaybuf_len; // delaybuf buffer length in samples - int delaybuf_pos; // offset in buffer where we are reading/writing - double* filter_coefs_surround; // FIR filter coefficients for surround sound 7kHz lowpass - int rate; // input data rate - int format; // input format - int input_channels; // input channels - -} pl_surround_t; - -static pl_surround_t pl_surround={0,20,NULL,NULL,NULL,0,0,NULL,0,0,0}; - -// to set/get/query special features/parameters -static int control(int cmd,void *arg){ - switch(cmd){ - case AOCONTROL_PLUGIN_SET_LEN: - if (pl_surround.passthrough) return CONTROL_OK; - //fprintf(stderr, "pl_surround: AOCONTROL_PLUGIN_SET_LEN with arg=%d\n", arg); - //fprintf(stderr, "pl_surround: ao_plugin_data.len=%d\n", ao_plugin_data.len); - // Allocate an output buffer - if (pl_surround.databuf != NULL) { - free(pl_surround.databuf); pl_surround.databuf = NULL; - } - // Allocate output buffer - pl_surround.databuf = calloc(ao_plugin_data.len, 1); - // Return back smaller len so we don't get overflowed... - ao_plugin_data.len /= 2; - return CONTROL_OK; - } - return -1; -} - -// open & setup audio device -// return: 1=success 0=fail -static int init(){ - - fprintf(stderr, "pl_surround: init input rate=%d, channels=%d\n", ao_plugin_data.rate, ao_plugin_data.channels); - if (ao_plugin_data.channels != 2) { - fprintf(stderr, "pl_surround: source audio must have 2 channels, using passthrough mode\n"); - pl_surround.passthrough = 1; - return 1; - } - if (ao_plugin_data.format != AF_FORMAT_S16_NE) { - fprintf(stderr, "pl_surround: I'm dumb and can only handle AF_FORMAT_S16_NE audio format, using passthrough mode\n"); - pl_surround.passthrough = 1; - return 1; - } - - pl_surround.passthrough = 0; - - /* Store info on input format to expect */ - pl_surround.rate=ao_plugin_data.rate; - pl_surround.format=ao_plugin_data.format; - pl_surround.input_channels=ao_plugin_data.channels; - - // Input 2 channels, output will be 4 - tell ao_plugin - ao_plugin_data.channels = 4; - ao_plugin_data.sz_mult /= 2; - - // Figure out buffer space (in int16_ts) needed for the 15msec delay - // Extra 31 samples allow for lowpass filter delay (taps-1) - pl_surround.delaybuf_len = (pl_surround.rate * pl_surround.msecs / 1000) + 31; - // Allocate delay buffers - pl_surround.Ls_delaybuf=(void*)calloc(pl_surround.delaybuf_len,sizeof(int16_t)); - pl_surround.Rs_delaybuf=(void*)calloc(pl_surround.delaybuf_len,sizeof(int16_t)); - fprintf(stderr, "pl_surround: %dmsec surround delay, rate %d - buffers are %d bytes each\n", - pl_surround.msecs,pl_surround.rate, pl_surround.delaybuf_len*sizeof(int16_t)); - pl_surround.delaybuf_pos = 0; - // Surround filer coefficients - pl_surround.filter_coefs_surround = calc_coefficients_7kHz_lowpass(pl_surround.rate); - //dump_filter_coefficients(pl_surround.filter_coefs_surround); - //testfilter(pl_surround.filter_coefs_surround, 32, pl_surround.rate); - return 1; -} - -// close plugin -static void uninit(){ - // fprintf(stderr, "pl_surround: uninit called!\n"); - if (pl_surround.passthrough) return; - if(pl_surround.Ls_delaybuf) - free(pl_surround.Ls_delaybuf); - if(pl_surround.Rs_delaybuf) - free(pl_surround.Rs_delaybuf); - if(pl_surround.databuf) { - free(pl_surround.databuf); - pl_surround.databuf = NULL; - } - pl_surround.delaybuf_len=0; -} - -// empty buffers -static void reset() -{ - if (pl_surround.passthrough) return; - //fprintf(stderr, "pl_surround: reset called\n"); - pl_surround.delaybuf_pos = 0; - memset(pl_surround.Ls_delaybuf, 0, sizeof(int16_t)*pl_surround.delaybuf_len); - memset(pl_surround.Rs_delaybuf, 0, sizeof(int16_t)*pl_surround.delaybuf_len); -} - -// The beginnings of an active matrix... -static double steering_matrix[][12] = { -// LL RL LR RR LS RS LLs RLs LRs RRs LC RC - {.707, .0, .0, .707, .5, -.5, .5878, -.3928, .3928, -.5878, .5, .5}, -}; - -// Experimental moving average dominances -//static int amp_L = 0, amp_R = 0, amp_C = 0, amp_S = 0; - -// processes 'ao_plugin_data.len' bytes of 'data' -// called for every block of data -static int play(){ - int16_t *in, *out; - int i, samples; - double *matrix = steering_matrix[0]; // later we'll index based on detected dominance - - if (pl_surround.passthrough) return 1; - - // fprintf(stderr, "pl_surround: play %d bytes, %d samples\n", ao_plugin_data.len, samples); - - samples = ao_plugin_data.len / sizeof(int16_t) / pl_surround.input_channels; - out = pl_surround.databuf; in = (int16_t *)ao_plugin_data.data; - - // Testing - place a 1kHz tone on Lt and Rt in anti-phase: should decode in S - //sinewave(in, samples, pl_surround.input_channels, 1000, 0.0, pl_surround.rate); - //sinewave(&in[1], samples, pl_surround.input_channels, 1000, PI, pl_surround.rate); - - for (i=0; i<samples; i++) { - - // Dominance: - //abs(in[0]) abs(in[1]); - //abs(in[0]+in[1]) abs(in[0]-in[1]); - //10 * log( abs(in[0]) / (abs(in[1])|1) ); - //10 * log( abs(in[0]+in[1]) / (abs(in[0]-in[1])|1) ); - - // About volume balancing... - // Surround encoding does the following: - // Lt=L+.707*C+.707*S, Rt=R+.707*C-.707*S - // So S should be extracted as: - // (Lt-Rt) - // But we are splitting the S to two output channels, so we - // must take 3dB off as we split it: - // Ls=Rs=.707*(Lt-Rt) - // Trouble is, Lt could be +32767, Rt -32768, so possibility that S will - // overflow. So to avoid that, we cut L/R by 3dB (*.707), and S by 6dB (/2). - // this keeps the overall balance, but guarantees no overflow. - - // output front left and right - out[0] = matrix[0]*in[0] + matrix[1]*in[1]; - out[1] = matrix[2]*in[0] + matrix[3]*in[1]; - // output Ls and Rs - from 20msec ago, lowpass filtered @ 7kHz - out[2] = firfilter(pl_surround.Ls_delaybuf, pl_surround.delaybuf_pos, - pl_surround.delaybuf_len, 32, pl_surround.filter_coefs_surround); -#ifdef SPLITREAR - out[3] = firfilter(pl_surround.Rs_delaybuf, pl_surround.delaybuf_pos, - pl_surround.delaybuf_len, 32, pl_surround.filter_coefs_surround); -#else - out[3] = -out[2]; -#endif - // calculate and save surround for 20msecs time -#ifdef SPLITREAR - pl_surround.Ls_delaybuf[pl_surround.delaybuf_pos] = - matrix[6]*in[0] + matrix[7]*in[1]; - pl_surround.Rs_delaybuf[pl_surround.delaybuf_pos++] = - matrix[8]*in[0] + matrix[9]*in[1]; -#else - pl_surround.Ls_delaybuf[pl_surround.delaybuf_pos++] = - matrix[4]*in[0] + matrix[5]*in[1]; -#endif - pl_surround.delaybuf_pos %= pl_surround.delaybuf_len; - - // next samples... - in = &in[pl_surround.input_channels]; out = &out[4]; - } - - // Show some state - //printf("\npl_surround: delaybuf_pos=%d, samples=%d\r\033[A", pl_surround.delaybuf_pos, samples); - - // Set output block/len - ao_plugin_data.data=pl_surround.databuf; - ao_plugin_data.len=samples*sizeof(int16_t)*4; - return 1; -}
--- a/libao2/pl_volnorm.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,250 +0,0 @@ -/* Normalizer plugin - * - * Limitations: - * - only AFMT_S16_LE supported - * - no parameters yet => tweak the values by editing the #defines - * - * License: GPLv2 - * Author: pl <p_l@gmx.fr> (c) 2002 and beyond... - * - * Sources: some ideas from volnorm plugin for xmms - * - * */ - -#define PLUGIN - -/* Values for AVG: - * 1: uses a 1 value memory and coefficients new=a*old+b*cur (with a+b=1) - * - * 2: uses several samples to smooth the variations (standard weighted mean - * on past samples) - * - * */ -#define AVG 1 - -#include <stdio.h> -#include <stdlib.h> -#include <inttypes.h> -#include <math.h> // for sqrt() - -#include "audio_out.h" -#include "audio_plugin.h" -#include "audio_plugin_internal.h" -#include "libaf/af_format.h" - -static ao_info_t info = { - "Volume normalizer", - "volnorm", - "pl <p_l@gmx.fr>", - "" -}; - -LIBAO_PLUGIN_EXTERN(volnorm) - -// mul is the value by which the samples are scaled -// and has to be in [MUL_MIN, MUL_MAX] -#define MUL_INIT 1.0 -#define MUL_MIN 0.1 -#define MUL_MAX 5.0 -static float mul; - - -#if AVG==1 -// "history" value of the filter -static float lastavg; - -// SMOOTH_* must be in ]0.0, 1.0[ -// The new value accounts for SMOOTH_MUL in the value and history -#define SMOOTH_MUL 0.06 -#define SMOOTH_LASTAVG 0.06 - - -#elif AVG==2 -// Size of the memory array -// FIXME: should depend on the frequency of the data (should be a few seconds) -#define NSAMPLES 128 - -// Indicates where to write (in 0..NSAMPLES-1) -static int idx; -// The array -static struct { - float avg; // average level of the sample - int32_t len; // sample size (weight) -} mem[NSAMPLES]; - -// If summing all the mem[].len is lower than MIN_SAMPLE_SIZE bytes, then we -// choose to ignore the computed value as it's not significant enough -// FIXME: should depend on the frequency of the data (0.5s maybe) -#define MIN_SAMPLE_SIZE 32000 - -#else -// Kab00m ! -#error "Unknown AVG" -#endif - - -// Some limits -#define MIN_S16 -32768 -#define MAX_S16 32767 - -// "Ideal" level -#define MID_S16 (MAX_S16 * 0.25) - -// Silence level -// FIXME: should be relative to the level of the samples -#define SIL_S16 (MAX_S16 * 0.01) - - -// Local data -static struct { - int inuse; // This plugin is in use TRUE, FALSE - int format; // sample fomat -} pl_volnorm = {0, 0}; - - -// minimal interface -static int control(int cmd,void *arg){ - switch(cmd){ - case AOCONTROL_PLUGIN_SET_LEN: - return CONTROL_OK; - } - return CONTROL_UNKNOWN; -} - -// minimal interface -// open & setup audio device -// return: 1=success 0=fail -static int init(){ - switch(ao_plugin_data.format){ - case(AF_FORMAT_S16_NE): - break; - default: - fprintf(stderr,"[pl_volnorm] Audio format not yet supported.\n"); - return 0; - } - - pl_volnorm.format = ao_plugin_data.format; - pl_volnorm.inuse = 1; - - reset(); - - printf("[pl_volnorm] Normalizer plugin in use.\n"); - return 1; -} - -// close plugin -static void uninit(){ - pl_volnorm.inuse=0; -} - -// empty buffers -static void reset(){ - int i; - mul = MUL_INIT; - switch(ao_plugin_data.format) { - case(AF_FORMAT_S16_NE): -#if AVG==1 - lastavg = MID_S16; -#elif AVG==2 - for(i=0; i < NSAMPLES; ++i) { - mem[i].len = 0; - mem[i].avg = 0; - } - idx = 0; -#endif - - break; - default: - fprintf(stderr,"[pl_volnorm] internal inconsistency - bugreport !\n"); - *(char *) 0 = 0; - } -} - -// processes 'ao_plugin_data.len' bytes of 'data' -// called for every block of data -static int play(){ - - switch(pl_volnorm.format){ - case(AF_FORMAT_S16_NE): { -#define CLAMP(x,m,M) do { if ((x)<(m)) (x) = (m); else if ((x)>(M)) (x) = (M); } while(0) - - int16_t* data=(int16_t*)ao_plugin_data.data; - int len=ao_plugin_data.len / 2; // 16 bits samples - - int32_t i, tmp; - float curavg, newavg; - -#if AVG==1 - float neededmul; -#elif AVG==2 - float avg; - int32_t totallen; -#endif - - // Evaluate current samples average level - curavg = 0.0; - for (i = 0; i < len ; ++i) { - tmp = data[i]; - curavg += tmp * tmp; - } - curavg = sqrt(curavg / (float) len); - - // Evaluate an adequate 'mul' coefficient based on previous state, current - // samples level, etc -#if AVG==1 - if (curavg > SIL_S16) { - neededmul = MID_S16 / ( curavg * mul); - mul = (1.0 - SMOOTH_MUL) * mul + SMOOTH_MUL * neededmul; - - // Clamp the mul coefficient - CLAMP(mul, MUL_MIN, MUL_MAX); - } -#elif AVG==2 - avg = 0.0; - totallen = 0; - - for (i = 0; i < NSAMPLES; ++i) { - avg += mem[i].avg * (float) mem[i].len; - totallen += mem[i].len; - } - - if (totallen > MIN_SAMPLE_SIZE) { - avg /= (float) totallen; - if (avg >= SIL_S16) { - mul = (float) MID_S16 / avg; - CLAMP(mul, MUL_MIN, MUL_MAX); - } - } -#endif - - // Scale & clamp the samples - for (i = 0; i < len ; ++i) { - tmp = mul * data[i]; - CLAMP(tmp, MIN_S16, MAX_S16); - data[i] = tmp; - } - - // Evaluation of newavg (not 100% accurate because of values clamping) - newavg = mul * curavg; - - // Stores computed values for future smoothing -#if AVG==1 - lastavg = (1.0 - SMOOTH_LASTAVG) * lastavg + SMOOTH_LASTAVG * newavg; - //printf("\rmul=%02.1f ", mul); -#elif AVG==2 - mem[idx].len = len; - mem[idx].avg = newavg; - idx = (idx + 1) % NSAMPLES; - //printf("\rmul=%02.1f (%04dKiB) ", mul, totallen/1024); -#endif - //fflush(stdout); - - break; - } - default: - return 0; - } - return 1; - -} -
--- a/libao2/pl_volume.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,166 +0,0 @@ -/* This audio output plugin changes the volume of the sound, and can - be used when the mixer doesn't support the PCM channel. The volume - is set in fixed steps between 0 - 2^8. */ - -#define PLUGIN - -// Some limits -#define MIN_S16 -32650 -#define MAX_S16 32650 -#define MIN_U8 0 -#define MAX_U8 255 -#define MIN_S8 -128 -#define MAX_S8 127 - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <inttypes.h> - -#include "audio_out.h" -#include "audio_plugin.h" -#include "audio_plugin_internal.h" -#include "libaf/af_format.h" - -static ao_info_t info = -{ - "Volume control audio plugin", - "volume", - "Anders", - "" -}; - -LIBAO_PLUGIN_EXTERN(volume) - -// local data -typedef struct pl_volume_s -{ - uint16_t volume; // output volume level - int inuse; // This plugin is in use TRUE, FALSE - int format; // sample fomat -} pl_volume_t; - -static pl_volume_t pl_volume={0,0,0}; - -// to set/get/query special features/parameters -static int control(int cmd,void *arg){ - switch(cmd){ - case AOCONTROL_PLUGIN_SET_LEN: - return CONTROL_OK; - case AOCONTROL_GET_VOLUME:{ - if(pl_volume.inuse){ - ((ao_control_vol_t *)arg)->right=((float)pl_volume.volume)/2.55; - ((ao_control_vol_t *)arg)->left=((float)pl_volume.volume)/2.55; - return CONTROL_OK; - } - else - return CONTROL_ERROR; - } - case AOCONTROL_SET_VOLUME:{ - if(pl_volume.inuse){ - // Calculate avarage between left and right - float vol =2.55*((((ao_control_vol_t *)arg)->right)+(((ao_control_vol_t *)arg)->left))/2; - pl_volume.volume=(uint16_t)vol; - // Volume must be between 0 and 255 - if(vol > 255) - pl_volume.volume = 0xFF; - if(vol < 0) - pl_volume.volume = 0; - return CONTROL_OK; - } - else - return CONTROL_ERROR; - } - } - return CONTROL_UNKNOWN; -} - -// open & setup audio device -// return: 1=success 0=fail -static int init(){ - // Sanity sheck this plugin supports AFMT_U8 and AFMT_S16_LE - switch(ao_plugin_data.format){ - case(AF_FORMAT_U8): - case(AF_FORMAT_S16_NE): - break; - default: - fprintf(stderr,"[pl_volume] Audio format not yet suported \n"); - return 0; - } - // Initialize volume to this value - pl_volume.volume=ao_plugin_cfg.pl_volume_volume; - pl_volume.format=ao_plugin_data.format; - /* The inuse flag is used in control to detremine if the return - value since that function always is called from ao_plugin regardless - of wether this plugin is in use or not. */ - pl_volume.inuse=1; - // Tell the world what we are up to - printf("[pl_volume] Software volume control in use%s.\n",ao_plugin_cfg.pl_volume_softclip?", soft clipping enabled":""); - return 1; -} - -// close plugin -static void uninit(){ - pl_volume.inuse=0; -} - -// empty buffers -static void reset(){ -} - -#define SIGN(x) (x>0?1:-1) -// processes 'ao_plugin_data.len' bytes of 'data' -// called for every block of data -static int play(){ - register int i=0; - register int vol=pl_volume.volume; // Logarithmic control sounds more natural - vol=(vol*vol*vol)>>12; - // Change the volume. - switch(pl_volume.format){ - case(AF_FORMAT_U8):{ - register uint8_t* data=(uint8_t*)ao_plugin_data.data; - register int x; - for(i=0;i<ao_plugin_data.len;i++){ - x=((data[i]-128) * vol) >> 8; - if(x>MAX_S8) - data[i]=MAX_U8; - else if(x<MIN_S8) - data[i]=MIN_U8; - else{ - if(ao_plugin_cfg.pl_volume_softclip) - data[i] = ((3*x - ((x*x*x) >> 14)) >> 1) + 128; - else - data[i] = x + 128; - } - } - break; - } - case(AF_FORMAT_S16_NE):{ - register int len=ao_plugin_data.len>>1; - register int16_t* data=(int16_t*)ao_plugin_data.data; - register int x; - for(i=0;i<len;i++){ - x=(data[i] * vol) >> 8; - if(x>MAX_S16) - data[i]=MAX_S16; - else if(x<MIN_S16) - data[i]=MIN_S16; - else{ - if(ao_plugin_cfg.pl_volume_softclip){ - int64_t t=x*x; - t=(t*x) >> 30; - data[i] = (3*x - (int)t) >> 1; - //data[i] = 2*x - SIGN(x)*((x*x)>>15); - } - else - data[i] = x; - } - } - break; - } - default: - return 0; - } - return 1; - -}
--- a/libao2/remez.c Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,711 +0,0 @@ -/************************************************************************** - * Parks-McClellan algorithm for FIR filter design (C version) - *------------------------------------------------- - * Copyright (c) 1995,1998 Jake Janovetz (janovetz@uiuc.edu) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - *************************************************************************/ - - -#include "config.h" -#include "remez.h" - -#include <stdio.h> -#ifdef HAVE_MALLOC_H -#include <malloc.h> -#endif -#include <stdlib.h> -#include <math.h> - -/******************* - * CreateDenseGrid - *================= - * Creates the dense grid of frequencies from the specified bands. - * Also creates the Desired Frequency Response function (D[]) and - * the Weight function (W[]) on that dense grid - * - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coefficients - * int numtaps - Number of taps in the resulting filter - * int numband - Number of bands in user specification - * double bands[] - User-specified band edges [2*numband] - * double des[] - Desired response per band [numband] - * double weight[] - Weight per band [numband] - * int symmetry - Symmetry of filter - used for grid check - * - * OUTPUT: - * ------- - * int gridsize - Number of elements in the dense frequency grid - * double Grid[] - Frequencies (0 to 0.5) on the dense grid [gridsize] - * double D[] - Desired response on the dense grid [gridsize] - * double W[] - Weight function on the dense grid [gridsize] - *******************/ - -void CreateDenseGrid(int r, int numtaps, int numband, double bands[], - double des[], double weight[], int *gridsize, - double Grid[], double D[], double W[], - int symmetry) -{ - int i, j, k, band; - double delf, lowf, highf; - - delf = 0.5/(GRIDDENSITY*r); - -/* - * For differentiator, hilbert, - * symmetry is odd and Grid[0] = max(delf, band[0]) - */ - - if ((symmetry == NEGATIVE) && (delf > bands[0])) - bands[0] = delf; - - j=0; - for (band=0; band < numband; band++) - { - Grid[j] = bands[2*band]; - lowf = bands[2*band]; - highf = bands[2*band + 1]; - k = (int)((highf - lowf)/delf + 0.5); /* .5 for rounding */ - for (i=0; i<k; i++) - { - D[j] = des[band]; - W[j] = weight[band]; - Grid[j] = lowf; - lowf += delf; - j++; - } - Grid[j-1] = highf; - } - -/* - * Similar to above, if odd symmetry, last grid point can't be .5 - * - but, if there are even taps, leave the last grid point at .5 - */ - if ((symmetry == NEGATIVE) && - (Grid[*gridsize-1] > (0.5 - delf)) && - (numtaps % 2)) - { - Grid[*gridsize-1] = 0.5-delf; - } -} - - -/******************** - * InitialGuess - *============== - * Places Extremal Frequencies evenly throughout the dense grid. - * - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coefficients - * int gridsize - Number of elements in the dense frequency grid - * - * OUTPUT: - * ------- - * int Ext[] - Extremal indexes to dense frequency grid [r+1] - ********************/ - -void InitialGuess(int r, int Ext[], int gridsize) -{ - int i; - - for (i=0; i<=r; i++) - Ext[i] = i * (gridsize-1) / r; -} - - -/*********************** - * CalcParms - *=========== - * - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coefficients - * int Ext[] - Extremal indexes to dense frequency grid [r+1] - * double Grid[] - Frequencies (0 to 0.5) on the dense grid [gridsize] - * double D[] - Desired response on the dense grid [gridsize] - * double W[] - Weight function on the dense grid [gridsize] - * - * OUTPUT: - * ------- - * double ad[] - 'b' in Oppenheim & Schafer [r+1] - * double x[] - [r+1] - * double y[] - 'C' in Oppenheim & Schafer [r+1] - ***********************/ - -void CalcParms(int r, int Ext[], double Grid[], double D[], double W[], - double ad[], double x[], double y[]) -{ - int i, j, k, ld; - double sign, xi, delta, denom, numer; - -/* - * Find x[] - */ - for (i=0; i<=r; i++) - x[i] = cos(Pi2 * Grid[Ext[i]]); - -/* - * Calculate ad[] - Oppenheim & Schafer eq 7.132 - */ - ld = (r-1)/15 + 1; /* Skips around to avoid round errors */ - for (i=0; i<=r; i++) - { - denom = 1.0; - xi = x[i]; - for (j=0; j<ld; j++) - { - for (k=j; k<=r; k+=ld) - if (k != i) - denom *= 2.0*(xi - x[k]); - } - if (fabs(denom)<0.00001) - denom = 0.00001; - ad[i] = 1.0/denom; - } - -/* - * Calculate delta - Oppenheim & Schafer eq 7.131 - */ - numer = denom = 0; - sign = 1; - for (i=0; i<=r; i++) - { - numer += ad[i] * D[Ext[i]]; - denom += sign * ad[i]/W[Ext[i]]; - sign = -sign; - } - delta = numer/denom; - sign = 1; - -/* - * Calculate y[] - Oppenheim & Schafer eq 7.133b - */ - for (i=0; i<=r; i++) - { - y[i] = D[Ext[i]] - sign * delta/W[Ext[i]]; - sign = -sign; - } -} - - -/********************* - * ComputeA - *========== - * Using values calculated in CalcParms, ComputeA calculates the - * actual filter response at a given frequency (freq). Uses - * eq 7.133a from Oppenheim & Schafer. - * - * - * INPUT: - * ------ - * double freq - Frequency (0 to 0.5) at which to calculate A - * int r - 1/2 the number of filter coefficients - * double ad[] - 'b' in Oppenheim & Schafer [r+1] - * double x[] - [r+1] - * double y[] - 'C' in Oppenheim & Schafer [r+1] - * - * OUTPUT: - * ------- - * Returns double value of A[freq] - *********************/ - -double ComputeA(double freq, int r, double ad[], double x[], double y[]) -{ - int i; - double xc, c, denom, numer; - - denom = numer = 0; - xc = cos(Pi2 * freq); - for (i=0; i<=r; i++) - { - c = xc - x[i]; - if (fabs(c) < 1.0e-7) - { - numer = y[i]; - denom = 1; - break; - } - c = ad[i]/c; - denom += c; - numer += c*y[i]; - } - return numer/denom; -} - - -/************************ - * CalcError - *=========== - * Calculates the Error function from the desired frequency response - * on the dense grid (D[]), the weight function on the dense grid (W[]), - * and the present response calculation (A[]) - * - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coefficients - * double ad[] - [r+1] - * double x[] - [r+1] - * double y[] - [r+1] - * int gridsize - Number of elements in the dense frequency grid - * double Grid[] - Frequencies on the dense grid [gridsize] - * double D[] - Desired response on the dense grid [gridsize] - * double W[] - Weight function on the desnse grid [gridsize] - * - * OUTPUT: - * ------- - * double E[] - Error function on dense grid [gridsize] - ************************/ - -void CalcError(int r, double ad[], double x[], double y[], - int gridsize, double Grid[], - double D[], double W[], double E[]) -{ - int i; - double A; - - for (i=0; i<gridsize; i++) - { - A = ComputeA(Grid[i], r, ad, x, y); - E[i] = W[i] * (D[i] - A); - } -} - -/************************ - * Search - *======== - * Searches for the maxima/minima of the error curve. If more than - * r+1 extrema are found, it uses the following heuristic (thanks - * Chris Hanson): - * 1) Adjacent non-alternating extrema deleted first. - * 2) If there are more than one excess extrema, delete the - * one with the smallest error. This will create a non-alternation - * condition that is fixed by 1). - * 3) If there is exactly one excess extremum, delete the smaller - * of the first/last extremum - * - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coefficients - * int Ext[] - Indexes to Grid[] of extremal frequencies [r+1] - * int gridsize - Number of elements in the dense frequency grid - * double E[] - Array of error values. [gridsize] - * OUTPUT: - * ------- - * int Ext[] - New indexes to extremal frequencies [r+1] - ************************/ - -void Search(int r, int Ext[], - int gridsize, double E[]) -{ - int i, j, k, l, extra; /* Counters */ - int up, alt; - int *foundExt; /* Array of found extremals */ - -/* - * Allocate enough space for found extremals. - */ - foundExt = (int *)malloc((2*r) * sizeof(int)); - k = 0; - -/* - * Check for extremum at 0. - */ - if (((E[0]>0.0) && (E[0]>E[1])) || - ((E[0]<0.0) && (E[0]<E[1]))) - foundExt[k++] = 0; - -/* - * Check for extrema inside dense grid - */ - for (i=1; i<gridsize-1; i++) - { - if (((E[i]>=E[i-1]) && (E[i]>E[i+1]) && (E[i]>0.0)) || - ((E[i]<=E[i-1]) && (E[i]<E[i+1]) && (E[i]<0.0))) - foundExt[k++] = i; - } - -/* - * Check for extremum at 0.5 - */ - j = gridsize-1; - if (((E[j]>0.0) && (E[j]>E[j-1])) || - ((E[j]<0.0) && (E[j]<E[j-1]))) - foundExt[k++] = j; - - -/* - * Remove extra extremals - */ - extra = k - (r+1); - - while (extra > 0) - { - if (E[foundExt[0]] > 0.0) - up = 1; /* first one is a maxima */ - else - up = 0; /* first one is a minima */ - - l=0; - alt = 1; - for (j=1; j<k; j++) - { - if (fabs(E[foundExt[j]]) < fabs(E[foundExt[l]])) - l = j; /* new smallest error. */ - if ((up) && (E[foundExt[j]] < 0.0)) - up = 0; /* switch to a minima */ - else if ((!up) && (E[foundExt[j]] > 0.0)) - up = 1; /* switch to a maxima */ - else - { - alt = 0; - break; /* Ooops, found two non-alternating */ - } /* extrema. Delete smallest of them */ - } /* if the loop finishes, all extrema are alternating */ - -/* - * If there's only one extremal and all are alternating, - * delete the smallest of the first/last extremals. - */ - if ((alt) && (extra == 1)) - { - if (fabs(E[foundExt[k-1]]) < fabs(E[foundExt[0]])) - l = foundExt[k-1]; /* Delete last extremal */ - else - l = foundExt[0]; /* Delete first extremal */ - } - - for (j=l; j<k; j++) /* Loop that does the deletion */ - { - foundExt[j] = foundExt[j+1]; - } - k--; - extra--; - } - - for (i=0; i<=r; i++) - { - Ext[i] = foundExt[i]; /* Copy found extremals to Ext[] */ - } - - free(foundExt); -} - - -/********************* - * FreqSample - *============ - * Simple frequency sampling algorithm to determine the impulse - * response h[] from A's found in ComputeA - * - * - * INPUT: - * ------ - * int N - Number of filter coefficients - * double A[] - Sample points of desired response [N/2] - * int symmetry - Symmetry of desired filter - * - * OUTPUT: - * ------- - * double h[] - Impulse Response of final filter [N] - *********************/ -void FreqSample(int N, double A[], double h[], int symm) -{ - int n, k; - double x, val, M; - - M = (N-1.0)/2.0; - if (symm == POSITIVE) - { - if (N%2) - { - for (n=0; n<N; n++) - { - val = A[0]; - x = Pi2 * (n - M)/N; - for (k=1; k<=M; k++) - val += 2.0 * A[k] * cos(x*k); - h[n] = val/N; - } - } - else - { - for (n=0; n<N; n++) - { - val = A[0]; - x = Pi2 * (n - M)/N; - for (k=1; k<=(N/2-1); k++) - val += 2.0 * A[k] * cos(x*k); - h[n] = val/N; - } - } - } - else - { - if (N%2) - { - for (n=0; n<N; n++) - { - val = 0; - x = Pi2 * (n - M)/N; - for (k=1; k<=M; k++) - val += 2.0 * A[k] * sin(x*k); - h[n] = val/N; - } - } - else - { - for (n=0; n<N; n++) - { - val = A[N/2] * sin(Pi * (n - M)); - x = Pi2 * (n - M)/N; - for (k=1; k<=(N/2-1); k++) - val += 2.0 * A[k] * sin(x*k); - h[n] = val/N; - } - } - } -} - -/******************* - * isDone - *======== - * Checks to see if the error function is small enough to consider - * the result to have converged. - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coeffiecients - * int Ext[] - Indexes to extremal frequencies [r+1] - * double E[] - Error function on the dense grid [gridsize] - * - * OUTPUT: - * ------- - * Returns 1 if the result converged - * Returns 0 if the result has not converged - ********************/ - -short isDone(int r, int Ext[], double E[]) -{ - int i; - double min, max, current; - - min = max = fabs(E[Ext[0]]); - for (i=1; i<=r; i++) - { - current = fabs(E[Ext[i]]); - if (current < min) - min = current; - if (current > max) - max = current; - } - if (((max-min)/max) < 0.0001) - return 1; - return 0; -} - -/******************** - * remez - *======= - * Calculates the optimal (in the Chebyshev/minimax sense) - * FIR filter impulse response given a set of band edges, - * the desired reponse on those bands, and the weight given to - * the error in those bands. - * - * INPUT: - * ------ - * int numtaps - Number of filter coefficients - * int numband - Number of bands in filter specification - * double bands[] - User-specified band edges [2 * numband] - * double des[] - User-specified band responses [numband] - * double weight[] - User-specified error weights [numband] - * int type - Type of filter - * - * OUTPUT: - * ------- - * double h[] - Impulse response of final filter [numtaps] - ********************/ - -void remez(double h[], int numtaps, - int numband, double bands[], double des[], double weight[], - int type) -{ - double *Grid, *W, *D, *E; - int i, iter, gridsize, r, *Ext; - double *taps, c; - double *x, *y, *ad; - int symmetry; - - if (type == BANDPASS) - symmetry = POSITIVE; - else - symmetry = NEGATIVE; - - r = numtaps/2; /* number of extrema */ - if ((numtaps%2) && (symmetry == POSITIVE)) - r++; - -/* - * Predict dense grid size in advance for memory allocation - * .5 is so we round up, not truncate - */ - gridsize = 0; - for (i=0; i<numband; i++) - { - gridsize += (int)(2*r*GRIDDENSITY*(bands[2*i+1] - bands[2*i]) + .5); - } - if (symmetry == NEGATIVE) - { - gridsize--; - } - -/* - * Dynamically allocate memory for arrays with proper sizes - */ - Grid = (double *)malloc(gridsize * sizeof(double)); - D = (double *)malloc(gridsize * sizeof(double)); - W = (double *)malloc(gridsize * sizeof(double)); - E = (double *)malloc(gridsize * sizeof(double)); - Ext = (int *)malloc((r+1) * sizeof(int)); - taps = (double *)malloc((r+1) * sizeof(double)); - x = (double *)malloc((r+1) * sizeof(double)); - y = (double *)malloc((r+1) * sizeof(double)); - ad = (double *)malloc((r+1) * sizeof(double)); - -/* - * Create dense frequency grid - */ - CreateDenseGrid(r, numtaps, numband, bands, des, weight, - &gridsize, Grid, D, W, symmetry); - InitialGuess(r, Ext, gridsize); - -/* - * For Differentiator: (fix grid) - */ - if (type == DIFFERENTIATOR) - { - for (i=0; i<gridsize; i++) - { -/* D[i] = D[i]*Grid[i]; */ - if (D[i] > 0.0001) - W[i] = W[i]/Grid[i]; - } - } - -/* - * For odd or Negative symmetry filters, alter the - * D[] and W[] according to Parks McClellan - */ - if (symmetry == POSITIVE) - { - if (numtaps % 2 == 0) - { - for (i=0; i<gridsize; i++) - { - c = cos(Pi * Grid[i]); - D[i] /= c; - W[i] *= c; - } - } - } - else - { - if (numtaps % 2) - { - for (i=0; i<gridsize; i++) - { - c = sin(Pi2 * Grid[i]); - D[i] /= c; - W[i] *= c; - } - } - else - { - for (i=0; i<gridsize; i++) - { - c = sin(Pi * Grid[i]); - D[i] /= c; - W[i] *= c; - } - } - } - -/* - * Perform the Remez Exchange algorithm - */ - for (iter=0; iter<MAXITERATIONS; iter++) - { - CalcParms(r, Ext, Grid, D, W, ad, x, y); - CalcError(r, ad, x, y, gridsize, Grid, D, W, E); - Search(r, Ext, gridsize, E); - if (isDone(r, Ext, E)) - break; - } - if (iter == MAXITERATIONS) - { - printf("Reached maximum iteration count.\nResults may be bad.\n"); - } - - CalcParms(r, Ext, Grid, D, W, ad, x, y); - -/* - * Find the 'taps' of the filter for use with Frequency - * Sampling. If odd or Negative symmetry, fix the taps - * according to Parks McClellan - */ - for (i=0; i<=numtaps/2; i++) - { - if (symmetry == POSITIVE) - { - if (numtaps%2) - c = 1; - else - c = cos(Pi * (double)i/numtaps); - } - else - { - if (numtaps%2) - c = sin(Pi2 * (double)i/numtaps); - else - c = sin(Pi * (double)i/numtaps); - } - taps[i] = ComputeA((double)i/numtaps, r, ad, x, y)*c; - } - -/* - * Frequency sampling design with calculated taps - */ - FreqSample(numtaps, taps, h, symmetry); - -/* - * Delete allocated memory - */ - free(Grid); - free(W); - free(D); - free(E); - free(Ext); - free(x); - free(y); - free(ad); -} -
--- a/libao2/remez.h Thu Jan 06 10:56:52 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/************************************************************************** - * Parks-McClellan algorithm for FIR filter design (C version) - *------------------------------------------------- - * Copyright (c) 1995,1998 Jake Janovetz (janovetz@uiuc.edu) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - *************************************************************************/ -#ifndef __REMEZ_H__ -#define __REMEZ_H__ - -#define BANDPASS 1 -#define DIFFERENTIATOR 2 -#define HILBERT 3 - -#define NEGATIVE 0 -#define POSITIVE 1 - -#define Pi 3.1415926535897932 -#define Pi2 6.2831853071795865 - -#define GRIDDENSITY 16 -#define MAXITERATIONS 40 - -/* Function prototype for remez() - the only function that should need be - * called from external code - */ -void remez(double h[], int numtaps, - int numband, double bands[], double des[], double weight[], - int type); - -#endif /* __REMEZ_H__ */ -