【数据压缩】第八次作业——MPEG音频编码实验

目录

一、 实验项目名称

二、 实验目的

 三、实验内容

1. 感知音频编码原理

2. 理解感知音频编码的设计思想

3. 理解心理声学模型的实现过程

临界频带 

心理声学模型实现过程

1、将样本变换到频域

3.  考虑安静时阈值

4. 将音频信号分解成 “乐音” 和“非乐音/噪声”部分

5、乐音和噪音掩蔽成分的消除

6、单个掩蔽阈值的计算

7、全局掩蔽阈值的计算

 8、每个子带的掩蔽阈值

9、计算每个子带信号掩蔽比

4. 理解码率分配的实现思路

5. 理解实验代码

 三、实验步骤

1. 选择不同特性音频文件输出采样率和目标码率

2. 分析某个数据帧


一、 实验项目名称

MPEG音频编码实验

二、 实验目的

  1. 理解程序设计的整体框架
  2. 理解感知音频编码的设计思想
  3. 理解心理声学模型的实现过程
  4. 理解码率分配的实现思路

 三、实验内容

1. 感知音频编码原理

下图为MPEG-1 Audio Layer||编码器原理

多项滤波器组:将PCM样本变换到32个子带的频域信号

心理声学模型:计算信号中不可听觉感知的部分

比特分配器:根据心理声学模型的计算结果,为每个子带信号分配比特数

装帧:产生MPEG-1兼容的比特流

2. 理解感知音频编码的设计思想

  •  两条线:

上面一条线为主干部分,进行子带编码,首先将输入的PCM码流通过滤波器组按低高频率分成32个子带,从子带样本中提取比例因子,提供给下面的心理声学模型调节比特分配,根据每个子带的分配比特结果进行量化,最后装帧。

下面一条线为辅助部分,做心理声学模型分析,首先将输入码流进行FFT变换,结果和上面的线得到的子带样本的比例因子一起输入给心理声学模型,得到的结果再作为输入给动态比特分配,动态比特分配同时结合码率条件给每个子带分配比特,传给上面线的线性量化器。

  • 时-频分析的矛盾

心理声学模型在频域上分析,需要高频域分辨率,子带编码要精确捕捉信号在时间上的变化,因此需要高时域分辨率,因此二者有矛盾。

3. 理解心理声学模型的实现过程

临界频带 

临界频带是指当某个纯音被以它为中心频率、且具有一定带宽的连续噪声所掩蔽时,如果该纯音刚好被听到时的功率等于这一频带内的噪声功率,这个带宽为临界频带宽度。

使噪声的中心频率等于信号频率,只改变噪声的带宽同时保持噪声的功率谱密度不变,测试纯音听阈随掩蔽噪声带宽变化的特性,纯音的听阈随掩蔽噪声带宽的增大而增大,在带宽增大到某一特定值之后听阈保持恒定不变

因此只有临界频带内的噪声才会对掩蔽起作用,临界频带以外的噪声对掩蔽不起作用。进行心理声学模型分析时仅需要在临界频带范围内就可以。

心理声学模型实现过程

1、将样本变换到频域

32个等分的子带信号并不能精确地反映人耳的听觉特性。引入FFT补偿频率分辨率不足的问题。

2. 确定声压级别

计算得到子带的声压级别,使用了子带编码的子带的比例因子输入

3.  考虑安静时阈值

也即绝对阈值,在标准中有根据输入PCM信号的采样率编制的“频率、临界频带率和绝对阈值”表。

4. 将音频信号分解成 “乐音” 和“非乐音/噪声”部分

因为两种信号掩蔽能力不同。分析乐音对噪声的掩蔽,乐音对乐音的掩蔽,噪声对乐音的掩蔽,噪声对噪声的掩蔽,在临界频带分析。

5、乐音和噪音掩蔽成分的消除

利用标准中给出的绝对阈值消除被掩蔽成分;考虑在每个临界频带内,小于0.5Bark的距离中只保留最高功率的成分

6、单个掩蔽阈值的计算

乐音成分和噪音成分单个掩蔽阈值根据标准中给出的算法求得 。

7、全局掩蔽阈值的计算

还要考虑别的临界频带的影响。一个掩蔽信号会对其它频带上的信号产生掩蔽效应。这种掩蔽效应称为掩蔽扩散 。

 8、每个子带的掩蔽阈值

