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

📄 pcm.c

📁 这个库实现了录象功能
💻 C
📖 第 1 页 / 共 3 页
字号:
        in *= 0x1000000 ;        mantissa = lrint (floor (in)) ;        out [2] = (mantissa >> 16) & 0xFF ;        out [1] = (mantissa >> 8) & 0xFF ;        out [0] = mantissa & 0xFF ;        return ;} /* double64_le_write *//* 32 bit float (Big Endian) */static void encode_fl32_be(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  int i;  float * input = (float*)_input;  for(i = 0; i < num_samples; i++)    {    float32_be_write(*input, codec->chunk_buffer_ptr);    codec->chunk_buffer_ptr+=4;    input++;    }    }static void decode_fl32_be(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  int i;  float * output = (float*)(*_output);    for(i = 0; i < num_samples; i++)    {    *output = float32_be_read(codec->chunk_buffer_ptr);    codec->chunk_buffer_ptr+=4;    output++;    }  *_output = output;  }/* 32 bit float (Little Endian) */static void encode_fl32_le(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  int i;  float * input = (float*)_input;  for(i = 0; i < num_samples; i++)    {    float32_le_write(*input, codec->chunk_buffer_ptr);    codec->chunk_buffer_ptr+=4;    input++;    }  }static void decode_fl32_le(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  int i;  float * output = (float*)(*_output);    for(i = 0; i < num_samples; i++)    {    *output = float32_le_read(codec->chunk_buffer_ptr);    codec->chunk_buffer_ptr+=4;    output++;    }  *_output = output;  }/* 64 bit float (Big Endian) */static void encode_fl64_be(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  int i;  double * input = (double*)_input;  for(i = 0; i < num_samples; i++)    {    double64_be_write(*input, codec->chunk_buffer_ptr);    codec->chunk_buffer_ptr+=8;    input++;    }    }static void decode_fl64_be(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  int i;  double * output = (double*)(*_output);    for(i = 0; i < num_samples; i++)    {    *output = double64_be_read(codec->chunk_buffer_ptr);    codec->chunk_buffer_ptr+=8;    output++;    }  *_output = output;  }/* 64 bit float (Little Endian) */static void encode_fl64_le(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  int i;  double * input = (double*)_input;  for(i = 0; i < num_samples; i++)    {    double64_le_write(*input, codec->chunk_buffer_ptr);    codec->chunk_buffer_ptr+=8;    input++;    }  }static void decode_fl64_le(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  int i;  double * output = (double*)(*_output);    for(i = 0; i < num_samples; i++)    {    *output = double64_le_read(codec->chunk_buffer_ptr);    codec->chunk_buffer_ptr+=8;    output++;    }  *_output = output;  }/* ulaw *//* See ulaw_tables.h for the tables references here */#define ENCODE_ULAW(src, dst) if(src >= 0) dst = ulaw_encode[src / 4]; else dst = 0x7F & ulaw_encode[src / -4] #define DECODE_ULAW(src, dst) dst = ulaw_decode [src]static void encode_ulaw(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  int i;  int16_t * input = (int16_t*)_input;    for(i = 0; i < num_samples; i++)    {    ENCODE_ULAW(input[0], codec->chunk_buffer_ptr[0]);    codec->chunk_buffer_ptr++;    input++;    }  }static void decode_ulaw(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  int i;  /* The uint32_t is intentional: Interpreting integers as unsigned has less pitfalls */  int16_t * output = (int16_t*)(*_output);    for(i = 0; i < num_samples; i++)    {    DECODE_ULAW(codec->chunk_buffer_ptr[0], output[0]);    codec->chunk_buffer_ptr++;    output++;    }  *_output = output;  }/* alaw *//* See alaw_tables.h for the tables references here */#define ENCODE_ALAW(src, dst) if(src >= 0) dst = alaw_encode[src / 16]; else dst = 0x7F & alaw_encode[src / -16] #define DECODE_ALAW(src, dst) dst = alaw_decode [src]static void encode_alaw(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  int i;  int16_t * input = (int16_t*)_input;    for(i = 0; i < num_samples; i++)    {    ENCODE_ALAW(input[0], codec->chunk_buffer_ptr[0]);    codec->chunk_buffer_ptr++;    input++;    }  }static void decode_alaw(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  int i;  /* The uint32_t is intentional: Interpreting integers as unsigned has less pitfalls */  int16_t * output = (int16_t*)(*_output);    for(i = 0; i < num_samples; i++)    {    DECODE_ALAW(codec->chunk_buffer_ptr[0], output[0]);    codec->chunk_buffer_ptr++;    output++;    }  *_output = output;  }/* Generic decode function */static int read_audio_chunk(quicktime_t * file, int track,                            long chunk,                            uint8_t ** buffer, int * buffer_alloc)  {  int bytes, samples, bytes_from_samples;  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_pcm_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  bytes = lqt_read_audio_chunk(file, track, chunk, buffer, buffer_alloc, &samples);  bytes_from_samples = samples * codec->block_align;  if(bytes > bytes_from_samples)    return bytes_from_samples;  else    return bytes;  }static int decode_pcm(quicktime_t *file, void * _output, long samples, int track)  {  int64_t chunk, chunk_sample;  quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_pcm_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  void * output;  int64_t samples_to_skip = 0;  int samples_in_chunk;  int samples_decoded, samples_to_decode;      if(!codec->initialized)    {    if(codec->init_decode)      codec->init_decode(file, track);        /* Read the first audio chunk */    codec->chunk_buffer_size = read_audio_chunk(file,                                                track, file->atracks[track].current_chunk,                                                &(codec->chunk_buffer),                                                &(codec->chunk_buffer_alloc));    if(codec->chunk_buffer_size <= 0)      {      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "EOF at the beginning of track");      return 0;      }    codec->chunk_buffer_ptr = codec->chunk_buffer;    codec->initialized = 1;    }  if(!_output) /* Global initialization */    {    return 0;    }    if(file->atracks[track].current_position != file->atracks[track].last_position)    {    /* Seeking happened */    quicktime_chunk_of_sample(&chunk_sample, &chunk,                              file->atracks[track].track,                              file->atracks[track].current_position);    /* Read the chunk */        if(file->atracks[track].current_chunk != chunk)      {      file->atracks[track].current_chunk = chunk;      codec->chunk_buffer_size = read_audio_chunk(file,                                                  track, file->atracks[track].current_chunk,                                                  &(codec->chunk_buffer),                                                  &(codec->chunk_buffer_alloc));      if(codec->chunk_buffer_size <= 0)        return 0;            codec->chunk_buffer_ptr = codec->chunk_buffer;      }    else      {      codec->chunk_buffer_ptr = codec->chunk_buffer;      }        /* Skip samples */        samples_to_skip = file->atracks[track].current_position - chunk_sample;    if(samples_to_skip < 0)      {      lqt_log(file, LQT_LOG_ERROR, LOG_DOMAIN, "Cannot skip backwards");      samples_to_skip = 0;      }    codec->chunk_buffer_ptr = codec->chunk_buffer + samples_to_skip * codec->block_align;    }  samples_decoded = 0;  output = _output;    while(samples_decoded < samples)    {    /* Get new chunk if necessary */    if(codec->chunk_buffer_ptr - codec->chunk_buffer >= codec->chunk_buffer_size)      {      file->atracks[track].current_chunk++;      codec->chunk_buffer_size = read_audio_chunk(file,                                                  track, file->atracks[track].current_chunk,                                                  &(codec->chunk_buffer),                                                  &(codec->chunk_buffer_alloc));      if(codec->chunk_buffer_size <= 0)        break;      codec->chunk_buffer_ptr = codec->chunk_buffer;      }    /* Decode */    samples_in_chunk = ((codec->chunk_buffer_size-(int)(codec->chunk_buffer_ptr - codec->chunk_buffer)))      /codec->block_align;        samples_to_decode = samples - samples_decoded;        if(samples_to_decode > samples_in_chunk)      samples_to_decode = samples_in_chunk;    codec->decode(codec, samples_to_decode * track_map->channels, &output);    samples_decoded += samples_to_decode;    }  file->atracks[track].last_position = file->atracks[track].current_position + samples_decoded;  return samples_decoded;  }/* Generic encode function */static int encode_pcm(quicktime_t *file, void * input, long samples, int track)  {  int result;  quicktime_atom_t chunk_atom;    quicktime_audio_map_t *track_map = &(file->atracks[track]);  quicktime_pcm_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;  quicktime_trak_t *trak = track_map->track;    /* Initialize */  if(!codec->initialized)    {    /* Initialize AVI header */        if(trak->strl)      {      /* strh stuff */      trak->strl->strh.dwRate = track_map->samplerate;      trak->strl->strh.dwScale = 1;      trak->strl->strh.dwSampleSize = codec->block_align / track_map->channels;            /* WAVEFORMATEX stuff */            trak->strl->strf.wf.f.WAVEFORMAT.nBlockAlign = codec->block_align;      trak->strl->strf.wf.f.WAVEFORMAT.nAvgBytesPerSec = codec->block_align * track_map->samplerate;      trak->strl->strf.wf.f.PCMWAVEFORMAT.wBitsPerSample = trak->strl->strh.dwSampleSize * 8;      }        if(codec->init_encode)      codec->init_encode(file, track);    codec->initialized = 1;    }  if(!input || !samples)    return 0;    /* Allocate chunk buffer */  if(codec->chunk_buffer_alloc < samples * codec->block_align)    {    codec->chunk_buffer_alloc = samples * codec->block_align + 1024;    codec->chunk_buffer = realloc(codec->chunk_buffer, codec->chunk_buffer_alloc);    }  codec->chunk_buffer_ptr = codec->chunk_buffer;  codec->encode(codec, samples * track_map->channels, input);  quicktime_write_chunk_header(file, trak, &chunk_atom);  result = quicktime_write_data(file, codec->chunk_buffer, samples * codec->block_align);  quicktime_write_chunk_footer(file, trak, track_map->current_chunk, &chunk_atom, samples);  file->atracks[track].current_chunk++;		    /* defeat fwrite's return */  if(result)     result = 0;   else     result = 1;       return result;  }/* Set parameters */static int set_parameter_pcm(quicktime_t *file,                              int track,                              const char *key,                              const void *value)  {  quicktime_audio_map_t *atrack = &(file->atracks[track]);  quicktime_pcm_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;  if(!strcasecmp(key, "pcm_little_endian"))    {    codec->little_endian = *((int*)(value));    }  else if(!strcasecmp(key, "pcm_format"))    {    if(!strcasecmp((char*)(value), "Integer (16 bit)"))      codec->format = FORMAT_INT_16;    else if(!strcasecmp((char*)(value), "Integer (24 bit)"))      codec->format = FORMAT_INT_24;    else if(!strcasecmp((char*)(value), "Integer (32 bit)"))      codec->format = FORMAT_INT_32;    else if(!strcasecmp((char*)(value), "Float (32 bit)"))      codec->format = FORMAT_FLOAT_32;    else if(!strcasecmp((char*)(value), "Float (64 bit)"))      codec->format = FORMAT_FLOAT_64;    }  return 0;  }/* Destructor */static int delete_pcm(quicktime_audio_map_t *atrack)  {  quicktime_pcm_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;  if(codec->chunk_buffer)    {    free(codec->chunk_buffer);    }  free(codec);  return 0;  }void quicktime_init_codec_twos(quicktime_audio_map_t *atrack)  {  quicktime_pcm_codec_t *codec;  quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;    /* Init public items */  codec_base->delete_acodec = delete_pcm;  codec_base->decode_audio = decode_pcm;  codec_base->encode_audio = encode_pcm;    /* Init private items */  codec = calloc(1, sizeof(*codec));  codec_base->priv = codec;    switch(atrack->track->mdia.minf.stbl.stsd.table[0].sample_size)    {    case 8:      codec->block_align = atrack->channels;      atrack->sample_format = LQT_SAMPLE_INT8;      codec->encode = encode_8;      codec->decode = decode_8;      break;    case 16:      codec->block_align = 2 * atrack->channels;      atrack->sample_format = LQT_SAMPLE_INT16;#ifdef WORDS_BIGENDIAN      codec->encode = encode_s16;      codec->decode = decode_s16;#else      codec->encode = encode_s16_swap;      codec->decode = decode_s16_swap;#endif      break;    case 24:      codec->block_align = 3 * atrack->channels;      atrack->sample_format = LQT_SAMPLE_INT32;      codec->encode = encode_s24_be;      codec->decode = decode_s24_be;      break;    }  }void quicktime_init_codec_sowt(quicktime_audio_map_t *atrack)  {  quicktime_pcm_codec_t *codec;  quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;    /* Init public items */  codec_base->delete_acodec = delete_pcm;  codec_base->decode_audio = decode_pcm;  codec_base->encode_audio = encode_pcm;  //  codec_base->wav_id = 0x01;  /* Init private items */  codec = calloc(1, sizeof(*codec));  codec_base->priv = codec;    switch(atrack->track->mdia.minf.stbl.stsd.table[0].sample_size)    {    case 8:      codec->block_align = atrack->channels;      atrack->sample_format = LQT_SAMPLE_UINT8;      codec->encode = encode_8;      codec->decode = decode_8;      break;    case 16:      codec->block_align = 2 * atrack->channels;      atrack->sample_format = LQT_SAMPLE_INT16;#ifdef WORDS_BIGENDIAN      codec->encode = encode_s16_swap;      codec->decode = decode_s16_swap;#else      codec->encode = encode_s16;      codec->decode = decode_s16;#endif      break;    case 24:      codec->block_align = 3 * atrack->channels;      atrack->sample_format = LQT_SAMPLE_INT32;      codec->encode = encode_s24_le;      codec->decode = decode_s24_le;      break;    }  }static void init_encode_in24(quicktime_t * file, int track)  {  quicktime_audio_map_t *atrack = &(file->atracks[track]);  quicktime_pcm_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;  quicktime_stsd_table_t *table = &(atrack->track->mdia.minf.stbl.stsd.table[0]);    /* Initialize version 1 stsd */  quicktime_set_stsd_audio_v1(table, 1, 3, 3 * atrack->channels, 2);

⌨️ 快捷键说明

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