📄 audio.c
字号:
return nsamples * 2 * 2; } else { /* mono */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) { sample0 = audio_linear_round(16, *left++, stats); data[0] = sample0 >> 8; data[1] = sample0 >> 0; data += 2; } break; case AUDIO_MODE_DITHER: while (len--) { sample0 = audio_linear_dither(16, *left++, &left_dither, stats); data[0] = sample0 >> 8; data[1] = sample0 >> 0; data += 2; } break; default: return 0; } return nsamples * 2; }}/* * NAME: audio_pcm_s24le() * DESCRIPTION: write a block of signed 24-bit little-endian PCM samples */unsigned int audio_pcm_s24le(unsigned char *data, unsigned int nsamples, mad_fixed_t const *left, mad_fixed_t const *right, enum audio_mode mode, struct audio_stats *stats){ unsigned int len; register signed long sample0, sample1; len = nsamples; if (right) { /* stereo */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) { sample0 = audio_linear_round(24, *left++, stats); sample1 = audio_linear_round(24, *right++, stats); data[0] = sample0 >> 0; data[1] = sample0 >> 8; data[2] = sample0 >> 16; data[3] = sample1 >> 0; data[4] = sample1 >> 8; data[5] = sample1 >> 16; data += 6; } break; case AUDIO_MODE_DITHER: while (len--) { sample0 = audio_linear_dither(24, *left++, &left_dither, stats); sample1 = audio_linear_dither(24, *right++, &right_dither, stats); data[0] = sample0 >> 0; data[1] = sample0 >> 8; data[2] = sample0 >> 16; data[3] = sample1 >> 0; data[4] = sample1 >> 8; data[5] = sample1 >> 16; data += 6; } break; default: return 0; } return nsamples * 3 * 2; } else { /* mono */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) { sample0 = audio_linear_round(24, *left++, stats); data[0] = sample0 >> 0; data[1] = sample0 >> 8; data[2] = sample0 >> 16; data += 3; } break; case AUDIO_MODE_DITHER: while (len--) { sample0 = audio_linear_dither(24, *left++, &left_dither, stats); data[0] = sample0 >> 0; data[1] = sample0 >> 8; data[2] = sample0 >> 16; data += 3; } break; default: return 0; } return nsamples * 3; }}/* * NAME: audio_pcm_s24be() * DESCRIPTION: write a block of signed 24-bit big-endian PCM samples */unsigned int audio_pcm_s24be(unsigned char *data, unsigned int nsamples, mad_fixed_t const *left, mad_fixed_t const *right, enum audio_mode mode, struct audio_stats *stats){ unsigned int len; register signed long sample0, sample1; len = nsamples; if (right) { /* stereo */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) { sample0 = audio_linear_round(24, *left++, stats); sample1 = audio_linear_round(24, *right++, stats); data[0] = sample0 >> 16; data[1] = sample0 >> 8; data[2] = sample0 >> 0; data[3] = sample1 >> 16; data[4] = sample1 >> 8; data[5] = sample1 >> 0; data += 6; } break; case AUDIO_MODE_DITHER: while (len--) { sample0 = audio_linear_dither(24, *left++, &left_dither, stats); sample1 = audio_linear_dither(24, *right++, &right_dither, stats); data[0] = sample0 >> 16; data[1] = sample0 >> 8; data[2] = sample0 >> 0; data[3] = sample1 >> 16; data[4] = sample1 >> 8; data[5] = sample1 >> 0; data += 6; } break; default: return 0; } return nsamples * 3 * 2; } else { /* mono */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) { sample0 = audio_linear_round(24, *left++, stats); data[0] = sample0 >> 16; data[1] = sample0 >> 8; data[2] = sample0 >> 0; data += 3; } break; case AUDIO_MODE_DITHER: while (len--) { sample1 = audio_linear_dither(24, *left++, &left_dither, stats); data[0] = sample1 >> 16; data[1] = sample1 >> 8; data[2] = sample1 >> 0; data += 3; } break; default: return 0; } return nsamples * 3; }}/* * NAME: audio_pcm_s32le() * DESCRIPTION: write a block of signed 32-bit little-endian PCM samples */unsigned int audio_pcm_s32le(unsigned char *data, unsigned int nsamples, mad_fixed_t const *left, mad_fixed_t const *right, enum audio_mode mode, struct audio_stats *stats){ unsigned int len; register signed long sample0, sample1; len = nsamples; if (right) { /* stereo */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) { sample0 = audio_linear_round(24, *left++, stats); sample1 = audio_linear_round(24, *right++, stats); data[0] = 0; data[1] = sample0 >> 0; data[2] = sample0 >> 8; data[3] = sample0 >> 16; data[4] = 0; data[5] = sample1 >> 0; data[6] = sample1 >> 8; data[7] = sample1 >> 16; data += 8; } break; case AUDIO_MODE_DITHER: while (len--) { sample0 = audio_linear_dither(24, *left++, &left_dither, stats); sample1 = audio_linear_dither(24, *right++, &right_dither, stats); data[0] = 0; data[1] = sample0 >> 0; data[2] = sample0 >> 8; data[3] = sample0 >> 16; data[4] = 0; data[5] = sample1 >> 0; data[6] = sample1 >> 8; data[7] = sample1 >> 16; data += 8; } break; default: return 0; } return nsamples * 4 * 2; } else { /* mono */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) { sample0 = audio_linear_round(24, *left++, stats); data[0] = 0; data[1] = sample0 >> 0; data[2] = sample0 >> 8; data[3] = sample0 >> 16; data += 4; } break; case AUDIO_MODE_DITHER: while (len--) { sample0 = audio_linear_dither(24, *left++, &left_dither, stats); data[0] = 0; data[1] = sample0 >> 0; data[2] = sample0 >> 8; data[3] = sample0 >> 16; data += 4; } break; default: return 0; } return nsamples * 4; }}/* * NAME: audio_pcm_s32be() * DESCRIPTION: write a block of signed 32-bit big-endian PCM samples */unsigned int audio_pcm_s32be(unsigned char *data, unsigned int nsamples, mad_fixed_t const *left, mad_fixed_t const *right, enum audio_mode mode, struct audio_stats *stats){ unsigned int len; register signed long sample0, sample1; len = nsamples; if (right) { /* stereo */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) { sample0 = audio_linear_round(24, *left++, stats); sample1 = audio_linear_round(24, *right++, stats); data[0] = sample0 >> 16; data[1] = sample0 >> 8; data[2] = sample0 >> 0; data[3] = 0; data[4] = sample1 >> 16; data[5] = sample1 >> 8; data[6] = sample1 >> 0; data[7] = 0; data += 8; } break; case AUDIO_MODE_DITHER: while (len--) { sample0 = audio_linear_dither(24, *left++, &left_dither, stats); sample1 = audio_linear_dither(24, *right++, &right_dither, stats); data[0] = sample0 >> 16; data[1] = sample0 >> 8; data[2] = sample0 >> 0; data[3] = 0; data[4] = sample1 >> 16; data[5] = sample1 >> 8; data[6] = sample1 >> 0; data[7] = 0; data += 8; } break; default: return 0; } return nsamples * 4 * 2; } else { /* mono */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) { sample0 = audio_linear_round(24, *left++, stats); data[0] = sample0 >> 16; data[1] = sample0 >> 8; data[2] = sample0 >> 0; data[3] = 0; data += 4; } break; case AUDIO_MODE_DITHER: while (len--) { sample0 = audio_linear_dither(24, *left++, &left_dither, stats); data[0] = sample0 >> 16; data[1] = sample0 >> 8; data[2] = sample0 >> 0; data[3] = 0; data += 4; } break; default: return 0; } return nsamples * 4; }}staticunsigned char linear2mulaw(mad_fixed_t sample){ unsigned int sign, mulaw; enum { BIAS = (mad_fixed_t) ((0x10 << 1) + 1) << (MAD_F_FRACBITS - 13) }; if (sample < 0) { sample = BIAS - sample; sign = 0x7f; } else { sample = BIAS + sample; sign = 0xff; } mulaw = 0x7f; if (sample < MAD_F_ONE) { unsigned int segment; unsigned long mask; segment = 7; for (mask = 1L << (MAD_F_FRACBITS - 1); !(sample & mask); mask >>= 1) --segment; mulaw = ((segment << 4) | ((sample >> (MAD_F_FRACBITS - 1 - (7 - segment) - 4)) & 0x0f)); } mulaw ^= sign;# if 0 if (mulaw == 0x00) mulaw = 0x02;# endif return mulaw;}staticmad_fixed_t mulaw2linear(unsigned char mulaw){ int sign, segment, mantissa, value; enum { BIAS = (0x10 << 1) + 1 }; mulaw = ~mulaw; sign = (mulaw >> 7) & 0x01; segment = (mulaw >> 4) & 0x07; mantissa = (mulaw >> 0) & 0x0f; value = ((0x21 | (mantissa << 1)) << segment) - BIAS; if (sign) value = -value; return (mad_fixed_t) value << (MAD_F_FRACBITS - 13);}/* * NAME: audio_mulaw_round() * DESCRIPTION: convert a linear PCM value to 8-bit ISDN mu-law */inlineunsigned char audio_mulaw_round(mad_fixed_t sample, struct audio_stats *stats){ clip(&sample, stats); return linear2mulaw(sample);}/* * NAME: audio_mulaw_dither() * DESCRIPTION: convert a linear PCM value to dithered 8-bit ISDN mu-law */inlineunsigned char audio_mulaw_dither(mad_fixed_t sample, struct audio_dither *dither, struct audio_stats *stats){ unsigned char mulaw; /* noise shape */ sample += dither->error[0]; clip(&sample, stats); mulaw = linear2mulaw(sample); /* error feedback */ dither->error[0] = sample - mulaw2linear(mulaw); return mulaw;}/* * NAME: audio_pcm_mulaw() * DESCRIPTION: write a block of 8-bit mu-law encoded samples */unsigned int audio_pcm_mulaw(unsigned char *data, unsigned int nsamples, mad_fixed_t const *left, mad_fixed_t const *right, enum audio_mode mode, struct audio_stats *stats){ unsigned int len; len = nsamples; if (right) { /* stereo */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) { data[0] = audio_mulaw_round(*left++, stats); data[1] = audio_mulaw_round(*right++, stats); data += 2; } break; case AUDIO_MODE_DITHER: while (len--) { data[0] = audio_mulaw_dither(*left++, &left_dither, stats); data[1] = audio_mulaw_dither(*right++, &right_dither, stats); data += 2; } break; default: return 0; } return nsamples * 2; } else { /* mono */ switch (mode) { case AUDIO_MODE_ROUND: while (len--) *data++ = audio_mulaw_round(*left++, stats); break; case AUDIO_MODE_DITHER: while (len--) *data++ = audio_mulaw_dither(*left++, &left_dither, stats); break; default: return 0; } return nsamples; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -