shithub: aacenc

Download patch

ref: f9d8423d5bb3abb3e62b8545ea21e4feb2641def
parent: c23025129e9516b0fa58540cb8432b2e443f89c6
author: menno <menno>
date: Tue Aug 8 08:47:58 EDT 2000

Changed for multichannel support. And big cleanup

--- a/enc_tf.c
+++ b/enc_tf.c
@@ -45,7 +45,7 @@
 enum AAC_PROFILE profile = MAIN;
 enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS];
 enum WINDOW_TYPE desired_block_type[MAX_TIME_CHANNELS];
-enum WINDOW_TYPE next_desired_block_type[MAX_TIME_CHANNELS+2];
+enum WINDOW_TYPE next_desired_block_type[MAX_TIME_CHANNELS];
 
 /* Additional variables for AAC */
 int aacAllowScalefacs = 1;              /* Allow AAC scalefactors to be nonconstant */
@@ -193,6 +193,37 @@
   initrft();
 }
 
+
+#define NZEROS 10
+#define NPOLES 10
+#define GAIN   1.769346444e+01
+
+static float xv1[NZEROS+1], yv1[NPOLES+1];
+static float xv2[NZEROS+1], yv2[NPOLES+1];
+
+static double filter(double in, int ch)
+  {
+	float *xv, *yv;
+	if (ch == 0) { xv = xv1; yv = yv1; }
+	else {xv = xv2; yv = yv2; }
+      { xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8]; xv[8] = xv[9]; xv[9] = xv[10]; 
+        xv[10] = in / GAIN;
+        yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8]; yv[8] = yv[9]; yv[9] = yv[10]; 
+        yv[10] =   (xv[0] + xv[10]) + 10 * (xv[1] + xv[9]) + 45 * (xv[2] + xv[8])
+                     + 120 * (xv[3] + xv[7]) + 210 * (xv[4] + xv[6]) + 252 * xv[5]
+                     + ( -0.0031942899 * yv[0]) + ( -0.0495126652 * yv[1])
+                     + ( -0.3523340657 * yv[2]) + ( -1.5191103652 * yv[3])
+                     + ( -4.4065847179 * yv[4]) + ( -9.0160440949 * yv[5])
+                     + (-13.2344234780 * yv[6]) + (-13.8407183240 * yv[7])
+                     + ( -9.9529291465 * yv[8]) + ( -4.4996258124 * yv[9]);
+        return yv[10];
+      }
+}
+
+
+
+
+
 /*******************************************************************************
  ***
  *** Function:    EncTfFrame
@@ -251,38 +282,38 @@
     available_bitreservoir_bits += 58;
 
   {
-    /* store input data in look ahead buffer which may be necessary for the window switching decision */
-    int i;
-    int chanNum;
+	  /* store input data in look ahead buffer which may be necessary for the window switching decision */
+	  int i;
+	  int chanNum;
 
-    for (chanNum=0;chanNum<max_ch;chanNum++) {
-      if(as->use_LTP)
-	for( i=0; i<block_size_samples; i++ ) {
-	  /* temporary fix: a linear buffer for LTP containing the whole time frame */
-	  nok_tmp_DTimeSigBuf[chanNum][i] = DTimeSigBuf[chanNum][i];
-	  nok_tmp_DTimeSigBuf[chanNum][block_size_samples + i] = DTimeSigLookAheadBuf[chanNum][i];
-        }
-	for( i=0; i<block_size_samples; i++ ) {
-	  /* last frame input data are encoded now */
-	  DTimeSigBuf[chanNum][i] = DTimeSigLookAheadBuf[chanNum][i];
-	  DTimeSigLookAheadBuf[chanNum][i] = as->inputBuffer[chanNum][i];
-        } /* end for(i ..) */
-    } /* end for(chanNum ... ) */
+	  for (chanNum=0;chanNum<max_ch;chanNum++) {
+		  if(as->use_LTP)
+			  for( i=0; i<block_size_samples; i++ ) {
+				  /* temporary fix: a linear buffer for LTP containing the whole time frame */
+				  nok_tmp_DTimeSigBuf[chanNum][i] = DTimeSigBuf[chanNum][i];
+				  nok_tmp_DTimeSigBuf[chanNum][block_size_samples + i] = DTimeSigLookAheadBuf[chanNum][i];
+			  }
+			  for( i=0; i<block_size_samples; i++ ) {
+				  /* last frame input data are encoded now */
+				  DTimeSigBuf[chanNum][i] = DTimeSigLookAheadBuf[chanNum][i];
+				  DTimeSigLookAheadBuf[chanNum][i] = as->inputBuffer[chanNum][i];
+			  } /* end for(i ..) */
+	  } /* end for(chanNum ... ) */
 
-    if (as->use_MS == 1) {
-      for (chanNum=0;chanNum<2;chanNum++) {
-	if (chanNum == 0) {
-	  for(i = 0; i < block_size_samples; i++){
-	    DTimeSigLookAheadBuf[chanNum][i] = (as->inputBuffer[0][i]+as->inputBuffer[1][i])*0.5;
-          }
-        }
-        else {
-	  for(i = 0; i < block_size_samples; i++){
-	    DTimeSigLookAheadBuf[chanNum][i] = (as->inputBuffer[0][i]-as->inputBuffer[1][i])*0.5;
-          }
-        }
-      }
-    }
+	  if (as->use_MS == 1) {
+		  for (chanNum=0;chanNum<2;chanNum++) {
+			  if (chanNum == 0) {
+				  for(i = 0; i < block_size_samples; i++){
+					  DTimeSigLookAheadBuf[chanNum][i] = (as->inputBuffer[0][i]+as->inputBuffer[1][i])*0.5;
+				  }
+			  }
+			  else {
+				  for(i = 0; i < block_size_samples; i++){
+					  DTimeSigLookAheadBuf[chanNum][i] = (as->inputBuffer[0][i]-as->inputBuffer[1][i])*0.5;
+				  }
+			  }
+		  }
+	  }
   }
 
   if (fixed_stream == NULL) {
@@ -296,7 +327,7 @@
   /***********************************************************************/
   /* Determine channel elements      */
   /***********************************************************************/
-  DetermineChInfo(channelInfo,max_ch);
+  DetermineChInfo(channelInfo, max_ch);
 
   /*****************************************************************************
   *
@@ -303,29 +334,17 @@
   * psychoacoustic
   *
   *****************************************************************************/
-  {
-    int chanNum, channels;
+  EncTf_psycho_acoustic(
+	  sampling_rate,
+	  max_ch,
+	  channelInfo,
+	  DTimeSigLookAheadBuf,
+	  next_desired_block_type,
+	  as->use_MS,
+	  chpo_long,
+	  chpo_short
+	  );
 
-    if (as->use_MS == 0)
-      channels = max_ch+2;
-    else
-      channels = max_ch;
-
-    for (chanNum = 0; chanNum < channels; chanNum++) {
-
-    EncTf_psycho_acoustic(
-			  sampling_rate,
-			  chanNum,
-			  &DTimeSigLookAheadBuf[chanNum],
-			  &next_desired_block_type[chanNum],
-//			  (int)qc_select,
-//			  block_size_samples,
-			  chpo_long,
-			  chpo_short
-			  );
-    }
-  }
-
   /*****************************************************************************
   *
   * block_switch processing
@@ -334,9 +353,6 @@
   {
     int chanNum;
 	
-	if (next_desired_block_type[1] == ONLY_SHORT_WINDOW)
-		next_desired_block_type[0] = ONLY_SHORT_WINDOW;
-
     for (chanNum=0;chanNum<max_ch;chanNum++) {
     /* A few definitions:                                                      */
     /*   block_type:  Initially, the block_type used in the previous frame.    */
@@ -372,7 +388,6 @@
 //	block_type[1] = ONLY_LONG_WINDOW;
 //	block_type[0] = ONLY_SHORT_WINDOW;
 //	block_type[1] = ONLY_SHORT_WINDOW;
-  block_type[1] = block_type[0];
 
   {
     int chanNum;
@@ -496,8 +511,7 @@
 		channelInfo, block_type, quantInfo, as->use_MS, as->use_IS, max_ch);
 
   MSEnergy(spectral_line_vector, energy, chpo_long, chpo_short, sfb_width_table,
-//		channelInfo, block_type, quantInfo, as->use_MS, max_ch);
-		block_type, quantInfo, as->use_MS, max_ch);
+		channelInfo, block_type, quantInfo, as->use_MS, max_ch);
 
   {
     int chanNum;
@@ -630,8 +644,8 @@
 		     channelInfo,
 		     sfb_offset_table,
 //		     block_type,
-		     quantInfo
-//		     ,max_ch
+		     quantInfo,
+		     max_ch
                      );
     }
 
