⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ima4.c

📁 这个库实现了录象功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************* ima4.c libquicktime - A library for reading and writing quicktime/avi/mp4 files. http://libquicktime.sourceforge.net Copyright (C) 2002 Heroine Virtual Ltd. Copyright (C) 2002-2007 Members of the libquicktime project. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************/ #include "lqt_private.h"#define LQT_LIBQUICKTIME#include <quicktime/lqt_codecapi.h>#include <stdlib.h>#include <string.h>#include "audiocodec.h"#define LOG_DOMAIN "ima4"/* Known by divine revelation */#define BLOCK_SIZE 0x22#define SAMPLES_PER_BLOCK 0x40typedef struct{/* Starting information for all channels during encoding. */	int *last_samples, *last_indexes;/* Buffer for samples */        int16_t * sample_buffer; /* SAMPLES_PER_BLOCK * channels (interleaved) */        int sample_buffer_size;  /* samples from last en/decode call */ /* Buffer for chunks */        int chunk_buffer_size;        int chunk_buffer_alloc;        int chunk_samples;        uint8_t * chunk_buffer;        uint8_t * chunk_buffer_ptr;        int decode_initialized;  } quicktime_ima4_codec_t;static int ima4_step[89] = {    7, 8, 9, 10, 11, 12, 13, 14, 16, 17,    19, 21, 23, 25, 28, 31, 34, 37, 41, 45,    50, 55, 60, 66, 73, 80, 88, 97, 107, 118,    130, 143, 157, 173, 190, 209, 230, 253, 279, 307,    337, 371, 408, 449, 494, 544, 598, 658, 724, 796,    876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,    2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,    5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,    15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767};static int ima4_index[16] = {    -1, -1, -1, -1, 2, 4, 6, 8,    -1, -1, -1, -1, 2, 4, 6, 8};/* ================================== private for ima4 */static void ima4_decode_sample(int *predictor, int *nibble, int *index, int *step){	int difference, sign;/* Get new index value */	*index += ima4_index[*nibble];	if(*index < 0) *index = 0; 	else 	if(*index > 88) *index = 88;/* Get sign and magnitude from *nibble */	sign = *nibble & 8;	*nibble = *nibble & 7;/* Get difference */	difference = *step >> 3;	if(*nibble & 4) difference += *step;	if(*nibble & 2) difference += *step >> 1;	if(*nibble & 1) difference += *step >> 2;/* Predict value */	if(sign) 	*predictor -= difference;	else 	*predictor += difference;	if(*predictor > 32767) *predictor = 32767;	else	if(*predictor < -32768) *predictor = -32768;/* Update the step value */	*step = ima4_step[*index];}static void ima4_decode_block(quicktime_audio_map_t *atrack, int16_t *output, unsigned char *input, int channels){	int predictor;	int index;	int step;	int nibble, nibble_count;	unsigned char *input_end = input + BLOCK_SIZE;/* Get the chunk header */	predictor = *input++ << 8;	predictor |= *input++;	index = predictor & 0x7f;	if(index > 88) index = 88;	predictor &= 0xff80;	if(predictor & 0x8000) predictor -= 0x10000;	step = ima4_step[index];/* Read the input buffer sequentially, one nibble at a time */	nibble_count = 0;	while(input < input_end)	{		nibble = nibble_count ? (*input++  >> 4) & 0x0f : *input & 0x0f;		ima4_decode_sample(&predictor, &nibble, &index, &step);		*output = predictor;                output += channels;		nibble_count ^= 1;	}}static void ima4_encode_sample(int *last_sample, int *last_index, int *nibble, int next_sample){	int difference, new_difference, mask, step;	difference = next_sample - *last_sample;	*nibble = 0;	step = ima4_step[*last_index];	new_difference = step >> 3;	if(difference < 0)	{		*nibble = 8;		difference = -difference;	}	mask = 4;	while(mask)	{		if(difference >= step)		{			*nibble |= mask;			difference -= step;			new_difference += step;		}		step >>= 1;		mask >>= 1;	}	if(*nibble & 8)		*last_sample -= new_difference;	else		*last_sample += new_difference;	if(*last_sample > 32767) *last_sample = 32767;	else	if(*last_sample < -32767) *last_sample = -32767;	*last_index += ima4_index[*nibble];	if(*last_index < 0) *last_index = 0;	else	if(*last_index > 88) *last_index= 88;}static void ima4_encode_block(quicktime_audio_map_t *atrack, unsigned char *output, int16_t *input, int step, int channel){	quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;	int i, nibble_count = 0, nibble, header;/* Get a fake starting sample */	header = codec->last_samples[channel];/* Force rounding. */	if(header < 0x7fc0) header += 0x40;	if(header < 0) header += 0x10000;	header &= 0xff80;	*output++ = (header & 0xff00) >> 8;	*output++ = (header & 0x80) + (codec->last_indexes[channel] & 0x7f);	for(i = 0; i < SAMPLES_PER_BLOCK; i++)	{		ima4_encode_sample(&(codec->last_samples[channel]), 							&(codec->last_indexes[channel]), 							&nibble, 							*input);		if(nibble_count)			*output++ |= (nibble << 4);		else			*output = nibble;		input += step;		nibble_count ^= 1;	}}/* Convert the number of samples in a chunk into the number of bytes in that *//* chunk.  The number of samples in a chunk should end on a block boundary. */static long ima4_samples_to_bytes(long samples, int channels)  {  return (samples / SAMPLES_PER_BLOCK) * BLOCK_SIZE * channels;  }#if 0static int read_audio_chunk(quicktime_t * file, int track,                            long chunk,                            uint8_t ** buffer, int * buffer_alloc)  {  int bytes, samples, bytes_from_samples;  bytes = lqt_read_audio_chunk(file, track, chunk, buffer, buffer_alloc, &samples);  //  bytes_from_samples = ima4_samples_to_bytes(samples, file->atracks[track].channels);  //  if(bytes > bytes_from_samples)  //    return bytes_from_samples;  //  else    return bytes;  }#endif/* =================================== public for ima4 */static int delete_codec(quicktime_audio_map_t *atrack){	quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;	if(codec->last_samples) free(codec->last_samples);	if(codec->last_indexes) free(codec->last_indexes);        if(codec->chunk_buffer)          free(codec->chunk_buffer);        if(codec->sample_buffer)          free(codec->sample_buffer);                free(codec);	return 0;}static int decode(quicktime_t *file, void * _output, long samples, int track){	int64_t chunk_sample;	int64_t i;        int64_t chunk;        int16_t * output = (int16_t*)_output;        int samples_decoded, samples_copied;	quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;        int samples_to_skip = 0;        if(!_output) /* Global initialization */          {          return 0;          }        if(!codec->decode_initialized)          {          codec->decode_initialized = 1;          codec->sample_buffer = malloc(sizeof(*(codec->sample_buffer)) * file->atracks[track].channels * SAMPLES_PER_BLOCK);                    /* Read first chunk */                    codec->chunk_buffer_size =            lqt_read_audio_chunk(file, track, file->atracks[track].current_chunk,                                 &(codec->chunk_buffer),                                 &(codec->chunk_buffer_alloc), &(codec->chunk_samples));                    if(codec->chunk_buffer_size <= 0)            return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -