public FrameData decodeFrame(final int mode){
		 FrameData fd = null;

		 if (mode == Constants.HUFFMAN_DOMAIN){
			 int mdb = 0;
			 fd = new FrameData(header.get_channels(), header.get_max_gr());

			 decoder.read_side_info(fd);

			 byte [] buffer = bitstream.get_main_data();

			 if( (mdb = fd.getMainDataBegin()) != 0 ){

				 byte[] data_res = reserve.read_from_reserve(mdb);

				 int totlen = fd.getMdLen() ;
				 int main_data_beg = fd.getMainDataBegin();

				 data_def = new byte[totlen];
				 int end = (totlen > main_data_beg)? main_data_beg: totlen;

				 for(int i = 0; i < end; i++){
					 data_def[i] = data_res[i];
				 }

				 if(totlen > main_data_beg){
					 int offset = end;
					 for(int i = offset; i < totlen; i++){
						 data_def[i] = buffer[i - end];
					 }
				 }

				 reserve.store_in_reserve(buffer);
			 } else {
				 int totlen = fd.getMdLen();

				 data_def = new byte[totlen];

				 for(int i = 0; i < totlen; i++)
					 data_def[i] = buffer[i];

				 reserve.store_in_reserve(buffer);
			 }
		 } else {

			 if(mode == Constants.QUANTIZED_DOMAIN){
				 fd = (FrameDataQuantized)   decoder.decodeFrame(mode);
			 } else{
				 fd = (FrameDataDequantized)    decoder.decodeFrame(mode);
			 }
		 }

		 header.copy_info(fd);


		 try {
			 header = bitstream.readFrame();
		 } catch (IOException ex) {
			 ex.printStackTrace();
		 }

		 return fd;
	 }