--- a/ms.c
+++ b/ms.c
@@ -47,190 +47,194 @@
 		   int numberOfChannels
 		  )
 {
-  int chanNum;
-  int sfbNum;
+	int chanNum;
+	int sfbNum;
 
-//  static int block = 0;
-  int used = 0, notused = 0;
-  int realyused = 0;
+	int used = 0, notused = 0;
+	int realyused = 0;
 
-  /* Look for channel_pair_elements */
-  for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
-    if (channelInfo[chanNum].present) {
-      if ((channelInfo[chanNum].cpe)&&(channelInfo[chanNum].ch_is_left)) {
-	int leftChan=chanNum;
-	int rightChan=channelInfo[chanNum].paired_ch;
-	channelInfo[leftChan].ms_info.is_present=0;
-	channelInfo[leftChan].common_window = 0;
+	/* Look for channel_pair_elements */
+	for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
+		if (channelInfo[chanNum].present) {
+			if ((channelInfo[chanNum].cpe)&&(channelInfo[chanNum].ch_is_left)) {
+				int leftChan=chanNum;
+				int rightChan=channelInfo[chanNum].paired_ch;
+				channelInfo[leftChan].ms_info.is_present=0;
+				channelInfo[leftChan].common_window = 0;
 
-	/* Perform MS if block_types are the same */
-	if ((block_type[leftChan]==block_type[rightChan])&&(use_ms==0)) {
-	  int numGroups;
-	  int groupIndex = 0;
-	  int maxSfb, isBand;
-	  int g,b,j;
-	  int use_ms_short;
-	  MS_Info *msInfo;
+				/* Perform MS if block_types are the same */
+				if ((block_type[leftChan]==block_type[rightChan])&&(use_ms==0)) {
+					int numGroups;
+					int groupIndex = 0;
+					int maxSfb, isBand;
+					int g,b,j;
+					int use_ms_short;
+					MS_Info *msInfo;
 
-	  numGroups = quantInfo[leftChan].num_window_groups;
-	  maxSfb = quantInfo[leftChan].max_sfb;
+					numGroups = quantInfo[leftChan].num_window_groups;
+					maxSfb = quantInfo[leftChan].max_sfb;
 
-	  /* Determine which bands should be enabled */
-	  msInfo = &(channelInfo[leftChan].ms_info);
-	  if (use_is) {
-	    isBand = (block_type[rightChan]==ONLY_SHORT_WINDOW) ? IS_MIN_BAND_S : IS_MIN_BAND_L;
-	    isBand = (isBand>maxSfb) ? maxSfb : isBand;
-	  }
-          else {
-	    isBand = maxSfb;
-          }
+					/* Determine which bands should be enabled */
+					msInfo = &(channelInfo[leftChan].ms_info);
+					if (use_is) {
+						isBand = (block_type[rightChan]==ONLY_SHORT_WINDOW) ? IS_MIN_BAND_S : IS_MIN_BAND_L;
+						isBand = (isBand>maxSfb) ? maxSfb : isBand;
+					} else {
+						isBand = maxSfb;
+					}
 
-	  for (g=0;g<numGroups;g++) {
-	    for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
-	      use_ms_short = 1;
-	      b = g*maxSfb+sfbNum;
+					for (g=0;g<numGroups;g++) {
+						for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+							use_ms_short = 1;
+							b = g*maxSfb+sfbNum;
 
-	      if (block_type[leftChan] == ONLY_SHORT_WINDOW) {
-              	for (j = groupIndex; j < quantInfo[leftChan].window_group_length[g]+groupIndex; j++) {
-		  use_ms_short = min(use_ms_short, p_chpo_short[1][j].use_ms[sfbNum]);
-                }
-	      	if (sfbNum < isBand) {
-		  msInfo->ms_used[b] = use_ms_short;
-                }
-                else {
-		  msInfo->ms_used[b] = 0;
-		  use_ms_short = 0;
-                }
+							if (block_type[leftChan] == ONLY_SHORT_WINDOW) {
+								for (j = groupIndex; j < quantInfo[leftChan].window_group_length[g]+groupIndex; j++) {
+									use_ms_short = min(use_ms_short, p_chpo_short[1][j].use_ms[sfbNum]);
+								}
+								if (sfbNum < isBand) {
+									msInfo->ms_used[b] = use_ms_short;
+								}
+								else {
+									msInfo->ms_used[b] = 0;
+									use_ms_short = 0;
+								}
 
-		if (msInfo->ms_used[b]) {
-		  realyused = 1;
-		  used++;
-		  for (j = groupIndex; j < quantInfo[leftChan].window_group_length[g]+groupIndex; j++) {
-		    p_ratio_short[0][(g*maxSfb)+sfbNum] = p_chpo_short[2][j].p_ratio[sfbNum];
-		    p_ratio_short[1][(g*maxSfb)+sfbNum] = p_chpo_short[3][j].p_ratio[sfbNum];
-		    p_chpo_short[1][j].use_ms[sfbNum] = use_ms_short;
-		  }
-                }
-                else {
-		  notused++;
-		  for (j = groupIndex; j < quantInfo[leftChan].window_group_length[g]+groupIndex; j++) {
-		    p_ratio_short[0][(g*maxSfb)+sfbNum] = p_chpo_short[0][j].p_ratio[sfbNum];
-		    p_ratio_short[1][(g*maxSfb)+sfbNum] = p_chpo_short[1][j].p_ratio[sfbNum];
-		    p_chpo_short[1][j].use_ms[sfbNum] = use_ms_short;
-                  }
-		}
-	      }
-              else {
-                if (sfbNum < isBand) {
-		  msInfo->ms_used[b] = p_chpo_long[1].use_ms[sfbNum];
-                }
-                else {
-		  msInfo->ms_used[b] = 0;
-		  p_chpo_long[1].use_ms[sfbNum] = 0;
-                }
-		if (msInfo->ms_used[b]) {
-		  realyused = 1;
-		  used++;
-		  p_ratio_long[0][sfbNum] = p_chpo_long[2].p_ratio[sfbNum];
-		  p_ratio_long[1][sfbNum] = p_chpo_long[3].p_ratio[sfbNum];
-                }
-                else {
-		  notused++;
-		  p_ratio_long[0][sfbNum] = p_chpo_long[0].p_ratio[sfbNum];
-		  p_ratio_long[1][sfbNum] = p_chpo_long[1].p_ratio[sfbNum];
-                }
-              }
-	    }
-	    groupIndex+=quantInfo[leftChan].window_group_length[g];
-          }
+								if (msInfo->ms_used[b]) {
+									realyused = 1;
+									used++;
+									for (j = groupIndex; j < quantInfo[leftChan].window_group_length[g]+groupIndex; j++) {
+										p_ratio_short[leftChan][(g*maxSfb)+sfbNum] = p_chpo_short[leftChan][j].p_ratio[sfbNum];
+										p_ratio_short[1][(g*maxSfb)+sfbNum] = p_chpo_short[1][j].p_ratio[sfbNum];
+										p_chpo_short[1][j].use_ms[sfbNum] = use_ms_short;
+									}
+								}
+								else {
+									notused++;
+									for (j = groupIndex; j < quantInfo[leftChan].window_group_length[g]+groupIndex; j++) {
+										p_ratio_short[leftChan][(g*maxSfb)+sfbNum] = p_chpo_short[leftChan][j].p_ratio[sfbNum];
+										p_ratio_short[1][(g*maxSfb)+sfbNum] = p_chpo_short[1][j].p_ratio[sfbNum];
+										p_chpo_short[1][j].use_ms[sfbNum] = use_ms_short;
+									}
+								}
+							}
+							else {
+								if (sfbNum < isBand) {
+									msInfo->ms_used[b] = p_chpo_long[1].use_ms[sfbNum];
+								}
+								else {
+									msInfo->ms_used[b] = 0;
+									p_chpo_long[1].use_ms[sfbNum] = 0;
+								}
+								if (msInfo->ms_used[b]) {
+									realyused = 1;
+									used++;
+									p_ratio_long[leftChan][sfbNum] = p_chpo_long[leftChan].p_ratio[sfbNum];
+									p_ratio_long[1][sfbNum] = p_chpo_long[1].p_ratio[sfbNum];
+								}
+								else {
+									notused++;
+									p_ratio_long[leftChan][sfbNum] = p_chpo_long[leftChan].p_ratio[sfbNum];
+									p_ratio_long[1][sfbNum] = p_chpo_long[1].p_ratio[sfbNum];
+								}
+							}
+						}
+						groupIndex+=quantInfo[leftChan].window_group_length[g];
+					}
 
-	  if (realyused) {
-	    channelInfo[leftChan].common_window = 1;  /* Use common window */
-	    channelInfo[leftChan].ms_info.is_present=1;
-          }
-        }
-        else if ((block_type[leftChan]==block_type[rightChan])&&(use_ms == 1)) {
-	  int chan;
-	  int numGroups;
-	  int groupIndex;
-	  int maxSfb;
-	  int g,b,j;
-	  MS_Info *msInfo;
+					if (realyused) {
+						channelInfo[leftChan].common_window = 1;  /* Use common window */
+						channelInfo[leftChan].ms_info.is_present=1;
+					}
+				}
+				else if ((block_type[leftChan]==block_type[rightChan])&&(use_ms == 1)) {
+					int chan;
+					int numGroups;
+					int groupIndex;
+					int maxSfb;
+					int g,b,j;
+					MS_Info *msInfo;
 
-	  channelInfo[0].ms_info.is_present = 1;
-	  channelInfo[0].common_window = 1;
+					channelInfo[leftChan].ms_info.is_present = 1;
+					channelInfo[leftChan].common_window = 1;
 
-	  for (chan = 0; chan < 2; chan++) {
-	    maxSfb = quantInfo[chan].max_sfb;
+					for (chan = 0; chan < 2; chan++) {
+						int chan2;
+						if (chan == 0) chan2 = leftChan;
+						else chan2 = rightChan;
 
-	    /* Determine which bands should be enabled */
-	    msInfo = &(channelInfo[leftChan].ms_info);
-	    numGroups = quantInfo[chan].num_window_groups;
+						maxSfb = quantInfo[chan].max_sfb;
 
-	    for (g=0;g<numGroups;g++) {
-	      for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
-	        b = g*maxSfb+sfbNum;
-	        groupIndex = 0;
+						/* Determine which bands should be enabled */
+						msInfo = &(channelInfo[leftChan].ms_info);
+						numGroups = quantInfo[chan2].num_window_groups;
 
-	        if (block_type[chan] == ONLY_SHORT_WINDOW) {
-		  msInfo->ms_used[b] = 1;
-		  for (j = groupIndex; j < quantInfo[chan].window_group_length[g]+groupIndex; j++) {
-		    p_ratio_short[chan][(g*maxSfb)+sfbNum] = p_chpo_short[chan][j].p_ratio[sfbNum];
-		    p_chpo_short[1][j].use_ms[sfbNum] = 1;
-                  }
-	        }
-                else {
-                  msInfo->ms_used[b] = 1;
-		  p_ratio_long[chan][sfbNum] = p_chpo_long[chan].p_ratio[sfbNum];
-		  p_chpo_long[1].use_ms[sfbNum] = 1;
-                }
-	      }
-//          groupIndex+=quantInfo[chan].window_group_length[g];
-            }
-       	  }
-        }
-        else {
-	  int chan;
-	  int numGroups;
-	  int groupIndex;
-	  int maxSfb;
-	  int g,b,j;
-	  MS_Info *msInfo;
+						for (g=0;g<numGroups;g++) {
+							for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+								b = g*maxSfb+sfbNum;
+								groupIndex = 0;
 
-	  for (chan = 0; chan < 2; chan++) {
-	    maxSfb = quantInfo[chan].max_sfb;
+								if (block_type[chan2] == ONLY_SHORT_WINDOW) {
+									msInfo->ms_used[b] = 1;
+									for (j = groupIndex; j < quantInfo[chan2].window_group_length[g]+groupIndex; j++) {
+										p_ratio_short[chan2][(g*maxSfb)+sfbNum] = p_chpo_short[chan2][j].p_ratio[sfbNum];
+										p_chpo_short[1][j].use_ms[sfbNum] = 1;
+									}
+								}
+								else {
+									msInfo->ms_used[b] = 1;
+									p_ratio_long[chan2][sfbNum] = p_chpo_long[chan2].p_ratio[sfbNum];
+									p_chpo_long[1].use_ms[sfbNum] = 1;
+								}
+							}
+//							groupIndex+=quantInfo[chan2].window_group_length[g];
+						}
+					}
+				}
+				else {
+					int chan;
+					int numGroups;
+					int groupIndex;
+					int maxSfb;
+					int g,b,j;
+					MS_Info *msInfo;
 
-	    /* Determine which bands should be enabled */
-	    msInfo = &(channelInfo[leftChan].ms_info);
-	    numGroups = quantInfo[chan].num_window_groups;
+					for (chan = 0; chan < 2; chan++) {
+						int chan2;
+						if (chan == 0) chan2 = leftChan;
+						else chan2 = rightChan;
 
-	    for (g=0;g<numGroups;g++) {
-	      for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
-	        b = g*maxSfb+sfbNum;
-	        groupIndex = 0;
+						maxSfb = quantInfo[chan].max_sfb;
 
-	        if (block_type[chan] == ONLY_SHORT_WINDOW) {
-                  msInfo->ms_used[b] = 0;
-		  for (j = groupIndex; j < quantInfo[chan].window_group_length[g]+groupIndex; j++) {
-		    p_ratio_short[chan][(g*maxSfb)+sfbNum] = p_chpo_short[chan][j].p_ratio[sfbNum];
-		    p_chpo_short[1][j].use_ms[sfbNum] = 0;
-                  }
-                }
-                else {
-                  msInfo->ms_used[b] = 0;
-		  p_ratio_long[chan][sfbNum] = p_chpo_long[chan].p_ratio[sfbNum];
-		  p_chpo_long[1].use_ms[sfbNum] = 0;
-                }
-              }
-//	      groupIndex+=quantInfo[chan].window_group_length[g];
-            }
-          }
-        }
-      }
-    }
-  }
+						/* Determine which bands should be enabled */
+						msInfo = &(channelInfo[leftChan].ms_info);
+						numGroups = quantInfo[chan2].num_window_groups;
 