低频一个子带可能对应多个临界频带,选择出本子带中最小的阈值作为子带阈值

而对高频不正确,高频区的临界频带很宽,可能跨越多个子带

9、计算每个子带信号掩蔽比

信掩比:SMR = 信号能量 / 掩蔽阈值,SMR即为心理声学模型的输出,会传递给编码单元

4. 理解码率分配的实现思路

  • 输入:

心理声学模型的输出SMR和作为约束条件的码率

  • 计算过程:

计算噪声-掩蔽比NMR=SMR-SNR,SMR为信掩比,SNR为信噪比

依据原则:使每个子带的NMR最小

信掩比<0不考虑,只给信掩比>0分配比特

循环分配比特,初始化比特分配均为0,每一次给信掩比最大的子带分配比特,直到每个子带SNR>=SMR或者没有更多的比特去分配

  • 输出:

每个子带的量化比特数

5. 理解实验代码

1. 数据组织结构

主要有三个结构体变量:frame_header、frame_info、Bit_stream_struc

frame_info:描述frame结构,包含一些头信息等等

typedef struct
{
  frame_header *header;		/* raw header information */
  int actual_mode;		/* when writing IS, may forget if 0 chs */
  al_table *alloc;		/* bit allocation table read in */
  int tab_num;			/* number of table as loaded */
  int nch;			/* num channels: 1 for mono, 2 for stereo */
  int jsbound;			/* first band of joint stereo coding */
  int sblimit;			/* total number of sub bands */
}
frame_info;

Bit_stream_struc:描述形成比特流的一些关键信息等

typedef struct bit_stream_struc
{
  FILE *pt;			/* pointer to bit stream device */
  unsigned char *buf;		/* bit stream buffer */
  int buf_size;			/* size of buffer (in number of bytes) */
  long totbit;			/* bit counter of bit stream */
  int buf_byte_idx;		/* pointer to top byte in buffer */
  int buf_bit_idx;		/* pointer to top bit of top byte in buffer */
  int mode;			/* bit stream open in read or write mode */
  int eob;			/* end of buffer index */
  int eobs;			/* end of bit stream flag */
  char format;

  /* format of file in rd mode (BINARY/ASCII) */
}
Bit_stream_struc;

frame_header:frame头信息,包含在frame_info中

typedef struct
{
  int version;
  int lay;
  int error_protection;
  int dab_extension;
  int dab_length;
  int bitrate_index;
  int sampling_frequency;
  int padding;
  int extension;
  int mode;
  int mode_ext;
  int copyright;
  int original;
  int emphasis;
}
frame_header;

 2. 重要缓冲区

buffer:输入音频样本

bit_alloc:比特分配信息

scfsi:缩放因子选择

scalar:比例因子

j_scale:比例因子选择

smr:信掩比

等等

3. 理解代码部分

get_audio,获取一帧音频数据写入buffer

/************************************************************************
*
* get_audio()
*
* PURPOSE:  reads a frame of audio data from a file to the buffer,
*   aligns the data for future processing, and separates the
*   left and right channels
*
*
************************************************************************/
unsigned long
get_audio (FILE * musicin, short buffer[2][1152], unsigned long num_samples,
	   int nch, frame_header *header)
{
  int j;
  short insamp[2304];
  unsigned long samples_read;

  if (nch == 2) {		/* stereo */
    samples_read =
      read_samples (musicin, insamp, num_samples, (unsigned long) 2304);
    if (glopts.channelswap == TRUE) {
      for (j = 0; j < 1152; j++) {
	buffer[1][j] = insamp[2 * j];
	buffer[0][j] = insamp[2 * j + 1];
      }
    } else {
      for (j = 0; j < 1152; j++) {
	buffer[0][j] = insamp[2 * j];
	buffer[1][j] = insamp[2 * j + 1];
      }
    }
  } else if (glopts.downmix == TRUE) {
    samples_read =
      read_samples (musicin, insamp, num_samples, (unsigned long) 2304);
    for (j = 0; j < 1152; j++) {
      buffer[0][j] = 0.5 * (insamp[2 * j] + insamp[2 * j + 1]);
    }
  } else {			/* mono */
    samples_read =
      read_samples (musicin, insamp, num_samples, (unsigned long) 1152);
    for (j = 0; j < 1152; j++) {
      buffer[0][j] = insamp[j];
      /* buffer[1][j] = 0;  don't bother zeroing this buffer. MFC Nov 99 */
    }
  }
  return (samples_read);
}

 available_bits,计算比特预算

