Fix possible read past the end of the buffer when reading 0 bits.
[xiph/unicode.git] / postfish / mute.c
blob306f0eff9d9d72d377f235ae3b27cb7f980883d3
1 /*
3 * postfish
4 *
5 * Copyright (C) 2002-2005 Monty and Xiph.Org
7 * Postfish is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
12 * Postfish is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Postfish; see the file COPYING. If not, write to the
19 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <sys/types.h>
25 #include "postfish.h"
26 #include "mix.h"
27 #include "mute.h"
28 #include "window.h"
30 extern int input_ch;
31 extern sig_atomic_t *mixpanel_active;
33 typedef struct {
34 u_int32_t active_prev;
35 int active_ch;
36 int init_state;
37 float *leftwindow;
38 } mute_state;
40 static mute_state channel_state;
42 int mute_load(void){
43 memset(&channel_state,0,sizeof(channel_state));
44 channel_state.active_ch=input_ch;
45 channel_state.leftwindow=window_get(1,input_size);
46 return 0;
49 int mute_channel_muted(u_int32_t active,int i){
50 return(!(active&(1<<i)));
53 time_linkage *mute_read(time_linkage *in){
54 u_int32_t preval=0,retval=0;
55 int i,j;
57 if(!channel_state.init_state)
58 channel_state.active_prev=in->active;
60 /* the mute module is responsible for smoothly ramping audio levels
61 to/from zero and unity upon mute state change */
63 for(i=0;i<input_ch;i++)
64 if(mixpanel_active[i])
65 preval|= (1<<i);
67 /* the mute module is responsible for smoothly ramping audio levels
68 to/from zero and unity upon mute state change */
69 for(i=0;i<input_ch;i++){
70 float *x=in->data[i];
71 if(mixpanel_active[i]){
72 retval|= (1<<i);
74 if(mute_channel_muted(channel_state.active_prev,i)){
75 /* mute->active */
76 for(j=0;j<input_size;j++)
77 x[j]*=channel_state.leftwindow[j];
80 }else{
81 if(!mute_channel_muted(channel_state.active_prev,i)){
82 /* active->mute; ramp to zero and temporarily keep this
83 channel active for this frame while ramping */
85 retval|= (1<<i);
86 for(j=0;j<input_size;j++)
87 x[j]*=channel_state.leftwindow[input_size-j];
93 in->active=retval;
94 channel_state.active_prev=preval;
95 channel_state.init_state=1;
96 return(in);