-//	printf("%d used: %d, notused: %d\n", block++, used, notused);
+						for (g=0;g<numGroups;g++) {
+							for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+								b = g*maxSfb+sfbNum;
+								groupIndex = 0;
+
+								if (block_type[chan2] == ONLY_SHORT_WINDOW) {
+									msInfo->ms_used[b] = 0;
+									for (j = groupIndex; j < quantInfo[chan].window_group_length[g]+groupIndex; j++) {
+										p_ratio_short[chan2][(g*maxSfb)+sfbNum] = p_chpo_short[chan2][j].p_ratio[sfbNum];
+										p_chpo_short[1][j].use_ms[sfbNum] = 0;
+									}
+								}
+								else {
+									msInfo->ms_used[b] = 0;
+									p_ratio_long[chan2][sfbNum] = p_chpo_long[chan2].p_ratio[sfbNum];
+									p_chpo_long[1].use_ms[sfbNum] = 0;
+								}
+							}
+//							groupIndex+=quantInfo[chan2].window_group_length[g];
+						}
+					}
+				}
+			}
+		}
+	}
 }
 
 void MSEnergy(double *spectral_line_vector[MAX_TIME_CHANNELS],
@@ -238,7 +242,7 @@
 	      CH_PSYCH_OUTPUT_LONG p_chpo_long[],
 	      CH_PSYCH_OUTPUT_SHORT p_chpo_short[][MAX_SHORT_WINDOWS],
 	      int sfb_width_table[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS],
-//	      Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+	      Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
 	      enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
 	      AACQuantInfo* quantInfo,               /* Quant info */
 	      int use_ms,
@@ -245,52 +249,91 @@
 	      int numberOfChannels
 	      )
 {
-  int chanNum, numWindows, bandNumber;
-  int windowLength, w, j;
-  int *p_use_ms;
+	int chanNum, numWindows, bandNumber;
+	int windowLength, w, j;
+	int *p_use_ms;
+	double dtmp;
 
-  for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
-    double dtmp;
+	for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
+		if (channelInfo[chanNum].present) {
+			if ((channelInfo[chanNum].cpe)&&(channelInfo[chanNum].ch_is_left)) {
+				int leftChan = chanNum;
+				int rightChan = channelInfo[chanNum].paired_ch;
 
-    /* Compute energy in each scalefactor band of each window */
-    numWindows = (block_type[chanNum]==ONLY_SHORT_WINDOW) ?	8 : 1;
-    windowLength = 1024/8;
-    bandNumber=0;
-    for (w=0;w<numWindows;w++) {
-      int offset=0;
-      int sfb;
+				/* Compute energy in each scalefactor band of each window */
+				numWindows = (block_type[chanNum]==ONLY_SHORT_WINDOW) ?	8 : 1;
+				windowLength = 1024/8;
+				bandNumber=0;
+				for (w=0;w<numWindows;w++) {
+					int offset=0;
+					int sfb;
 
-      if (block_type[chanNum] == ONLY_SHORT_WINDOW) {
-	p_use_ms = p_chpo_short[1][w].use_ms;
-      }
-      else {
-	p_use_ms = p_chpo_long[1].use_ms;
-      }
+					if (block_type[chanNum] == ONLY_SHORT_WINDOW) {
+						p_use_ms = p_chpo_short[1][w].use_ms;
+					}
+					else {
+						p_use_ms = p_chpo_long[1].use_ms;
+					}
 
-      j = w*windowLength;
+					j = w*windowLength;
 
-      /* Only compute energy up to max_sfb */
-      for(sfb=0; sfb< quantInfo[chanNum].max_sfb; sfb++ ) {
-	/* calculate scale factor band energy */
-	int width,i;
-	energy[chanNum][bandNumber] = 0.0;
-	width=sfb_width_table[chanNum][sfb];
-	for(i=offset; i<(offset+width); i++ ) {
-	  if (((p_use_ms[sfb]||(use_ms==1)) && (chanNum == 0))&&(use_ms!=-1))
-	    dtmp = (spectral_line_vector[0][j]+spectral_line_vector[1][j])*0.5;
-	  else if (((p_use_ms[sfb]||(use_ms==1)) && (chanNum == 1))&&(use_ms!=-1))
-	    dtmp = (spectral_line_vector[0][j]-spectral_line_vector[1][j])*0.5;
-	  else
-	    dtmp = spectral_line_vector[chanNum][j];
-	  j++;
-	  energy[chanNum][bandNumber] += dtmp*dtmp;
-        }
-	energy[chanNum][bandNumber] = energy[chanNum][bandNumber] / width;
-	bandNumber++;
-	offset+=width;
-      }
-    }
-  }  /* for (chanNum... */
+					/* Only compute energy up to max_sfb */
+					for(sfb=0; sfb< quantInfo[chanNum].max_sfb; sfb++ ) {
+						/* calculate scale factor band energy */
+						int width,i;
+						energy[chanNum][bandNumber] = 0.0;
+						width=sfb_width_table[chanNum][sfb];
+						for(i=offset; i<(offset+width); i++ ) {
+							if ((p_use_ms[sfb]||(use_ms==1))&&(use_ms!=-1)) {
+								dtmp = (spectral_line_vector[leftChan][j]+spectral_line_vector[rightChan][j])*0.5;
+								energy[leftChan][bandNumber] += dtmp*dtmp;
+								dtmp = (spectral_line_vector[0][j]-spectral_line_vector[1][j])*0.5;
+								energy[rightChan][bandNumber] += dtmp*dtmp;
+							} else {
+								dtmp = spectral_line_vector[leftChan][j];
+								energy[leftChan][bandNumber] += dtmp*dtmp;
+								dtmp = spectral_line_vector[rightChan][j];
+								energy[rightChan][bandNumber] += dtmp*dtmp;
+							}
+							j++;
+						}
+						energy[leftChan][bandNumber] = energy[leftChan][bandNumber] / width;
+						energy[rightChan][bandNumber] = energy[rightChan][bandNumber] / width;
+						bandNumber++;
+						offset+=width;
+					}
+				}
+			} else { /* SCE or LFE */
+
+				/* Compute energy in each scalefactor band of each window */
+				numWindows = (block_type[chanNum]==ONLY_SHORT_WINDOW) ?	8 : 1;
+				windowLength = 1024/8;
+				bandNumber=0;
+				for (w=0;w<numWindows;w++) {
+					int offset=0;
+					int sfb;
+
+					j = w*windowLength;
+
+					/* Only compute energy up to max_sfb */
+					for(sfb = 0; sfb < quantInfo[chanNum].max_sfb; sfb++ ) {
+						/* calculate scale factor band energy */
+						int width, i;
+						energy[chanNum][bandNumber] = 0.0;
+						width=sfb_width_table[chanNum][sfb];
+						for(i=offset; i<(offset+width); i++ ) {
+							dtmp = spectral_line_vector[chanNum][j];
+							energy[chanNum][bandNumber] += dtmp*dtmp;
+							j++;
+						}
+						energy[chanNum][bandNumber] = energy[chanNum][bandNumber] / width;
+						bandNumber++;
+						offset+=width;
+					}
+				}
+			}
+		}
+	}  /* for (chanNum... */
 }
 
 /* Perform MS encoding.  Spectrum is non-interleaved.  */