/* function returns the number of available bits */
int available_bits (frame_header *header, options * glopts)
{
  int adb;

  slots.extra = 0;		/* be default, no extra slots */

  slots.average =
    (1152.0 / s_freq[header->version][header->sampling_frequency]) *
    ((double) bitrate[header->version][header->bitrate_index] / 8.0);

  slots.whole = (int) slots.average;
  slots.frac = slots.average - (double) slots.whole;

  /* never allow padding for a VBR frame. 
     Don't ask me why, I've forgotten why I set this */
  if (slots.frac != 0 && glopts->usepadbit && glopts->vbr == FALSE) {
    if (slots.lag > (slots.frac - 1.0)) {	/* no padding for this frame */
      slots.lag -= slots.frac;
      slots.extra = 0;
      header->padding = 0;
    } else {			/* padding */

      slots.extra = 1;
      header->padding = 1;
      slots.lag += (1 - slots.frac);
    }
  }

  adb = (slots.whole + slots.extra) * 8;

  return adb;
}

 WindowFilterSubband,子带分解,生成32个子带样本

void WindowFilterSubband (short *pBuffer, int ch, double s[SBLIMIT])
{
……

scale_factor_calc,计算比例因子

void scale_factor_calc (double sb_sample[][3][SCALE_BLOCK][SBLIMIT],
			unsigned int
 scalar[][3][SBLIMIT], int nch,
			int sblimit)
{
……

pick_scale,选择最大比例因子

void pick_scale (unsigned int scalar[2][3][SBLIMIT], frame_info * frame,
		 double max_sc[2][SBLIMIT])
{
  int i, j, k, max;
  int nch = frame->nch;
  int sblimit = frame->sblimit;

  for (k = 0; k < nch; k++)
    for (i = 0; i < sblimit; max_sc[k][i] = multiple[max], i++)
      for (j = 1, max = scalar[k][0][i]; j < 3; j++)
	if (max > scalar[k][j][i])
	  max = scalar[k][j][i];
  for (i = sblimit; i < SBLIMIT; i++)
    max_sc[0][i] = max_sc[1][i] = 1E-20;
}

 心理声学模型分析,可以选择模型0,1,2等

if ((glopts.quickmode == TRUE) && (++psycount % glopts.quickcount != 0)) {
      /* We're using quick mode, so we're only calculating the model every
         'quickcount' frames. Otherwise, just copy the old ones across */
      for (ch = 0; ch < nch; ch++) {
	for (sb = 0; sb < SBLIMIT; sb++)
	  smr[ch][sb] = smrdef[ch][sb];
      }
    } else {
      /* calculate the psymodel */
      switch (model) {
      case -1:
	psycho_n1 (smr, nch);
	break;
      case 0:	/* Psy Model A */
	psycho_0 (smr, nch, scalar, (FLOAT) s_freq[header.version][header.sampling_frequency] * 1000);	
	break;
      case 1:
	psycho_1 (buffer, max_sc, smr, &frame);
	break;
      case 2:
	for (ch = 0; ch < nch; ch++) {
	  psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32,
		     (FLOAT) s_freq[header.version][header.sampling_frequency] *
		     1000, &glopts);
	}
	break;
      case 3:
	/* Modified psy model 1 */
	psycho_3 (buffer, max_sc, smr, &frame, &glopts);
	break;
      case 4:
	/* Modified Psycho Model 2 */
	for (ch = 0; ch < nch; ch++) {
	  psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32,
		     (FLOAT) s_freq[header.version][header.sampling_frequency] *
		     1000, &glopts);
	}
	break;	
      case 5:
	/* Model 5 comparse model 1 and 3 */
	psycho_1 (buffer, max_sc, smr, &frame);
	fprintf(stdout,"1 ");
	smr_dump(smr,nch);
	psycho_3 (buffer, max_sc, smr, &frame, &glopts);
	fprintf(stdout,"3 ");
	smr_dump(smr,nch);
	break;
      case 6:
	/* Model 6 compares model 2 and 4 */
	for (ch = 0; ch < nch; ch++) 
	  psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32,
		    (FLOAT) s_freq[header.version][header.sampling_frequency] *
		    1000, &glopts);
	fprintf(stdout,"2 ");
	smr_dump(smr,nch);
	for (ch = 0; ch < nch; ch++) 
	  psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32,
		     (FLOAT) s_freq[header.version][header.sampling_frequency] *
		     1000, &glopts);
	fprintf(stdout,"4 ");
	smr_dump(smr,nch);
	break;
      case 7:
	fprintf(stdout,"Frame: %i\n",frameNum);
	/* Dump the SMRs for all models */	
	psycho_1 (buffer, max_sc, smr, &frame);
	fprintf(stdout,"1");
	smr_dump(smr, nch);
	psycho_3 (buffer, max_sc, smr, &frame, &glopts);
	fprintf(stdout,"3");
	smr_dump(smr,nch);
	for (ch = 0; ch < nch; ch++) 
	  psycho_2 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], //snr32,
		    (FLOAT) s_freq[header.version][header.sampling_frequency] *
		    1000, &glopts);
	fprintf(stdout,"2");
	smr_dump(smr,nch);
	for (ch = 0; ch < nch; ch++) 
	  psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32,
		     (FLOAT) s_freq[header.version][header.sampling_frequency] *
		     1000, &glopts);
	fprintf(stdout,"4");
	smr_dump(smr,nch);
	break;
      case 8:
	/* Compare 0 and 4 */	
	psycho_n1 (smr, nch);
	fprintf(stdout,"0");
	smr_dump(smr,nch);

	for (ch = 0; ch < nch; ch++) 
	  psycho_4 (&buffer[ch][0], &sam[ch][0], ch, &smr[ch][0], // snr32,
		     (FLOAT) s_freq[header.version][header.sampling_frequency] *
		     1000, &glopts);
	fprintf(stdout,"4");
	smr_dump(smr,nch);
	break;
      default:
	fprintf (stderr, "Invalid psy model specification: %i\n", model);
	exit (0);
      }

      if (glopts.quickmode == TRUE)
	/* copy the smr values and reuse them later */
	for (ch = 0; ch < nch; ch++) {
	  for (sb = 0; sb < SBLIMIT; sb++)
	    smrdef[ch][sb] = smr[ch][sb];
	}

      if (glopts.verbosity > 4) 
	smr_dump(smr, nch);

