示例#1
0
int d2083_audio_hs_set_gain(enum d2083_audio_output_sel hs_path_sel, enum d2083_hp_vol_val hs_gain_val)
{
	int ret = 0;
	u8 regval;
	
	if(D2083_HPVOL_NEG_57DB > hs_gain_val || D2083_HPVOL_MUTE < hs_gain_val) {
		dlg_info("[%s]- Invalid gain, so set to -1dB \n", __func__);
		hs_gain_val = D2083_HPVOL_NEG_1DB;				
	}
	
	dlg_info("d2083_audio_hs_set_gain path=%d hs_pga_gain=0x%x \n", hs_path_sel, hs_gain_val);
	
	if(dlg_audio->HSenabled==true)
	{
		if (hs_path_sel & D2083_OUT_HPL) 
		{
			regval = audio_read(D2083_HP_L_GAIN_REG) & ~D2042_HP_AMP_GAIN;
			ret |= audio_write(D2083_HP_L_GAIN_REG, regval | (hs_gain_val & D2042_HP_AMP_GAIN));
			ret |= audio_clear_bits(D2083_HP_L_CTRL_REG, D2083_HP_AMP_MUTE_EN);
		}

		if (hs_path_sel & D2083_OUT_HPR) 
		{
			regval = audio_read(D2083_HP_R_GAIN_REG) & ~D2042_HP_AMP_GAIN;
			ret |= audio_write(D2083_HP_R_GAIN_REG, regval | (hs_gain_val & D2042_HP_AMP_GAIN));
			ret |= audio_clear_bits(D2083_HP_R_CTRL_REG, D2083_HP_AMP_MUTE_EN);
		}            

	}
	dlg_audio->hs_pga_gain=hs_gain_val;

	return ret;
}
示例#2
0
int d2083_audio_hs_preamp_gain(enum d2083_preamp_gain_val hsgain_val)
{
	u8 regval = 0;
	int ret = 0;

	dlg_info("d2083_audio_hs_preamp_gain hs_pre_gain=0x%x \n",hsgain_val);
	//if(0 <  hsgain_val && D2083_PREAMP_GAIN_MUTE > hsgain_val ) 
		//dlg_audio->hs_pre_gain = hsgain_val;

	if(0 >  hsgain_val || D2083_PREAMP_GAIN_MUTE < hsgain_val ) {
		dlg_info("[%s]- Invalid preamp gain, so set to 0dB \n", __func__);
		hsgain_val = D2083_PREAMP_GAIN_0DB;				
	}

	if(dlg_audio->HSenabled==true)
	{
#ifdef USE_AUDIO_DIFFERENTIAL
		if(!dlg_audio->IHFenabled) 
		{
			regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL;
			regval |= (hsgain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL;
			ret = audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
		}
#endif		
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= (hsgain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL;
		ret = audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
	}
	dlg_audio->hs_pre_gain = hsgain_val;

	return ret;
}
示例#3
0
int d2083_audio_hs_ihf_poweroff(void)
{
	int ret = 0;
	u8 regval;

	if(ihf_power_status ==0){
		return ret;
	}
	ihf_power_status = 0;
	dlg_info("%s, HP =%d, status:%d \n", __func__,dlg_audio->HSenabled,ihf_power_status);

	audio_write(D2083_SP_CTRL_REG,0x32);

#ifdef USE_AUDIO_DIFFERENTIAL
	if (dlg_audio->HSenabled == false) 
#endif
	{
		regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= (D2083_PREAMP_MUTE);
		regval &= (~D2083_PREAMP_EN);
		ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
	}

	audio_write(D2083_SP_PWR_REG, 0x00);
	audio_write(D2083_SP_NON_CLIP_ZC_REG, 0x00);
	audio_write(D2083_SP_NON_CLIP_REG, 0x00);
	audio_write(D2083_SP_NG1_REG, 0x00);
	audio_write(D2083_SP_NG2_REG, 0x00);
	
	dlg_audio->IHFenabled = false;
	//if(dlg_audio->HSenabled==false)
	//    audio_write(D2083_LDO_AUD_MCTL_REG, 0x00); //AUD_LDO off

	return ret;
}
static ssize_t sound_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
	int dev = iminor(file->f_path.dentry->d_inode);
	int ret = -EINVAL;

	/*
	 *	The OSS drivers aren't remotely happy without this locking,
	 *	and unless someone fixes them when they are about to bite the
	 *	big one anyway, we might as well bandage here..
	 */
	 
	lock_kernel();
	
	DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
	switch (dev & 0x0f) {
	case SND_DEV_DSP:
	case SND_DEV_DSP16:
	case SND_DEV_AUDIO:
		ret = audio_read(dev, file, buf, count);
		break;

	case SND_DEV_SEQ:
	case SND_DEV_SEQ2:
		ret = sequencer_read(dev, file, buf, count);
		break;

	case SND_DEV_MIDIN:
		ret = MIDIbuf_read(dev, file, buf, count);
	}
	unlock_kernel();
	return ret;
}
void audio_isr (void *context, unsigned int id) {
  uint32_t numToRead = (samples_for_fft_requested) ? (NUM_SAMPLES - numRead) : AUDIO_BUF_SIZE;
  // Want to read step
  size_t count = audio_read (left_buffer, right_buffer, STEP_SIZE*numToRead);
  audio_write (left_buffer, right_buffer, count);
  if (samples_for_fft_requested) {
      size_t i;
      red_leds_set (0xFF);
      //modify count by STEP_SIZE since only count/STEP_SIZE samples actually copied
      size_t numSamples = count/STEP_SIZE;
      if (numRead + numSamples >= NUM_SAMPLES) {
        numRead = 0;
        samples_for_fft_requested = false;
        signal_audio_ready();
        startVal = 0;
      }
      for (i = startVal; i < count; i+= STEP_SIZE) {
        samples_for_fft[i/STEP_SIZE + numRead].r = left_buffer[i];
      }
      numRead += numSamples;
      //maintian proper spacing on next set of samples when next interrupt received
      startVal = count%STEP_SIZE;
      red_leds_clear (0xFF);
    }
}
示例#6
0
static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
	int dev = MINOR(file->f_dentry->d_inode->i_rdev);

	DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
	switch (dev & 0x0f) {
	case SND_DEV_STATUS:
		return sndstat_file_read(file, buf, count, ppos);

#ifdef CONFIG_AUDIO
	case SND_DEV_DSP:
	case SND_DEV_DSP16:
	case SND_DEV_AUDIO:
		return audio_read(dev, file, buf, count);
#endif

#ifdef CONFIG_SEQUENCER
	case SND_DEV_SEQ:
	case SND_DEV_SEQ2:
		return sequencer_read(dev, file, buf, count);
#endif

#ifdef CONFIG_MIDI
	case SND_DEV_MIDIN:
		return MIDIbuf_read(dev, file, buf, count);
#endif

	default:;
	}
	return -EINVAL;
}
示例#7
0
// speaker on/off
int d2083_audio_hs_ihf_poweron1(void)
{
	int ret = 0;
	u8 regval;

	if(ihf_power_status == true)
	 return ret;
	ihf_power_status = true;
	 
	dlg_info("%s HP =%d \n",__func__, dlg_audio->HSenabled);

	// if(dlg_audio->HSenabled==false)
	//     audio_write(D2083_LDO_AUD_MCTL_REG, 0x44); //AUD_LDO on

	audio_write(D2083_MXHPL_CTRL_REG,0x19); 

	regval = audio_read(D2083_PREAMP_A_CTRL1_REG);
	regval = (regval | D2083_PREAMP_EN) & ~D2083_PREAMP_MUTE;
	ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
	ret |= audio_write(D2083_PREAMP_A_CTRL2_REG,0x03); //pre amp A fully differential

	regval = audio_read(D2083_SP_CTRL_REG);
	regval &= ~D2083_SP_MUTE;
	regval |= D2083_SP_EN;
	ret |= audio_write(D2083_SP_CTRL_REG,regval);

	ret |= audio_write(D2083_SP_CFG1_REG,0x00); 
	ret |= audio_write(D2083_SP_CFG2_REG,0x00); 
	//ret |= audio_write(D2083_SP_NG1_REG,0x0F); 
	//ret |= audio_write(D2083_SP_NG2_REG,0x07); 
	ret |= audio_write(D2083_SP_NON_CLIP_ZC_REG,0x00);
	ret |= audio_write(D2083_SP_NON_CLIP_REG,0x00); 
	ret |= audio_write(D2083_SP_PWR_REG,0x00);

	ret |= audio_write(D2083_BIAS_CTRL_REG,0x3F); 
	dlg_audio->IHFenabled = true;

	return ret;
}
示例#8
0
int d2083_audio_ihf_preamp_gain(enum d2083_preamp_gain_val ihfgain_val)
{
	u8 regval;

	dlg_info("d2083_audio_ihf_preamp_gain gain=%d \n", ihfgain_val);

	if(0 >  ihfgain_val || D2083_PREAMP_GAIN_MUTE < ihfgain_val ) {
		dlg_info("[%s]- Invalid preamp gain, so set to 0dB \n", __func__);
		ihfgain_val = D2083_PREAMP_GAIN_0DB;				
	}

	regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL;
	regval |= (ihfgain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL;

	return audio_write(D2083_PREAMP_A_CTRL1_REG,regval);

}
示例#9
0
int d2083_audio_set_input_mode(enum d2083_input_path_sel inpath_sel, enum d2083_input_mode_val mode_val)
{
	int reg;
	u8 regval;

	if (inpath_sel == D2083_INPUTA)
		reg = D2083_PREAMP_A_CTRL2_REG;
	else if (inpath_sel == D2083_INPUTB)
		reg = D2083_PREAMP_B_CTRL2_REG;
	else
		return -EINVAL;

	regval = audio_read(reg) & ~D2083_PREAMP_CFG;
	regval |= mode_val & D2083_PREAMP_CFG;

	return audio_write(reg,regval);
}
示例#10
0
int d2083_audio_set_input_preamp_gain(enum d2083_input_path_sel inpath_sel, enum d2083_preamp_gain_val pagain_val)
{
	int reg;
	u8 regval;

	if (inpath_sel == D2083_INPUTA)
		reg = D2083_PREAMP_A_CTRL1_REG;
	else if (inpath_sel == D2083_INPUTB)
		reg = D2083_PREAMP_B_CTRL1_REG;
	else
		return -EINVAL;

	regval = audio_read(reg) & ~D2083_PREAMP_VOL;
	regval |= (pagain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL;

	dlg_info("[%s]-addr[0x%x] ihfgain_val[0x%x]\n", __func__, reg,regval);

	return audio_write(reg,regval);
}
示例#11
0
int d2083_audio_set_mixer_input(enum d2083_audio_output_sel path_sel, enum d2083_audio_input_val input_val)
{
	int reg;
	u8 regval;

	if(path_sel == D2083_OUT_HPL)
		reg = D2083_MXHPL_CTRL_REG;
	else if(path_sel == D2083_OUT_HPR)
		reg = D2083_MXHPR_CTRL_REG;
	else if(path_sel == D2083_OUT_SPKR)
		reg = D2083_MXSP_CTRL_REG;
	else
		return -EINVAL;

	regval = audio_read(reg) & ~D2083_MX_SEL;
	regval |= (input_val << D2083_MX_SEL_SHIFT) & D2083_MX_SEL;

	return audio_write(reg,regval);
}
示例#12
0
int d2083_audio_hs_ihf_set_gain(enum d2083_sp_vol_val ihfgain_val)
{
	u8 regval;

	dlg_info("[%s]-ihfgain_val[0x%x]\n", __func__, ihfgain_val);
	
	if(0 > ihfgain_val || D2083_SPVOL_MUTE < ihfgain_val) {
		dlg_info("[%s]- Invalid gain, so set to 4dB \n", __func__);
		ihfgain_val = D2083_SPVOL_0DB;				
	}

	regval = audio_read(D2083_SP_CTRL_REG);
	if (ihfgain_val == D2083_SPVOL_MUTE) 
	{
		regval |= D2083_SP_MUTE;
	} 
	else 
	{
		regval &= ~(D2083_SP_VOL | D2083_SP_MUTE);
		regval |= (ihfgain_val << D2083_SP_VOL_SHIFT) & D2083_SP_VOL;			
	}
	return  audio_write(D2083_SP_CTRL_REG,regval);
}
示例#13
0
int d2083_audio_multicast(u8 flag)
{
	u8 regval;
	int ret = 0;
	
	dlg_info("%s = %d\n",__func__, flag);
	
	switch(flag)
	{
		case DLG_REMOVE_IHF:
		if(!is_playback_stop) {
			ret = audio_write(D2083_MXHPL_CTRL_REG,0x07);
			regval = audio_read(D2083_PREAMP_B_CTRL1_REG);
			ret = audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
		}
		ret |= d2083_audio_hs_ihf_poweroff();
		break;

		case DLG_REMOVE_HS:
		ret = d2083_audio_hs_poweron1(0);
		break;
		
		case DLG_ADD_IHF:
		ret = audio_write(D2083_MXHPL_CTRL_REG,0x19);
		ret |= d2083_audio_hs_ihf_poweron1();
		break;
		
		case DLG_ADD_HS: 
		ret = d2083_audio_hs_poweron1(1);
		break;

		default:
		break;
	}
	
	return ret;
}
示例#14
0
int d2083_audio_hs_poweron1(bool on)
{
    int ret = 0;
    u8 regval;

	//dlg_info("%s status:%d, cmd:%d\n",__func__,hs_pw_status, on);     
	
	if ( hs_pw_status == on){
		return ret;
	}
	hs_pw_status = on;
	
	dlg_info("%s HP=%d speaker_power=%d \n",__func__,on,dlg_audio->IHFenabled);     

    if(on) 
	{
		//if(dlg_audio->IHFenabled==false)
		//{
		    //audio_write(D2083_LDO_AUD_MCTL_REG, 0x44); //AUD_LDO on
		    //audio_write(D2083_LDO1_MCTL_REG, 0x54);
		    //mdelay(20);
		//}

		if (!dlg_audio_sleep) {
			ret |= audio_write(D2083_HP_L_CTRL_REG,0xF0);
			ret |= audio_write(D2083_HP_R_CTRL_REG,0xF0);

			ret = audio_write(D2083_HP_L_GAIN_REG,0x00);
			ret = audio_write(D2083_HP_R_GAIN_REG,0x00); 

			ret = audio_write(D2083_HP_NG1_REG,0x10);
			msleep(30); // will test for pop noise newly
		}

		//dlg_audio->hs_pga_gain -= (LIMITED_SWAP_PRE - dlg_audio->hs_pre_gain-1);
		//dlg_audio->hs_pre_gain += (LIMITED_SWAP_PRE - dlg_audio->hs_pre_gain);
#ifndef USE_AUDIO_DIFFERENTIAL
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= ((dlg_audio->hs_pre_gain << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL);
		regval |= (D2083_PREAMP_EN | D2083_PREAMP_ZC_EN);
		regval &= ~D2083_PREAMP_MUTE;

		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
		ret |= audio_write(D2083_PREAMP_B_CTRL2_REG,0x00); 

		ret |= audio_write(D2083_MXHPR_CTRL_REG,0x11);
		ret |= audio_write(D2083_MXHPL_CTRL_REG,0x09);   

#else
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= ((dlg_audio->hs_pre_gain << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL);
		regval |= (D2083_PREAMP_EN | D2083_PREAMP_ZC_EN);
		regval &= ~D2083_PREAMP_MUTE;

		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
		ret |= audio_write(D2083_PREAMP_B_CTRL2_REG,0x03); 

		    if(dlg_audio->IHFenabled == false) {
		regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= ((dlg_audio->hs_pre_gain << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL);
		regval |= (D2083_PREAMP_EN | D2083_PREAMP_ZC_EN);
		regval &= ~D2083_PREAMP_MUTE;

		ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
		ret |= audio_write(D2083_PREAMP_A_CTRL2_REG,0x03); 
		    }

		    // HP Mixer controll
		    if(dlg_audio->IHFenabled == false){
			    audio_write(D2083_MXHPL_CTRL_REG,0x07); 
		    } else {
			    audio_write(D2083_MXHPL_CTRL_REG,0x19); 
		    }
			    audio_write(D2083_MXHPR_CTRL_REG,0x19);
#endif

		regval = audio_read(D2083_HP_L_GAIN_REG) & ~D2042_HP_AMP_GAIN & ~D2083_HP_AMP_MUTE_EN; 
		ret |= audio_write(D2083_HP_L_GAIN_REG, regval | (dlg_audio->hs_pga_gain & D2042_HP_AMP_GAIN));

		regval = audio_read(D2083_HP_R_GAIN_REG) & ~D2042_HP_AMP_GAIN & ~D2083_HP_AMP_MUTE_EN;
		ret |= audio_write(D2083_HP_R_GAIN_REG, regval | (dlg_audio->hs_pga_gain & D2042_HP_AMP_GAIN));

		ret |= audio_write(D2083_CP_CTRL_REG,0xC9);
		ret |= audio_write(D2083_CP_DELAY_REG,0x85);

		ret |= audio_write(D2083_CP_DETECTOR_REG,0x00);
		ret |= audio_write(D2083_CP_VOL_THRESHOLD_REG,0x32);
		ret |= audio_write(D2083_BIAS_CTRL_REG,0x3F);

		msleep(65);
		
#ifndef USE_AUDIO_DIFFERENTIAL
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG);
		regval &= ~D2083_PREAMP_ZC_EN;       
		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
#else
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG);
		regval &= ~D2083_PREAMP_ZC_EN;       
		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
		
		if(dlg_audio->IHFenabled == false){
		regval = audio_read(D2083_PREAMP_A_CTRL1_REG);
		regval &= ~D2083_PREAMP_ZC_EN;       
		ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
		}
#endif
		ret = audio_write(D2083_HP_NG1_REG, dlg_set_ng1);
		ret = audio_write(D2083_HP_NG2_REG, dlg_set_ng2);

		ret |= audio_write(D2083_HP_L_CTRL_REG,0xa0);
		ret |= audio_write(D2083_HP_R_CTRL_REG,0xa0);

		msleep(25);
		ret |= audio_write(D2083_CP_CTRL_REG,0xCD);

		msleep(40);
		dlg_audio->HSenabled = true;

	}
	else
	{

#ifndef USE_AUDIO_DIFFERENTIAL
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= (D2083_PREAMP_MUTE);
		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
#else		
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= (D2083_PREAMP_MUTE);
		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
		
		if(dlg_audio->IHFenabled != true) {
		regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= (D2083_PREAMP_MUTE);
		ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
		}
#endif
		ret = audio_write(D2083_HP_L_GAIN_REG, dlg_audio->hs_pga_gain -2);
		ret = audio_write(D2083_HP_R_GAIN_REG, dlg_audio->hs_pga_gain -2); 
		msleep(10);

		ret = audio_write(D2083_HP_L_GAIN_REG, dlg_audio->hs_pga_gain -5);
		ret = audio_write(D2083_HP_R_GAIN_REG, dlg_audio->hs_pga_gain -5); 
		msleep(10);

		ret = audio_write(D2083_HP_L_GAIN_REG, dlg_audio->hs_pga_gain -10);
		ret = audio_write(D2083_HP_R_GAIN_REG, dlg_audio->hs_pga_gain -10); 
		msleep(10);

		ret = audio_write(D2083_HP_NG1_REG,0x11); 
		ret = audio_write(D2083_HP_NG2_REG,0x07);    

		if(dlg_audio->IHFenabled != true)
		msleep(50);

		ret = audio_write(D2083_HP_L_GAIN_REG,0x00);
		ret = audio_write(D2083_HP_R_GAIN_REG,0x00); 
		msleep(10);

		audio_write(D2083_CP_CTRL_REG,0xC9);
			
		dlg_audio_sleep = false;
		dlg_audio->HSenabled = false;

		// if(dlg_audio->IHFenabled==false) {
		//     audio_write(D2083_LDO_AUD_MCTL_REG, 0x00); //AUD_LDO off
		//	 audio_write(D2083_LDO1_MCTL_REG, 0x54);
		// }

	}

	return ret;
}
示例#15
0
void toc_extract( WINDOW * win )
{
  static const char * ext[] = { "avr", "raw", "raw", "wav" };
  char pathname[ 256 ];
  char prog_info[ 64 ];
  char buf[ 128 ];
  struct avr_header * avrh;
  struct wave_header * wavh;
  struct audio_entry entry;
  struct audio_stream * as;
  struct _toc_data * data;
  struct device_info * info;
  OBJECT * ck;
  int format, i, max, track_no;
  int fd, swap;
  long offset, length, position, end, progress, total_length;
  long max_buf_blocks, nblocks;
  void * buffer;

  if( !fileselect( preferences.toc_dest, "", "TXT_EXTDEST" ) )
    return;
  strrchr( preferences.toc_dest, '\\' )[1] = '\0';

  data = DataSearch( win, TW_MAGIC );
  max = data->n_tracks;
  format = fmt_popup.selected;
  total_length = 0;
  buffer = alloc_comm_buffer( BUFSIZE );
  if( !buffer )
    return;
  for( i = 0; i < max; i++ )
  {
    ck = data->tree + 1 + TF_CK + i * data->n_obj;
    if( ! (ck->ob_state & SELECTED) )
      continue;
    offset = toc_address( data->f[i].beg_time );
    length = toc_address( data->f[i].end_time ) + 1 - offset;
    if( length > 0 )
      total_length += length;
  }
  max_buf_blocks = BUFSIZE / 2352;

  progress = 0;
  progress_init( get_string( "TXT_EXTMSG" ), total_length );
  progress_activate_cancel( 1 );
  progress_init_timer();

  log_begin();
  log_printf( "*** Begin of a track extraction session\n\n" );
  as = NULL;
  for( i = 0; i < max; i++ )
  {
    ck = data->tree + 1 + TF_CK + i * data->n_obj;
    if( ! (ck->ob_state & SELECTED) )
      continue;
    offset = toc_address( data->f[i].beg_time );
    length = toc_address( data->f[i].end_time ) + 1 - offset;
    if( length <= 0 )
      continue;
    track_no = i + 1;
    position = get_track_offset( &data->toc, track_no, &end );
    if( toc_popup.selected == 0 )
      gen_daoimg_entry( &entry, toc_info.toc_file, track_no,
                        offset - position, end - offset - length );
    else
    {
      info = (struct device_info*)toc_popup.item[toc_popup.selected].info;
      gen_cd_entry( &entry, info, track_no, offset - position, end - offset - length );
    }
    if( as )
      as = audio_reopen( as, &entry );
    else
      as = audio_open( &entry );
    if( as == NULL )
      continue;

    sprintf( prog_info, get_string( "TXT_EXTTRK" ), track_no );
    progress_setinfo( prog_info );

    sprintf( pathname, "%strack%02d.%s", preferences.toc_dest, track_no, ext[ format ] );
    fd = open( pathname, O_WRONLY|O_CREAT|O_TRUNC );
    if( fd == -1 )
    {
      audio_close( as );
      alert_msg( "AL_FILERR", 1, pathname );
      goto error;
    }
    switch( format )
    {
    case 0:        /* AVR */
      avrh = (struct avr_header *) buf;
      avrh->avr_id = '2BIT';
      memset( avrh->name, 0, 8 );
      avrh->num_voices = 0xFFFF;
      avrh->num_bits = 16;
      avrh->signe = 0xffff;
      avrh->loop = 0;
      avrh->midi = 0xffff;
      avrh->freq_type.frequence = 0xff00ac44L;
      avrh->length = length * (2352 / 2);
      avrh->beg_loop = 0;
      avrh->end_loop = avrh->length;
      memset( avrh->reserved, 0, 26 + 64 );
      write( fd, avrh, sizeof( *avrh ) );
      swap = as->little_endian;
      break;
    case 1:        /* RAW big-endian */
      swap = as->little_endian;
      break;
    case 2:        /* RAW little-endian */
      swap = !as->little_endian;
      break;
    case 3:        /* WAVE */
      wavh = (struct wave_header *) buf;
      wavh->riff_id = 'RIFF';
      wavh->riff_len = swap_long( length * 2352 + 36 );
      wavh->wave_id = 'WAVE';
      wavh->fmt_id = 'fmt ';
      wavh->fmt_size = 0x10000000L;
      wavh->fmt_compression_code = 0x0100;
      wavh->fmt_channels = 0x0200;
      wavh->fmt_freq = 0x44ac0000L;
      wavh->fmt_bytes_sec = 0x10b10200L;
      wavh->fmt_block_align = 0x0400;
      wavh->fmt_num_bits = 0x1000;
      wavh->data_id = 'data';
      wavh->data_size = swap_long( length * 2352 );
      write( fd, wavh, sizeof( *wavh ) );
      swap = !as->little_endian;
      break;
    }
    while( length > 0 )
    {
      if( yield() )
      {
        audio_close( as );
        alert_msg( "AL_EXTINT", 1 );
        goto error;
      }
      nblocks = MIN( length, max_buf_blocks );
      if( audio_read( as, buffer, nblocks ) == 0 )
      {
        audio_close( as );
        goto error;
      }
      if( swap )
        swap_endian( buffer, nblocks * 2352 );
      if( write( fd, buffer, nblocks * 2352 ) == -1 )
      {
        close( fd );
        audio_close( as );
        alert_msg( "AL_FWRTERR", 1, pathname );
        goto error;
      }
      length -= nblocks;
      progress += nblocks;
      progress_setcount( progress );
    }
    close( fd );
  }
  audio_close( as );
error:
  log_printf( "*** End of the track extraction session\n\n" );
  log_end();
  progress_exit();
  free_comm_buffer( buffer );

}