@@ -302,73 +345,71 @@
 	      AACQuantInfo* quantInfo,               /* Quant info */
 	      int numberOfChannels)                  /* Number of channels */
 {
-  int chanNum;
-  int sfbNum;
-  int lineNum;
-  double sum,diff;
+	int chanNum;
+	int sfbNum;
+	int lineNum;
+	double sum,diff;
 
-  /* Look for channel_pair_elements */
-  for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
-    if (channelInfo[chanNum].present) {
-      if ((channelInfo[chanNum].cpe)&&(channelInfo[chanNum].ch_is_left)) {
-	int leftChan=chanNum;
-	int rightChan=channelInfo[chanNum].paired_ch;
-	channelInfo[leftChan].ms_info.is_present=0;
+	/* Look for channel_pair_elements */
+	for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
+		if (channelInfo[chanNum].present) {
+			if ((channelInfo[chanNum].cpe)&&(channelInfo[chanNum].ch_is_left)) {
+				int leftChan=chanNum;
+				int rightChan=channelInfo[chanNum].paired_ch;
+				channelInfo[leftChan].ms_info.is_present=0;
 
-	/* Perform MS if block_types are the same */
-	if (block_type[leftChan]==block_type[rightChan]) {
-          int numGroups;
-	  int maxSfb;
-	  int g,b,w,line_offset;
-	  int startWindow,stopWindow;
-	  IS_Info *isInfo;
-	  MS_Info *msInfo;
+				/* Perform MS if block_types are the same */
+				if (block_type[leftChan]==block_type[rightChan]) {
+					int numGroups;
+					int maxSfb;
+					int g,b,w,line_offset;
+					int startWindow,stopWindow;
+					IS_Info *isInfo;
+					MS_Info *msInfo;
 
-	  channelInfo[leftChan].common_window = 1;  /* Use common window */
-	  channelInfo[leftChan].ms_info.is_present=1;
-//        w = 0;
+					channelInfo[leftChan].common_window = 1;  /* Use common window */
+					channelInfo[leftChan].ms_info.is_present=1;
 
-	  numGroups = quantInfo[leftChan].num_window_groups;
-	  maxSfb = quantInfo[leftChan].max_sfb;
+					numGroups = quantInfo[leftChan].num_window_groups;
+					maxSfb = quantInfo[leftChan].max_sfb;
 
-	  /* Determine which bands should be enabled */
-	  /* Right now, simply enable bands which do not use intensity stereo */
-	  isInfo = &(channelInfo[rightChan].is_info);
-	  msInfo = &(channelInfo[leftChan].ms_info);
-	  for (g=0;g<numGroups;g++) {
-	    for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
-	      b = g*maxSfb+sfbNum;
-	      msInfo->ms_used[b] = ( (!isInfo->is_used[b])||(!isInfo->is_present) );
-            }
-          }
+					/* Determine which bands should be enabled */
+					/* Right now, simply enable bands which do not use intensity stereo */
+					isInfo = &(channelInfo[rightChan].is_info);
+					msInfo = &(channelInfo[leftChan].ms_info);
+					for (g=0;g<numGroups;g++) {
+						for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+							b = g*maxSfb+sfbNum;
+							msInfo->ms_used[b] = ( (!isInfo->is_used[b])||(!isInfo->is_present) );
+						}
+					}
 
-	  /* Perform sum and differencing on bands in which ms_used flag */
-	  /* has been set. */
-//	  line_offset=0;
-	  startWindow = 0;
-	  for (g=0;g<numGroups;g++) {
-	    int numWindows = quantInfo[leftChan].window_group_length[g];
-	    stopWindow = startWindow + numWindows;
-	    for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
-	      /* Enable MS mask */
-	      if (msInfo->ms_used[g*maxSfb+sfbNum]) {
-	      	for (w=startWindow;w<stopWindow;w++) {
-		  for (lineNum=sfb_offset_table[leftChan][sfbNum]; lineNum<sfb_offset_table[leftChan][sfbNum+1]; lineNum++) {
-		    line_offset = w*BLOCK_LEN_SHORT;
-		    sum=spectrum[leftChan][line_offset+lineNum]+spectrum[rightChan][line_offset+lineNum];
-		    diff=spectrum[leftChan][line_offset+lineNum]-spectrum[rightChan][line_offset+lineNum];
-		    spectrum[leftChan][line_offset+lineNum] = 0.5 * sum;
-		    spectrum[rightChan][line_offset+lineNum] = 0.5 * diff;
-                  }  /* for (lineNum... */
-                }  /* for (w=... */
-              }
-            }  /* for (sfbNum... */
-	    startWindow = stopWindow;
-          } /* for (g... */
-        }  /* if (block_type... */
-      }
-    }  /* if (channelInfo[chanNum].present */
-  }  /* for (chanNum... */
+					/* Perform sum and differencing on bands in which ms_used flag */
+					/* has been set. */
+					startWindow = 0;
+					for (g=0;g<numGroups;g++) {
+						int numWindows = quantInfo[leftChan].window_group_length[g];
+						stopWindow = startWindow + numWindows;
+						for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+							/* Enable MS mask */
+							if (msInfo->ms_used[g*maxSfb+sfbNum]) {
+								for (w=startWindow;w<stopWindow;w++) {
+									for (lineNum=sfb_offset_table[leftChan][sfbNum]; lineNum<sfb_offset_table[leftChan][sfbNum+1]; lineNum++) {
+										line_offset = w*BLOCK_LEN_SHORT;
+										sum=spectrum[leftChan][line_offset+lineNum]+spectrum[rightChan][line_offset+lineNum];
+										diff=spectrum[leftChan][line_offset+lineNum]-spectrum[rightChan][line_offset+lineNum];
+										spectrum[leftChan][line_offset+lineNum] = 0.5 * sum;
+										spectrum[rightChan][line_offset+lineNum] = 0.5 * diff;
+									}  /* for (lineNum... */
+								}  /* for (w=... */
+							}
+						}  /* for (sfbNum... */
+						startWindow = stopWindow;
+					} /* for (g... */
+				}  /* if (block_type... */
+			}
+		}  /* if (channelInfo[chanNum].present */
+	}  /* for (chanNum... */
 }
 
 /* Perform MS encoding.  Spectrum is non-interleaved.  */
@@ -377,72 +418,71 @@
 	      Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
 	      int sfb_offset_table[][MAX_SCFAC_BANDS+1],
 //	      enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
-	      AACQuantInfo* quantInfo               /* Quant info */
-//	      ,int numberOfChannels                 /* Number of channels */
+	      AACQuantInfo* quantInfo,               /* Quant info */
+	      int numberOfChannels                 /* Number of channels */
               )
 {
-  int chanNum;
-  int sfbNum;
-  int lineNum;
-  double sum,diff;
+	int chanNum;
+	int sfbNum;
+	int lineNum;
+	double sum,diff;
 
-  /* Look for channel_pair_elements */
-//for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
-    chanNum = 0;
-    if (channelInfo[0].ms_info.is_present) {
-      int leftChan=chanNum;
-      int rightChan=channelInfo[chanNum].paired_ch;
-      int numGroups;
-      int maxSfb;
-      int g,b,w,line_offset;
-      int startWindow,stopWindow;
-      IS_Info *isInfo;
-      MS_Info *msInfo;
+	/* Look for channel_pair_elements */
+	for (chanNum=0;chanNum<numberOfChannels;chanNum++) {
+		if (channelInfo[0].ms_info.is_present) {
+			if ((channelInfo[chanNum].cpe)&&(channelInfo[chanNum].ch_is_left)) {
+				int leftChan=chanNum;
+				int rightChan=channelInfo[chanNum].paired_ch;
+				int numGroups;
+				int maxSfb;
+				int g,b,w,line_offset;
+				int startWindow,stopWindow;
+				IS_Info *isInfo;
+				MS_Info *msInfo;
 
-      channelInfo[leftChan].common_window = 1;  /* Use common window */
-      channelInfo[leftChan].ms_info.is_present=1;
+				channelInfo[leftChan].common_window = 1;  /* Use common window */
+				channelInfo[leftChan].ms_info.is_present=1;
 
-      numGroups = quantInfo[leftChan].num_window_groups;
-      maxSfb = quantInfo[leftChan].max_sfb;
-//    w=0;
+				numGroups = quantInfo[leftChan].num_window_groups;
+				maxSfb = quantInfo[leftChan].max_sfb;
 
-      /* Determine which bands should be enabled */
-      /* Right now, simply enable bands which do not use intensity stereo */
-      isInfo = &(channelInfo[rightChan].is_info);
-      msInfo = &(channelInfo[leftChan].ms_info);
+				/* Determine which bands should be enabled */
+				/* Right now, simply enable bands which do not use intensity stereo */
+				isInfo = &(channelInfo[rightChan].is_info);
+				msInfo = &(channelInfo[leftChan].ms_info);
 #if 1
-      for (g=0;g<numGroups;g++) {
-	for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
-	  b = g*maxSfb+sfbNum;
-	  msInfo->ms_used[b] = (((!isInfo->is_used[b])||(!isInfo->is_present))&&msInfo->ms_used[b]);
-        }
-      }
+				for (g=0;g<numGroups;g++) {
+					for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+						b = g*maxSfb+sfbNum;
+						msInfo->ms_used[b] = (((!isInfo->is_used[b])||(!isInfo->is_present))&&msInfo->ms_used[b]);
+					}
+				}
 #endif
-      /* Perform sum and differencing on bands in which ms_used flag */
-      /* has been set. */
-//    line_offset=0;
-      startWindow = 0;
-      for (g=0;g<numGroups;g++) {
-	int numWindows = quantInfo[leftChan].window_group_length[g];
-	stopWindow = startWindow + numWindows;
-	for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
-	  /* Enable MS mask */
-	  if (msInfo->ms_used[g*maxSfb+sfbNum]) {
-	    for (w=startWindow;w<stopWindow;w++) {
-	      for (lineNum=sfb_offset_table[leftChan][sfbNum];lineNum<sfb_offset_table[leftChan][sfbNum+1];lineNum++) {
-		line_offset = w*BLOCK_LEN_SHORT;
-		sum=spectrum[leftChan][line_offset+lineNum]+spectrum[rightChan][line_offset+lineNum];
-		diff=spectrum[leftChan][line_offset+lineNum]-spectrum[rightChan][line_offset+lineNum];
-		spectrum[leftChan][line_offset+lineNum] = 0.5 * sum;
-		spectrum[rightChan][line_offset+lineNum] = 0.5 * diff;
-              }  /* for (lineNum... */
-            }  /* for (w=... */
-          }
-        }  /* for (sfbNum... */
-	startWindow = stopWindow;
-      } /* for (g... */
-    }  /* if (block_type... */
-//}  /* for (chanNum... */
+				/* Perform sum and differencing on bands in which ms_used flag */
+				/* has been set. */
+				startWindow = 0;
+				for (g=0;g<numGroups;g++) {
+					int numWindows = quantInfo[leftChan].window_group_length[g];
+					stopWindow = startWindow + numWindows;
+					for (sfbNum=0;sfbNum<maxSfb;sfbNum++) {
+						/* Enable MS mask */
+						if (msInfo->ms_used[g*maxSfb+sfbNum]) {
+							for (w=startWindow;w<stopWindow;w++) {
+								for (lineNum=sfb_offset_table[leftChan][sfbNum];lineNum<sfb_offset_table[leftChan][sfbNum+1];lineNum++) {
+									line_offset = w*BLOCK_LEN_SHORT;
+									sum=spectrum[leftChan][line_offset+lineNum]+spectrum[rightChan][line_offset+lineNum];
+									diff=spectrum[leftChan][line_offset+lineNum]-spectrum[rightChan][line_offset+lineNum];
+									spectrum[leftChan][line_offset+lineNum] = 0.5 * sum;
+									spectrum[rightChan][line_offset+lineNum] = 0.5 * diff;
+								}  /* for (lineNum... */
+							}  /* for (w=... */
+						}
+					}  /* for (sfbNum... */
+					startWindow = stopWindow;
+				} /* for (g... */
+			}
+		}
+	}  /* for (chanNum... */
 }
 
 
--- a/ms.h
+++ b/ms.h
@@ -56,7 +56,7 @@
 			  CH_PSYCH_OUTPUT_LONG p_chpo_long[],
 			  CH_PSYCH_OUTPUT_SHORT p_chpo_short[][MAX_SHORT_WINDOWS],
 			  int sfb_width_table[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS],