这里以model=1为例,输入buffer和max_sc,得到smr

psycho_1 (buffer, max_sc, smr, &frame);

比特分配 

main_bit_allocation (smr, scfsi, bit_alloc, &adb, &frame, &glopts);

编码,对比特分配信息和比例因子等辅助信息编码,对子带样本量化,最后封装

	//编码
    if (error_protection)
      CRC_calc (&frame, bit_alloc, scfsi, &crc);
    encode_info (&frame, &bs);
    if (error_protection)
      encode_CRC (crc, &bs);
    encode_bit_alloc (bit_alloc, &frame, &bs);
    encode_scale (bit_alloc, scfsi, scalar, &frame, &bs);
    subband_quantization (scalar, *sb_sample, j_scale, *j_sample, bit_alloc,
			  *subband, &frame);
    sample_encoding (*subband, bit_alloc, &frame, &bs);

最后向外输出码流

 三、实验步骤

1. 选择不同特性音频文件输出采样率和目标码率

  • 持续噪声

如图采样率为48kHz,目标码率为192kbps

  • 突发噪声

如图采样率为48kHz,目标码率为192kbps

  • 乐音

如图采样率为44.1kHz,目标码率为192kbps

  • 混合音

如图采样率为44.1kHz,目标码率为192kbps

2. 分析某个数据帧

选择第6帧数据帧,输出该帧所分配的比特数,该帧的比例因子,和该帧的分配结果

在原代码中添加如下代码,位置在计算了比例因子代码之后