-//			  Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
+			  Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
 			  enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
 			  AACQuantInfo* quantInfo,               /* Quant info */
 			  int use_ms,
@@ -67,8 +67,8 @@
 	      Ch_Info *channelInfo,                  /* Pointer to Ch_Info */
 	      int sfb_offset_table[][MAX_SCFAC_BANDS+1],
 //	      enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS], /* Block type */
-	      AACQuantInfo* quantInfo
-//	      ,int numberOfChannels
+	      AACQuantInfo* quantInfo,
+	      int numberOfChannels
               );                 /* Number of channels */
 
 void MSEncode(double *spectrum[MAX_TIME_CHANNELS],   /* array of pointers to spectral data */
--- a/psych.c
+++ b/psych.c
@@ -49,13 +49,6 @@
 
 Copyright (c) 1997.
 
-
-Source file:
-
-$Id: psych.c,v 1.54 2000/05/18 13:53:20 menno Exp $
-$Id: psych.c,v 1.54 2000/05/18 13:53:20 menno Exp $
-$Id: psych.c,v 1.54 2000/05/18 13:53:20 menno Exp $
-
 **********************************************************************/
 
 /* CREATED BY :  Bernhard Grill -- August-96  */
@@ -173,7 +166,7 @@
 	{ -1 }
 };
 
-double          sample[MAX_TIME_CHANNELS+2][BLOCK_LEN_LONG*2];
+double          sample[MAX_TIME_CHANNELS*2][BLOCK_LEN_LONG*2];
                                /* sample value */
 
 FFT_TABLE_LONG    fft_tbl_long;  /* table for long fft */
@@ -182,9 +175,9 @@
 PARTITION_TABLE_SHORT    part_tbl_short;
 DYN_PART_TABLE_LONG     dyn_long;  
 DYN_PART_TABLE_SHORT    dyn_short;
-PSY_STATVARIABLE_LONG    psy_stvar_long[MAX_TIME_CHANNELS+2];
+PSY_STATVARIABLE_LONG    psy_stvar_long[MAX_TIME_CHANNELS*2];
                                /* variables for long block */
-PSY_STATVARIABLE_SHORT    psy_stvar_short[MAX_TIME_CHANNELS+2];
+PSY_STATVARIABLE_SHORT    psy_stvar_short[MAX_TIME_CHANNELS*2];
                                /* variables for short block */
 
 /* added by T. Araki (1997.10.16) end */
@@ -196,7 +189,7 @@
 	/* added by T. Araki (1997.10.16) */
 	psy_fft_table_init(&fft_tbl_long, &fft_tbl_short);
 	/* initializing fft table */
-	for (chanNum=0;chanNum<MAX_TIME_CHANNELS+2;chanNum++) {
+	for (chanNum=0;chanNum<MAX_TIME_CHANNELS*2;chanNum++) {
 		psy_calc_init(&sample[chanNum], &psy_stvar_long[chanNum], &psy_stvar_short[chanNum]);
 		/* initializing static variables */
 	}
@@ -291,7 +284,7 @@
 	part_tbl_long->len = crit_bands+1;
 //	printf("%d %d\t",part_tbl_long->len, part_tbl_long->w_high[crit_bands]);
 
-//	cbound /= 3;
+	cbands /= 3;
 	part_tbl_short->sampling_rate = (int)sampling_rate;
 	part_tbl_short->w_low[0] = 0;
 	part_tbl_short->w_high[0] = 0;
@@ -472,16 +465,16 @@
 			   /* input */
 			   double sampling_rate,
 			   int    no_of_chan,         /* no of audio channels */
+			   Ch_Info* channelInfo,
 			   double *p_time_signal[],
 			   enum WINDOW_TYPE block_type[],
-//			   int qcSelect,
-//			   int frameLength,
+			   int use_MS,
 			   /* output */
 			   CH_PSYCH_OUTPUT_LONG p_chpo_long[],
 			   CH_PSYCH_OUTPUT_SHORT p_chpo_short[][MAX_SHORT_WINDOWS]
 			   )
 {
-	int             ch, i, b;
+	int             chanNum, i;
     SR_INFO         *p_sri;
 
 	/* added by T. Araki (1997.07.10) */
@@ -488,12 +481,12 @@
 
     static int   flag = 0;
 
-    PSY_VARIABLE_LONG    psy_var_long;  /* variables for long block */
-    PSY_VARIABLE_SHORT    psy_var_short;  /* variables for short block */
+    PSY_VARIABLE_LONG    psy_var_long[4];  /* variables for long block */
+    PSY_VARIABLE_SHORT    psy_var_short[4];  /* variables for short block */
 
+
 	memset(&psy_var_long, 0, sizeof(psy_var_long));
 	memset(&psy_var_short, 0, sizeof(psy_var_short));
-	/* added by T. Araki (1997.07.10) end */
 
     p_sri = &sr_info_aac[0];
 	
@@ -509,101 +502,197 @@
 		flag = 1;
 	}
 
-	{
-		ch = 0;
-		if (no_of_chan < 2) {
-			psy_step1(p_time_signal,sample, no_of_chan);
-			psy_step2(&sample[no_of_chan], &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &fft_tbl_long, 
-				&fft_tbl_short, ch);
-//			psy_step3(&psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short, ch);
-//			psy_step4(&psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short, ch);
-			psy_step3(&psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short);
-			psy_step4(&psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short);
-		} else if (no_of_chan == 2) {
-			int w, l;
-			psy_stvar_long[2].p_fft += BLOCK_LEN_LONG;
-			if(psy_stvar_long[2].p_fft == BLOCK_LEN_LONG * 3)
-				psy_stvar_long[2].p_fft = 0;
-			psy_stvar_long[3].p_fft += BLOCK_LEN_LONG;
-			if(psy_stvar_long[3].p_fft == BLOCK_LEN_LONG * 3)
-				psy_stvar_long[3].p_fft = 0;
-			for (w = 0; w < BLOCK_LEN_LONG; w++) {
-				psy_stvar_long[2].fft_r[w+psy_stvar_long->p_fft] = (psy_stvar_long[0].fft_r[w+psy_stvar_long[0].p_fft]+psy_stvar_long[1].fft_r[w+psy_stvar_long[1].p_fft])*0.5;
-				psy_stvar_long[3].fft_r[w+psy_stvar_long->p_fft] = (psy_stvar_long[0].fft_r[w+psy_stvar_long[0].p_fft]-psy_stvar_long[1].fft_r[w+psy_stvar_long[1].p_fft])*0.5;
-			}
-			for (l = 0; l < MAX_SHORT_WINDOWS; l++) {
-				for (w = 0; w < BLOCK_LEN_SHORT; w++) {
-					psy_stvar_short[2].fft_r[l][w] = (psy_stvar_short[0].fft_r[l][w]+psy_stvar_short[1].fft_r[l][w])*0.5;
-					psy_stvar_short[3].fft_r[l][w] = (psy_stvar_short[0].fft_r[l][w]-psy_stvar_short[1].fft_r[l][w])*0.5;
+	for (chanNum = 0; chanNum < no_of_chan; chanNum++) {
+		if (channelInfo[chanNum].present) {
+			if ((channelInfo[chanNum].cpe) && (channelInfo[chanNum].ch_is_left)) { /* CPE */
+				int leftChan = chanNum;
+				int rightChan = channelInfo[chanNum].paired_ch;
+				int midChan = chanNum + MAX_TIME_CHANNELS;
+				int sideChan = chanNum + MAX_TIME_CHANNELS;
+
+				psy_step1(p_time_signal, sample, leftChan);
+				psy_step1(p_time_signal, sample, rightChan);
+
+				psy_step2(sample, &psy_stvar_long[leftChan],
+					&psy_stvar_short[leftChan],	&fft_tbl_long, &fft_tbl_short, leftChan);
+				psy_step2(sample, &psy_stvar_long[rightChan],
+					&psy_stvar_short[rightChan], &fft_tbl_long, &fft_tbl_short, rightChan);
+				if (use_MS >= 0)
+					psy_step2MS(psy_stvar_long, psy_stvar_short,
+					leftChan, rightChan, midChan, sideChan);
+
+				psy_step3(&psy_stvar_long[leftChan], &psy_stvar_short[leftChan],
+					&psy_var_long[0], &psy_var_short[0]);
+				psy_step3(&psy_stvar_long[rightChan], &psy_stvar_short[rightChan],
+					&psy_var_long[1], &psy_var_short[1]);
+
+				psy_step4(&psy_stvar_long[leftChan], &psy_stvar_short[leftChan],
+					&psy_var_long[0], &psy_var_short[0]);
+				psy_step4(&psy_stvar_long[rightChan], &psy_stvar_short[rightChan],
+					&psy_var_long[1], &psy_var_short[1]);
+				if (use_MS >= 0)
+					psy_step4MS(psy_var_long, psy_var_short, 0, 1, 2, 3);
+
+				psy_step5(&part_tbl_long, &part_tbl_short, &psy_stvar_long[leftChan], &psy_stvar_short[leftChan],
+					&psy_var_long[0], &psy_var_short[0]);
+				psy_step5(&part_tbl_long, &part_tbl_short, &psy_stvar_long[rightChan], &psy_stvar_short[rightChan],
+					&psy_var_long[1], &psy_var_short[1]);
+				if (use_MS >= 0) {
+					psy_step5(&part_tbl_long, &part_tbl_short, &psy_stvar_long[midChan], &psy_stvar_short[midChan],
+						&psy_var_long[2], &psy_var_short[2]);
+					psy_step5(&part_tbl_long, &part_tbl_short, &psy_stvar_long[sideChan], &psy_stvar_short[sideChan],
+						&psy_var_long[3], &psy_var_short[3]);
 				}
-			}
-		}
 
-		if (no_of_chan == 0) {
-			for (b = 0; b < NPART_LONG; b++)
-				psy_stvar_long[no_of_chan].save_cw[b] = psy_var_long.c[b];
-			for (i = 0; i < MAX_SHORT_WINDOWS; i++)
-				for (b = 0; b < NPART_SHORT; b++)
-					psy_stvar_short[no_of_chan].save_cw[i][b] = psy_var_short.c[i][b];
-		}
-		if (no_of_chan == 1) {
-			for (b = 0; b < NPART_LONG; b++)
-				psy_stvar_long[no_of_chan].save_cw[b] = min(psy_var_long.c[b], psy_stvar_long[0].save_cw[b]);
-			for (i = 0; i < MAX_SHORT_WINDOWS; i++)
-				for (b = 0; b < NPART_SHORT; b++)
-					psy_stvar_short[no_of_chan].save_cw[i][b] = min(psy_var_short.c[i][b], psy_stvar_short[0].save_cw[i][b]);
-		}
-		if (no_of_chan > 1) {
-			for (b = 0; b < NPART_LONG; b++)
-				psy_var_long.c[b] = psy_stvar_long[1].save_cw[b];
-			for (i = 0; i < MAX_SHORT_WINDOWS; i++)
-				for (b = 0; b < NPART_SHORT; b++)
-					psy_var_short.c[i][b] = psy_stvar_short[1].save_cw[i][b];
-		}
+				psy_step6(&part_tbl_long, &part_tbl_short, &psy_stvar_long[leftChan], &psy_stvar_short[leftChan],
+					&psy_var_long[0], &psy_var_short[0]);
+				psy_step6(&part_tbl_long, &part_tbl_short, &psy_stvar_long[rightChan], &psy_stvar_short[rightChan],
+					&psy_var_long[1], &psy_var_short[1]);
+				if (use_MS >= 0) {
+					psy_step6(&part_tbl_long, &part_tbl_short, &psy_stvar_long[midChan], &psy_stvar_short[midChan],
+						&psy_var_long[2], &psy_var_short[2]);
+					psy_step6(&part_tbl_long, &part_tbl_short, &psy_stvar_long[sideChan], &psy_stvar_short[sideChan],
+						&psy_var_long[3], &psy_var_short[3]);
+				}
 
-		psy_step5(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan],
-//			&psy_var_long, &psy_var_short, ch);
-			&psy_var_long, &psy_var_short);
-		psy_step6(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan],
-			&psy_var_long, &psy_var_short);
+				psy_step7(&part_tbl_long, &part_tbl_short, &psy_var_long[0], &psy_var_short[0]);
+				psy_step7(&part_tbl_long, &part_tbl_short, &psy_var_long[1], &psy_var_short[1]);
+				if (use_MS >= 0) {
+					psy_step7MS(psy_var_long, psy_var_short, 0, 1, 2, 3);
+				}
 
-		if (no_of_chan < 2) {
-			psy_step7(&part_tbl_long, &part_tbl_short, &psy_var_long, &psy_var_short);
-			for (b = 0; b < NPART_LONG; b++)
-				psy_stvar_long[no_of_chan].save_tb[b] = psy_var_long.tb[b];
-			for (i = 0; i < MAX_SHORT_WINDOWS; i++)
-				for (b = 0; b < NPART_SHORT; b++)
-					psy_stvar_short[no_of_chan].save_tb[i][b] = psy_var_short.tb[i][b];
-		} else {
-			for (b = 0; b < NPART_LONG; b++)
-				psy_var_long.tb[b] = psy_stvar_long[no_of_chan-2].save_tb[b];
-			for (i = 0; i < MAX_SHORT_WINDOWS; i++)
-				for (b = 0; b < NPART_SHORT; b++)
-					psy_var_short.tb[i][b] = psy_stvar_short[no_of_chan-2].save_tb[i][b];
-		}
+				psy_step8(&part_tbl_long, &part_tbl_short, &psy_var_long[0], &psy_var_short[0]);
+				psy_step8(&part_tbl_long, &part_tbl_short, &psy_var_long[1], &psy_var_short[1]);
+				if (use_MS >= 0) {
+					psy_step8(&part_tbl_long, &part_tbl_short, &psy_var_long[2], &psy_var_short[2]);
+					psy_step8(&part_tbl_long, &part_tbl_short, &psy_var_long[3], &psy_var_short[3]);
+				}
 
-		psy_step8(&part_tbl_long, &part_tbl_short, &psy_var_long, &psy_var_short);
-		psy_step9(&part_tbl_long, &part_tbl_short, &psy_var_long, &psy_var_short);
-		psy_step10(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], 
-//			&psy_var_long, &psy_var_short, ch);
-			&psy_var_long, &psy_var_short);
-		psy_step11andahalf(&part_tbl_long, &part_tbl_short, psy_stvar_long, psy_stvar_short, no_of_chan);
-//		psy_step11(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], ch);
-		psy_step11(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan]);
-		psy_step12(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan],
-			&psy_var_long, &psy_var_short/*, ch*/);
-//		psy_step12(&part_tbl_long, &psy_stvar_long[no_of_chan], &psy_var_long);
-//		psy_step13(&psy_var_long, block_type, ch);
-		psy_step13(&psy_var_long, block_type);
-		psy_step14(p_sri, &part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan],
-//			&psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short, ch);
-			&psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short);
-		psy_step15(psy_stvar_long[no_of_chan].use_ms, psy_stvar_short[no_of_chan].use_ms, p_sri, &psy_stvar_long[0], &psy_stvar_short[0], &psy_var_long, &psy_var_short, no_of_chan);
+				psy_step9(&part_tbl_long, &part_tbl_short, &psy_var_long[0], &psy_var_short[0]);
+				psy_step9(&part_tbl_long, &part_tbl_short, &psy_var_long[1], &psy_var_short[1]);
+				if (use_MS >= 0) {
+					psy_step9(&part_tbl_long, &part_tbl_short, &psy_var_long[2], &psy_var_short[2]);
+					psy_step9(&part_tbl_long, &part_tbl_short, &psy_var_long[3], &psy_var_short[3]);
+				}
+
+				psy_step10(&part_tbl_long, &part_tbl_short, &psy_stvar_long[leftChan], &psy_stvar_short[leftChan], 
+					&psy_var_long[0], &psy_var_short[0]);
+				psy_step10(&part_tbl_long, &part_tbl_short, &psy_stvar_long[rightChan], &psy_stvar_short[rightChan], 
+					&psy_var_long[1], &psy_var_short[1]);
+				if (use_MS >= 0) {
+					psy_step10(&part_tbl_long, &part_tbl_short, &psy_stvar_long[midChan], &psy_stvar_short[midChan], 
+						&psy_var_long[2], &psy_var_short[2]);
+					psy_step10(&part_tbl_long, &part_tbl_short, &psy_stvar_long[sideChan], &psy_stvar_short[sideChan], 
+						&psy_var_long[3], &psy_var_short[3]);
+
+					psy_step11MS(&part_tbl_long, &part_tbl_short, psy_stvar_long, psy_stvar_short, no_of_chan);
+				}
+
+				psy_step11(&part_tbl_long, &part_tbl_short, &psy_stvar_long[leftChan], &psy_stvar_short[leftChan]);
+				psy_step11(&part_tbl_long, &part_tbl_short, &psy_stvar_long[rightChan], &psy_stvar_short[rightChan]);
+				if (use_MS >= 0) {
+					psy_step11(&part_tbl_long, &part_tbl_short, &psy_stvar_long[midChan], &psy_stvar_short[midChan]);
+					psy_step11(&part_tbl_long, &part_tbl_short, &psy_stvar_long[sideChan], &psy_stvar_short[sideChan]);
+				}
+
+				psy_step12(&part_tbl_long, &part_tbl_short, &psy_stvar_long[leftChan], &psy_stvar_short[leftChan],
+					&psy_var_long[0], &psy_var_short[0]);
+				psy_step12(&part_tbl_long, &part_tbl_short, &psy_stvar_long[rightChan], &psy_stvar_short[rightChan],
+					&psy_var_long[1], &psy_var_short[1]);
+
+				psy_step13(&psy_var_long[0], &block_type[leftChan]);
+				if (*block_type != ONLY_SHORT_WINDOW) {
+					psy_step13(&psy_var_long[1], &block_type[rightChan]);
+					block_type[leftChan] = block_type[rightChan];
+				} else {
+					block_type[rightChan] = block_type[leftChan];
+				}
+
+				psy_step14(p_sri, &part_tbl_long, &part_tbl_short, &psy_stvar_long[leftChan],
+					&psy_stvar_short[leftChan], &psy_var_long[0], &psy_var_short[0]);
+				psy_step14(p_sri, &part_tbl_long, &part_tbl_short, &psy_stvar_long[rightChan],
+					&psy_stvar_short[rightChan], &psy_var_long[1], &psy_var_short[1]);
+				if (use_MS >= 0) {
+					psy_step14(p_sri, &part_tbl_long, &part_tbl_short, &psy_stvar_long[midChan],
+						&psy_stvar_short[midChan], &psy_var_long[2], &psy_var_short[2]);
+					psy_step14(p_sri, &part_tbl_long, &part_tbl_short, &psy_stvar_long[sideChan],
+						&psy_stvar_short[sideChan], &psy_var_long[3], &psy_var_short[3]);
+
+					psy_step15(p_sri, psy_stvar_long, psy_stvar_short,
+						psy_var_long, psy_var_short,
+						leftChan, rightChan, midChan, sideChan);
+				}
+
+				if (use_MS == 1) {
+					p_chpo_long[leftChan].p_ratio   = psy_stvar_long[midChan].ismr;
+					p_chpo_long[rightChan].p_ratio   = psy_stvar_long[sideChan].ismr;
+				} else {
+					p_chpo_long[leftChan].p_ratio   = psy_stvar_long[leftChan].ismr;
+					p_chpo_long[rightChan].p_ratio   = psy_stvar_long[rightChan].ismr;
+				}
+				p_chpo_long[leftChan].cb_width  = p_sri->cb_width_long;
+				p_chpo_long[rightChan].cb_width  = p_sri->cb_width_long;
+				p_chpo_long[leftChan].no_of_cb = p_sri->num_cb_long;
+				p_chpo_long[rightChan].no_of_cb = p_sri->num_cb_long;
+
+				memcpy(p_chpo_long[rightChan].use_ms, psy_stvar_long[rightChan].use_ms, NSFB_LONG*sizeof(int));
+
+				for( i=0; i<MAX_SHORT_WINDOWS; i++ ) {
+					if (use_MS == 1) {
+						p_chpo_short[leftChan][i].p_ratio  = psy_stvar_short[midChan].ismr[i];
+						p_chpo_short[rightChan][i].p_ratio  = psy_stvar_short[sideChan].ismr[i];
+					} else {
+						p_chpo_short[leftChan][i].p_ratio  = psy_stvar_short[leftChan].ismr[i];
+						p_chpo_short[rightChan][i].p_ratio  = psy_stvar_short[rightChan].ismr[i];
+					}
+					p_chpo_short[leftChan][i].cb_width = p_sri->cb_width_short;
+					p_chpo_short[rightChan][i].cb_width = p_sri->cb_width_short;
+					p_chpo_short[leftChan][i].no_of_cb = p_sri->num_cb_short;
+					p_chpo_short[rightChan][i].no_of_cb = p_sri->num_cb_short;
+
+					memcpy(p_chpo_short[rightChan][i].use_ms, psy_stvar_short[rightChan].use_ms[i], NSFB_SHORT*sizeof(int));
+				}
+
+			} else if (channelInfo[chanNum].lfe) { /* LFE */ /* not yet finished */
+
+			} else { /* SCE */
+
+				psy_step1(p_time_signal, sample, chanNum);
+				psy_step2(sample, &psy_stvar_long[chanNum], &psy_stvar_short[chanNum],
+					&fft_tbl_long, &fft_tbl_short, chanNum);
+				psy_step3(&psy_stvar_long[chanNum], &psy_stvar_short[chanNum], &psy_var_long[0], &psy_var_short[0]);
+				psy_step4(&psy_stvar_long[chanNum], &psy_stvar_short[chanNum], &psy_var_long[0], &psy_var_short[0]);
+				psy_step5(&part_tbl_long, &part_tbl_short, &psy_stvar_long[chanNum], &psy_stvar_short[chanNum],
+					&psy_var_long[0], &psy_var_short[0]);
+				psy_step6(&part_tbl_long, &part_tbl_short, &psy_stvar_long[chanNum], &psy_stvar_short[chanNum],
+					&psy_var_long[0], &psy_var_short[0]);
+				psy_step7(&part_tbl_long, &part_tbl_short, &psy_var_long[0], &psy_var_short[0]);
+				psy_step8(&part_tbl_long, &part_tbl_short, &psy_var_long[0], &psy_var_short[0]);
+				psy_step9(&part_tbl_long, &part_tbl_short, &psy_var_long[0], &psy_var_short[0]);
+				psy_step10(&part_tbl_long, &part_tbl_short, &psy_stvar_long[chanNum], &psy_stvar_short[chanNum], 
+					&psy_var_long[0], &psy_var_short[0]);
+				psy_step11(&part_tbl_long, &part_tbl_short, &psy_stvar_long[chanNum], &psy_stvar_short[chanNum]);
+				psy_step12(&part_tbl_long, &part_tbl_short, &psy_stvar_long[chanNum], &psy_stvar_short[chanNum],
+					&psy_var_long[0], &psy_var_short[0]);
+				psy_step13(&psy_var_long[0], &block_type[chanNum]);
+				psy_step14(p_sri, &part_tbl_long, &part_tbl_short, &psy_stvar_long[chanNum],
+					&psy_stvar_short[chanNum], &psy_var_long[0], &psy_var_short[0]);
+
+				p_chpo_long[chanNum].p_ratio   = psy_stvar_long[chanNum].ismr;
+				p_chpo_long[chanNum].cb_width  = p_sri->cb_width_long;
+				p_chpo_long[chanNum].no_of_cb = p_sri->num_cb_long;
+
+				for( i=0; i<MAX_SHORT_WINDOWS; i++ ) {
+					p_chpo_short[chanNum][i].p_ratio  = psy_stvar_short[chanNum].ismr[i];
+					p_chpo_short[chanNum][i].cb_width = p_sri->cb_width_short;
+					p_chpo_short[chanNum][i].no_of_cb = p_sri->num_cb_short;
+				}
+			}
+		}
 	}
 