if (frameNum == 6) {
		printf("当前帧是第%d帧\n", frameNum);
		printf("该帧所分配比特数为:%d\n", adb);
		printf("————该帧比例因子————\n");
		for (int i = 0; i < nch; i++) {   //声道
			printf("————声道%d————\n", i + 1);
			for (int j = 0; j < frame.sblimit; j++) {   //子带
				printf("子带%d\t", j + 1);
				for (int k = 0; k < 3; k++) {    //每个子带的比例因子
					printf("%d\t", scalar[i][k][j]);
				}
				printf("\n");
			}
		}
		printf("\n");
		printf("————该帧比特分配:————\n");
		for (int i = 0; i < nch; i++) {   //声道
			printf("————声道%d————\n", i + 1);
			for (int j = 0; j < frame.sblimit; j++) {   //每个子带比特分配结果
				printf("子带%d:\t%d\t", j + 1, bit_alloc[i][j]);
			}
			printf("\n");
		}
	}

得到了如下结果:

  • 持续噪声
当前帧是第6帧
该帧所分配比特数为:4608
————该帧比例因子————
————声道1————
子带1   63      63      63
子带2   63      63      63
子带3   63      63      63
子带4   63      63      63
子带5   63      63      63
子带6   63      63      63
子带7   63      63      63
子带8   63      63      63
子带9   63      63      63
子带10  63      63      63
子带11  63      63      63
子带12  63      63      63
子带13  63      63      63
子带14  63      63      63
子带15  63      63      63
子带16  63      63      63
子带17  63      63      63
子带18  63      63      63
子带19  63      63      63
子带20  63      63      63
子带21  63      63      63
子带22  63      63      63
子带23  63      63      63
子带24  63      63      63
子带25  63      63      63
子带26  63      63      63
子带27  63      63      63
————声道2————
子带1   63      63      63
子带2   63      63      63
子带3   63      63      63
子带4   63      63      63
子带5   63      63      63
子带6   63      63      63
子带7   63      63      63
子带8   63      63      63
子带9   63      63      63
子带10  63      63      63
子带11  63      63      63
子带12  63      63      63
子带13  63      63      63
子带14  63      63      63
子带15  63      63      63
子带16  63      63      63
子带17  63      63      63
子带18  63      63      63
子带19  63      63      63
子带20  63      63      63
子带21  63      63      63
子带22  63      63      63
子带23  63      63      63
子带24  63      63      63
子带25  63      63      63
子带26  63      63      63
子带27  63      63      63

————该帧比特分配:————
————声道1————
子带1:  3       子带2:  3       子带3:  3       子带4:  6       子带5:  6       子带6:  6       子带7:  5       子带8: 4子带9:  4       子带10: 4       子带11: 4       子带12: 4       子带13: 3       子带14: 3       子带15: 2       子带16:
1       子带17: 0       子带18: 0       子带19: 0       子带20: 0       子带21: 0       子带22: 0       子带23: 0       子带24: 0       子带25: 0       子带26: 0       子带27: 0
————声道2————
子带1:  3       子带2:  3       子带3:  3       子带4:  6       子带5:  6       子带6:  6       子带7:  5       子带8: 4子带9:  4       子带10: 4       子带11: 4       子带12: 3       子带13: 3       子带14: 3       子带15: 2       子带16:
1       子带17: 0       子带18: 0       子带19: 0       子带20: 0       子带21: 0       子带22: 0       子带23: 0       子带24: 0       子带25: 0       子带26: 0       子带27: 0
  • 突发噪声
当前帧是第6帧
该帧所分配比特数为:4608
————该帧比例因子————
————声道1————
子带1   63      63      63
子带2   63      63      63
子带3   63      63      63
子带4   63      63      63
子带5   63      63      63
子带6   63      63      63
子带7   63      63      63
子带8   63      63      63
子带9   63      63      63
子带10  63      63      63
子带11  63      63      63
子带12  63      63      63
子带13  63      63      63
子带14  63      63      63
子带15  63      63      63
子带16  63      63      63
子带17  63      63      63
子带18  63      63      63
子带19  63      63      63
子带20  63      63      63
子带21  63      63      63
子带22  63      63      63
子带23  63      63      63
子带24  63      63      63
子带25  63      63      63
子带26  63      63      63
子带27  63      63      63
————声道2————
子带1   63      63      63
子带2   63      63      63
子带3   63      63      63
子带4   63      63      63
子带5   63      63      63
子带6   63      63      63
子带7   63      63      63
子带8   63      63      63
子带9   63      63      63
子带10  63      63      63
子带11  63      63      63
子带12  63      63      63
子带13  63      63      63
子带14  63      63      63
子带15  63      63      63
子带16  63      63      63
子带17  63      63      63
子带18  63      63      63
子带19  63      63      63
子带20  63      63      63
子带21  63      63      63
子带22  63      63      63
子带23  63      63      63
子带24  63      63      63
子带25  63      63      63
子带26  63      63      63
子带27  63      63      63