-	{
-		int i;
 
+	{
 		p_chpo_long[no_of_chan].p_ratio   = psy_stvar_long[no_of_chan].ismr;
 		p_chpo_long[no_of_chan].cb_width  = p_sri->cb_width_long;
 		p_chpo_long[no_of_chan].no_of_cb = p_sri->num_cb_long;
@@ -629,7 +718,7 @@
 
 	for(i = 0; i < BLOCK_LEN_LONG; i++){
 		sample[ch][i] = sample[ch][i+BLOCK_LEN_LONG];
-		sample[ch][i+BLOCK_LEN_LONG] = p_time_signal[0][i];
+		sample[ch][i+BLOCK_LEN_LONG] = p_time_signal[ch][i];
 	}
 }
 
@@ -719,6 +808,34 @@
     }
 }
 
+
+void psy_step2MS(PSY_STATVARIABLE_LONG *psy_stvar_long,
+			PSY_STATVARIABLE_SHORT *psy_stvar_short,
+			int leftChan, int rightChan,
+			int midChan, int sideChan)
+{
+	int w, l;
+	psy_stvar_long[midChan].p_fft += BLOCK_LEN_LONG;
+	if(psy_stvar_long[midChan].p_fft == BLOCK_LEN_LONG * 3)
+		psy_stvar_long[midChan].p_fft = 0;
+
+	psy_stvar_long[sideChan].p_fft += BLOCK_LEN_LONG;
+	if(psy_stvar_long[sideChan].p_fft == BLOCK_LEN_LONG * 3)
+		psy_stvar_long[sideChan].p_fft = 0;
+
+	for (w = 0; w < BLOCK_LEN_LONG; w++) {
+		psy_stvar_long[midChan].fft_r[w+psy_stvar_long[midChan].p_fft] = (psy_stvar_long[leftChan].fft_r[w+psy_stvar_long[leftChan].p_fft]+psy_stvar_long[rightChan].fft_r[w+psy_stvar_long[rightChan].p_fft])*0.5;
+		psy_stvar_long[sideChan].fft_r[w+psy_stvar_long[sideChan].p_fft] = (psy_stvar_long[leftChan].fft_r[w+psy_stvar_long[leftChan].p_fft]-psy_stvar_long[rightChan].fft_r[w+psy_stvar_long[rightChan].p_fft])*0.5;
+	}
+	for (l = 0; l < MAX_SHORT_WINDOWS; l++) {
+		for (w = 0; w < BLOCK_LEN_SHORT; w++) {
+			psy_stvar_short[midChan].fft_r[l][w] = (psy_stvar_short[leftChan].fft_r[l][w]+psy_stvar_short[rightChan].fft_r[l][w])*0.5;
+			psy_stvar_short[sideChan].fft_r[l][w] = (psy_stvar_short[leftChan].fft_r[l][w]-psy_stvar_short[rightChan].fft_r[l][w])*0.5;
+		}
+	}
+}
+
+
 void psy_step3(PSY_STATVARIABLE_LONG *psy_stvar_long,
                PSY_STATVARIABLE_SHORT *psy_stvar_short,
                PSY_VARIABLE_LONG *psy_var_long,
@@ -828,13 +945,26 @@
 	}
 }
 
+void psy_step4MS(PSY_VARIABLE_LONG *psy_var_long,
+			PSY_VARIABLE_SHORT *psy_var_short,
+			int leftChan, int rightChan,
+			int midChan, int sideChan)
+{
+	int b, i;
+
+	for (b = 0; b < NPART_LONG; b++)
+		psy_var_long[midChan].c[b] = psy_var_long[sideChan].c[b] = min(psy_var_long[leftChan].c[b], psy_var_long[rightChan].c[b]);
+	for (i = 0; i < MAX_SHORT_WINDOWS; i++)
+		for (b = 0; b < NPART_SHORT; b++)
+			psy_var_short[midChan].c[i][b] = psy_var_short[sideChan].c[i][b] = min(psy_var_short[leftChan].c[i][b], psy_var_short[rightChan].c[i][b]);
+}
+
 void psy_step5(PARTITION_TABLE_LONG *part_tbl_long,
 			   PARTITION_TABLE_SHORT *part_tbl_short,
 			   PSY_STATVARIABLE_LONG *psy_stvar_long,
-                           PSY_STATVARIABLE_SHORT *psy_stvar_short,
+               PSY_STATVARIABLE_SHORT *psy_stvar_short,
 			   PSY_VARIABLE_LONG *psy_var_long,
 			   PSY_VARIABLE_SHORT *psy_var_short
-//			   ,int ch
 			   )
 {
     int b,w,i;
@@ -851,7 +981,7 @@
 		}
 		/* added by T. Araki (1997.10.16) end */
 
-		psy_var_long->c[b] = tmp_cb;
+		psy_var_long->cb[b] = tmp_cb;
     }
 
 	/* added by T. Araki (1997.10.16) */
@@ -865,16 +995,17 @@
 				tmp_cb += psy_sqr(psy_stvar_short->fft_r[i][w]) * psy_var_short->c[i][w];
 			}
 
-			psy_var_short->c[i][b] = tmp_cb;
+			psy_var_short->cb[i][b] = tmp_cb;
 		}
     }
 	/* added by T. Araki (1997.10.16) end */
 }
 
+
 void psy_step6(PARTITION_TABLE_LONG *part_tbl_long, 
 			   PARTITION_TABLE_SHORT *part_tbl_short, 
 			   PSY_STATVARIABLE_LONG *psy_stvar_long,
-         PSY_STATVARIABLE_SHORT *psy_stvar_short,
+               PSY_STATVARIABLE_SHORT *psy_stvar_short,
 			   PSY_VARIABLE_LONG *psy_var_long, 
 			   PSY_VARIABLE_SHORT *psy_var_short
 			   )
@@ -891,15 +1022,15 @@
 			//sprd = sprdngf(part_tbl_long, part_tbl_short, bb, b, 0);
 			sprd = part_tbl_long->dyn->spreading[bb][b];
 			ecb += psy_var_long->e[bb] * sprd;
-			ct += psy_var_long->c[bb] * sprd;
+			ct += psy_var_long->cb[bb] * sprd;
 		}
 
 		if (ecb!=0.0) {
-			psy_var_long->cb[b] = ct / ecb;
+			psy_var_long->cbb[b] = ct / ecb;
 			psy_stvar_long->en[b] = psy_var_long->en[b] = ecb
 				* part_tbl_long->dyn->rnorm[b];
 		} else {
-			psy_var_long->cb[b] = 0.0;
+			psy_var_long->cbb[b] = 0.0;
 			psy_stvar_long->en[b] = psy_var_long->en[b] = 0;
 		}
 	}
@@ -914,15 +1045,15 @@
 				//sprd = sprdngf(part_tbl_long, part_tbl_short, bb, b, 1);
 				sprd = part_tbl_short->dyn->spreading[bb][b];
 				ecb += psy_var_short->e[i][bb] * sprd;
-				ct += psy_var_short->c[i][bb] * sprd;
+				ct += psy_var_short->cb[i][bb] * sprd;
 			}
 
 			if (ecb!=0.0) {	
-				psy_var_short->cb[i][b] = ct / ecb;
+				psy_var_short->cbb[i][b] = ct / ecb;
 				psy_stvar_short->en[i][b] = psy_var_short->en[i][b] = ecb
 					* part_tbl_short->dyn->rnorm[b];
 			} else {
-				psy_var_short->cb[i][b] = 0.0;
+				psy_var_short->cbb[i][b] = 0.0;
 				psy_stvar_short->en[i][b] = psy_var_short->en[i][b] = 0;
 			}
 		}
@@ -938,8 +1069,8 @@
     int b,i;
 
     for(b = 0; b < part_tbl_long->len; b++){
-		if (psy_var_long->cb[b] > 0.0) {
-			psy_var_long->tb[b] = -0.299 - 0.43 * log(psy_var_long->cb[b]);
+		if (psy_var_long->cbb[b] > 0.0) {
+			psy_var_long->tb[b] = -0.299 - 0.43 * log(psy_var_long->cbb[b]);
 		} else {
 			psy_var_long->tb[b] = 1.0;
 		}
@@ -955,8 +1086,8 @@
 	/* added by T. Araki (1997.10.16) */
     for(i = 0;  i < MAX_SHORT_WINDOWS; i++){
         for(b = 0; b < part_tbl_short->len; b++){
-			if (psy_var_short->cb[i][b]>0.0) {
-				psy_var_short->tb[i][b] = -0.299 - 0.43 * log(psy_var_short->cb[i][b]);
+			if (psy_var_short->cbb[i][b]>0.0) {
+				psy_var_short->tb[i][b] = -0.299 - 0.43 * log(psy_var_short->cbb[i][b]);
 			} else {
 				psy_var_short->tb[i][b] = 1.0;
 			}
@@ -972,6 +1103,25 @@
 }
 
 
+void psy_step7MS(PSY_VARIABLE_LONG *psy_var_long,
+				 PSY_VARIABLE_SHORT *psy_var_short,
+				 int leftChan, int rightChan,
+				 int midChan, int sideChan)
+{
+	int b, i;
+
+	for (b = 0; b < NPART_LONG; b++) {
+		psy_var_long[midChan].tb[b] = psy_var_long[leftChan].tb[b];
+		psy_var_long[sideChan].tb[b] = psy_var_long[rightChan].tb[b];
+	}
+	for (i = 0; i < MAX_SHORT_WINDOWS; i++)
+		for (b = 0; b < NPART_SHORT; b++) {
+			psy_var_short[midChan].tb[i][b] = psy_var_short[leftChan].tb[i][b];
+			psy_var_short[sideChan].tb[i][b] = psy_var_short[rightChan].tb[i][b];
+		}
+}
+
+
 void psy_step8(PARTITION_TABLE_LONG *part_tbl_long,
 	       PARTITION_TABLE_SHORT *part_tbl_short,
 	       PSY_VARIABLE_LONG *psy_var_long, 
@@ -1017,7 +1167,6 @@
 		PSY_STATVARIABLE_SHORT *psy_stvar_short,
 		PSY_VARIABLE_LONG *psy_var_long,
 		PSY_VARIABLE_SHORT *psy_var_short
-//		,int ch
 		)
 {
     int b,i;
@@ -1045,7 +1194,6 @@
 		PARTITION_TABLE_SHORT *part_tbl_short, 
 		PSY_STATVARIABLE_LONG *psy_stvar_long, 
 		PSY_STATVARIABLE_SHORT *psy_stvar_short
-//		,int ch
 		)
 {
     int b,i;
@@ -1083,7 +1231,7 @@
 	/* added by T. Araki (1997.10.16) end */
 }
 
-void psy_step11andahalf(PARTITION_TABLE_LONG *part_tbl_long, 
+void psy_step11MS(PARTITION_TABLE_LONG *part_tbl_long, 
 						PARTITION_TABLE_SHORT *part_tbl_short, 
 						PSY_STATVARIABLE_LONG *psy_stvar_long, 
 						PSY_STATVARIABLE_SHORT *psy_stvar_short, 
@@ -1339,29 +1487,37 @@
 }
 
 
-void psy_step15(int use_ms_l[NSFB_LONG], int use_ms_s[MAX_SHORT_WINDOWS][NSFB_SHORT],
-				SR_INFO *p_sri,
+void psy_step15(SR_INFO *p_sri,
 				PSY_STATVARIABLE_LONG *psy_stvar_long,
 				PSY_STATVARIABLE_SHORT *psy_stvar_short,
 				PSY_VARIABLE_LONG *psy_var_long, PSY_VARIABLE_SHORT *psy_var_short,
-				int ch
+				int leftChan, int rightChan, int midChan, int sideChan
 				)
 {
 	int b, i;
 	double temp, x1, x2, db;
 
-	if (ch == 0) {
-		for (b = 0; b < p_sri->num_cb_long; b++)
-			psy_stvar_long->save_npart_l[b] = psy_var_long->npart[b];
-		for (i = 0; i < 8; i++)
-			for (b = 0; b < p_sri->num_cb_short; b++)
-				psy_stvar_short->save_npart_s[i][b] = psy_var_short->npart[i][b];
+	for (b = 0; b < p_sri->num_cb_long; b++) {
+		x1 = min(psy_var_long[0].npart[b],psy_var_long[1].npart[b]);
+		x2 = max(psy_var_long[0].npart[b],psy_var_long[1].npart[b]);
+		if (x2 >= 1000*x1)
+			db=30;
+		else
+			db = 10*log10(x2/x1);
+		temp = 0.35*(db)/5.0;
+//		printf("%d\t%f\n", b, temp);
+		if (temp < 0.35) {
+			psy_stvar_long[rightChan].use_ms[b] = 1;
+			psy_stvar_long[leftChan].ismr[b] = psy_stvar_long[midChan].ismr[b];
+			psy_stvar_long[rightChan].ismr[b] = psy_stvar_long[sideChan].ismr[b];
+		} else {
+			psy_stvar_long[rightChan].use_ms[b] = 0;
+		}
 	}
-
-	if (ch == 1) {
-		for (b = 0; b < p_sri->num_cb_long; b++) {
-			x1 = min(psy_stvar_long->save_npart_l[b],psy_var_long->npart[b]);
-			x2 = max(psy_stvar_long->save_npart_l[b],psy_var_long->npart[b]);
+	for (i = 0; i < 8; i++) {
+		for (b = 0; b < p_sri->num_cb_short; b++) {
+			x1 = min(psy_var_short[0].npart[i][b],psy_var_short[1].npart[i][b]);
+			x2 = max(psy_var_short[0].npart[i][b],psy_var_short[1].npart[i][b]);
 			if (x2 >= 1000*x1)
 				db=30;
 			else
@@ -1368,25 +1524,12 @@
 				db = 10*log10(x2/x1);
 			temp = 0.35*(db)/5.0;
 //			printf("%d\t%f\n", b, temp);
-			if (temp < 0.35)
-				use_ms_l[b] = 1;
-			else
-				use_ms_l[b] = 0;
-		}
-		for (i = 0; i < 8; i++) {
-			for (b = 0; b < p_sri->num_cb_short; b++) {
-				x1 = min(psy_stvar_short->save_npart_s[i][b],psy_var_short->npart[i][b]);
-				x2 = max(psy_stvar_short->save_npart_s[i][b],psy_var_short->npart[i][b]);
-				if (x2 >= 1000*x1)
-					db=30;
-				else
-					db = 10*log10(x2/x1);
-				temp = 0.35*(db)/5.0;
-//				printf("%d\t%f\n", b, temp);
-				if (temp < 0.35)
-					use_ms_s[i][b] = 1;
-				else
-					use_ms_s[i][b] = 0;
+			if (temp < 0.35) {
+				psy_stvar_short[rightChan].use_ms[i][b] = 1;
+				psy_stvar_short[leftChan].ismr[i][b] = psy_stvar_short[midChan].ismr[i][b];
+				psy_stvar_short[rightChan].ismr[i][b] = psy_stvar_short[sideChan].ismr[i][b];
+			} else {
+				psy_stvar_short[rightChan].use_ms[i][b] = 0;
 			}
 		}
 	}
--- a/psych.h
+++ b/psych.h
@@ -123,6 +123,7 @@
   double cw[NPART_LONG];
   double en[NPART_LONG];
   double cb[NPART_LONG];
+  double cbb[NPART_LONG];
   double tb[NPART_LONG];
   double snr[NPART_LONG];
   double bc[NPART_LONG];
@@ -157,6 +158,7 @@
   double cw[MAX_SHORT_WINDOWS][NPART_SHORT];
   double en[MAX_SHORT_WINDOWS][NPART_SHORT];
   double cb[MAX_SHORT_WINDOWS][NPART_SHORT];
+  double cbb[MAX_SHORT_WINDOWS][NPART_SHORT];
   double tb[MAX_SHORT_WINDOWS][NPART_SHORT];
   double snr[MAX_SHORT_WINDOWS][NPART_SHORT];
   double bc[MAX_SHORT_WINDOWS][NPART_SHORT];
@@ -191,8 +193,10 @@
   /* input */
   double sampling_rate,
   int    no_of_chan,         /* no of audio channels */
+  Ch_Info* chInfo,
   double *p_time_signal[],
   enum WINDOW_TYPE block_type[],
+  int use_MS,
 //  int qcSelect,
 //  int frameLength,
   /* output */
@@ -336,15 +340,33 @@
 //		,int ch
                 );
 
-void psy_step15(int use_ms_l[NSFB_LONG],
-				int use_ms_s[MAX_SHORT_WINDOWS][NSFB_SHORT],
-				SR_INFO *p_sri,
+void psy_step15(SR_INFO *p_sri,
 				PSY_STATVARIABLE_LONG *psy_stvar_long,
 				PSY_STATVARIABLE_SHORT *psy_stvar_short,
-				PSY_VARIABLE_LONG *psy_var_long,
-				PSY_VARIABLE_SHORT *psy_var_short,
-				int ch
+				PSY_VARIABLE_LONG *psy_var_long, PSY_VARIABLE_SHORT *psy_var_short,
+				int leftChan, int rightChan, int midChan, int sideChan
 				);
+
+void psy_step2MS(PSY_STATVARIABLE_LONG *psy_stvar_long,
+			PSY_STATVARIABLE_SHORT *psy_stvar_short,
+			int leftChan, int rightChan,
+			int midChan, int sideChan);
+
+void psy_step4MS(PSY_VARIABLE_LONG *psy_var_long,
+			PSY_VARIABLE_SHORT *psy_var_short,
+			int leftChan, int rightChan,
+			int midChan, int sideChan);
+
+void psy_step7MS(PSY_VARIABLE_LONG *psy_var_long,
+				 PSY_VARIABLE_SHORT *psy_var_short,
+				 int leftChan, int rightChan,
+				 int midChan, int sideChan);
+
+void psy_step11MS(PARTITION_TABLE_LONG *part_tbl_long, 
+						PARTITION_TABLE_SHORT *part_tbl_short, 
+						PSY_STATVARIABLE_LONG *psy_stvar_long, 
+						PSY_STATVARIABLE_SHORT *psy_stvar_short, 
+						int ch);
 
 #ifdef __cplusplus
 }