————该帧比特分配:————
————声道1————
子带1:  3       子带2:  3       子带3:  3       子带4:  6       子带5:  6       子带6:  6       子带7:  5       子带8: 4子带9:  4       子带10: 4       子带11: 4       子带12: 4       子带13: 3       子带14: 3       子带15: 2       子带16:
1       子带17: 0       子带18: 0       子带19: 0       子带20: 0       子带21: 0       子带22: 0       子带23: 0       子带24: 0       子带25: 0       子带26: 0       子带27: 0
————声道2————
子带1:  3       子带2:  3       子带3:  3       子带4:  6       子带5:  6       子带6:  6       子带7:  5       子带8: 4子带9:  4       子带10: 4       子带11: 4       子带12: 3       子带13: 3       子带14: 3       子带15: 2       子带16:
1       子带17: 0       子带18: 0       子带19: 0       子带20: 0       子带21: 0       子带22: 0       子带23: 0       子带24: 0       子带25: 0       子带26: 0       子带27: 0
  • 乐音
当前帧是第6帧
该帧所分配比特数为:5016
————该帧比例因子————
————声道1————
子带1   10      11      9
子带2   17      18      16
子带3   21      21      21
子带4   29      27      27
子带5   30      30      23
子带6   28      28      23
子带7   26      27      26
子带8   27      27      27
子带9   31      31      30
子带10  34      29      29
子带11  31      31      27
子带12  29      28      30
子带13  29      28      26
子带14  23      24      26
子带15  26      25      26
子带16  24      27      27
子带17  30      34      35
子带18  31      29      31
子带19  29      33      31
子带20  30      32      31
子带21  31      31      31
子带22  32      31      31
子带23  40      39      39
子带24  50      50      51
子带25  54      54      52
子带26  56      55      54
子带27  54      53      54
子带28  54      54      52
子带29  55      50      54
子带30  55      54      53

————该帧比特分配:————
————声道1————
子带1:  9       子带2:  7       子带3:  6       子带4:  9       子带5:  7       子带6:  7       子带7:  7       子带8: 7子带9:  6       子带10: 6       子带11: 6       子带12: 7       子带13: 6       子带14: 6       子带15: 6       子带16:
5       子带17: 4       子带18: 4       子带19: 5       子带20: 6       子带21: 5       子带22: 3       子带23: 0       子带24: 0       子带25: 0       子带26: 0       子带27: 0       子带28: 0       子带29: 0       子带30: 0
  • 混合音
当前帧是第6帧
该帧所分配比特数为:5016
————该帧比例因子————
————声道1————
子带1   13      14      12
子带2   20      20      20
子带3   23      25      23
子带4   31      32      33
子带5   32      33      27
子带6   30      31      26
子带7   29      30      30
子带8   30      30      29
子带9   34      34      33
子带10  38      34      31
子带11  35      34      30
子带12  31      32      32
子带13  33      31      28
子带14  27      28      29
子带15  27      28      29
子带16  29      31      29
子带17  34      35      39
子带18  39      33      33
子带19  33      34      36
子带20  33      35      34
子带21  34      34      34
子带22  34      35      34
子带23  43      40      42
子带24  53      53      54
子带25  55      54      55
子带26  56      56      55
子带27  54      54      54
子带28  54      56      55
子带29  55      52      57
子带30  55      55      55

————该帧比特分配:————
————声道1————
子带1:  9       子带2:  7       子带3:  6       子带4:  9       子带5:  8       子带6:  7       子带7:  7       子带8: 7子带9:  6       子带10: 6       子带11: 6       子带12: 7       子带13: 6       子带14: 6       子带15: 6       子带16:
5       子带17: 4       子带18: 5       子带19: 5       子带20: 6       子带21: 4       子带22: 2       子带23: 0       子带24: 0       子带25: 0       子带26: 0       子带27: 0       子带28: 0       子带29: 0       子带30: 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值