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

📄 pcm.c

📁 这个库实现了录象功能
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************* pcm.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"#include "ulaw_tables.h"#include "alaw_tables.h"#define LQT_LIBQUICKTIME#include <quicktime/lqt_codecapi.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "audiocodec.h"#define LOG_DOMAIN "pcm"#ifndef HAVE_LRINT#define lrint(x) ((long int)(x))#endiftypedef enum  {    FORMAT_INT_16,    FORMAT_INT_24,    FORMAT_INT_32,    FORMAT_FLOAT_32,    FORMAT_FLOAT_64,  } format_t;typedef struct quicktime_pcm_codec_s  {  uint8_t * chunk_buffer;  uint8_t * chunk_buffer_ptr;  int chunk_buffer_size;  int chunk_buffer_alloc;      int block_align;  int sample_buffer_size;  int last_chunk_samples;  void (*encode)(struct quicktime_pcm_codec_s*, int num_samples, void * input);  void (*decode)(struct quicktime_pcm_codec_s*, int num_samples, void ** output);  void (*init_encode)(quicktime_t * file, int track);  void (*init_decode)(quicktime_t * file, int track);  int initialized;  /* Encoding parameters for lpcm */  format_t format;  int little_endian;  } quicktime_pcm_codec_t;/* 8 bit per sample, signedness and endian neutral */static void encode_8(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  memcpy(codec->chunk_buffer_ptr, _input, num_samples);  }static void decode_8(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  uint8_t * output = (uint8_t *)(*_output);  memcpy(output, codec->chunk_buffer_ptr, num_samples);  codec->chunk_buffer_ptr += num_samples;  output += num_samples;  *_output = output;  }/* 16 bit per sample, without swapping */static void encode_s16(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  memcpy(codec->chunk_buffer_ptr, _input, 2 * num_samples);  }static void decode_s16(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  uint8_t * output = (uint8_t *)(*_output);  memcpy(output, codec->chunk_buffer_ptr, 2 * num_samples);  codec->chunk_buffer_ptr += 2 * num_samples;    output += 2 * num_samples;  *_output = output;  }/* 16 bit per sample with swapping */static void encode_s16_swap(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  int i;  uint8_t * input = (uint8_t*)_input;  for(i = 0; i < num_samples; i++)    {    codec->chunk_buffer_ptr[0] = input[1];    codec->chunk_buffer_ptr[1] = input[0];    codec->chunk_buffer_ptr+=2;    input+=2;    }  }static void decode_s16_swap(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  int i;  uint8_t * output = (uint8_t*)(*_output);    for(i = 0; i < num_samples; i++)    {    output[0] = codec->chunk_buffer_ptr[1];    output[1] = codec->chunk_buffer_ptr[0];    codec->chunk_buffer_ptr+=2;    output+=2;    }  *_output = output;  }/* 24 bit per sample (Big Endian) */static void encode_s24_be(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  int i;  /* The uint32_t is intentional: Interpreting integers as unsigned has less pitfalls */  uint32_t * input = (uint32_t*)_input;  for(i = 0; i < num_samples; i++)    {    codec->chunk_buffer_ptr[0] = (*input & 0xff000000) >> 24;    codec->chunk_buffer_ptr[1] = (*input & 0xff0000) >> 16;    codec->chunk_buffer_ptr[2] = (*input & 0xff00) >> 8;    codec->chunk_buffer_ptr+=3;    input++;    }    }static void decode_s24_be(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  int i;  /* The uint32_t is intentional: Interpreting integers as unsigned has less pitfalls */  uint32_t * output = (uint32_t*)(*_output);    for(i = 0; i < num_samples; i++)    {    *output  = (uint32_t)(codec->chunk_buffer_ptr[0]) << 24;    *output |= (uint32_t)(codec->chunk_buffer_ptr[1]) << 16;    *output |= (uint32_t)(codec->chunk_buffer_ptr[2]) <<  8;    codec->chunk_buffer_ptr+=3;    output++;    }  *_output = output;  }/* 24 bit per sample (Little Endian) */static void encode_s24_le(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  int i;  /* The uint32_t is intentional: Interpreting integers as unsigned has less pitfalls */  uint32_t * input = (uint32_t*)_input;  for(i = 0; i < num_samples; i++)    {    codec->chunk_buffer_ptr[2] = (*input & 0xff000000) >> 24;    codec->chunk_buffer_ptr[1] = (*input & 0xff0000) >> 16;    codec->chunk_buffer_ptr[0] = (*input & 0xff00) >> 8;    codec->chunk_buffer_ptr+=3;    input++;    }  }static void decode_s24_le(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  int i;  /* The uint32_t is intentional: Interpreting integers as unsigned has less pitfalls */  uint32_t * output = (uint32_t*)(*_output);    for(i = 0; i < num_samples; i++)    {    *output  = (uint32_t)(codec->chunk_buffer_ptr[2]) << 24;    *output |= (uint32_t)(codec->chunk_buffer_ptr[1]) << 16;    *output |= (uint32_t)(codec->chunk_buffer_ptr[0]) <<  8;    codec->chunk_buffer_ptr+=3;    output++;    }  *_output = output;  }/* 32 bit per sample, without swapping */static void encode_s32(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  memcpy(codec->chunk_buffer_ptr, _input, 4 * num_samples);  }static void decode_s32(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  uint8_t * output = (uint8_t *)(*_output);  memcpy(output, codec->chunk_buffer_ptr, 4 * num_samples);  codec->chunk_buffer_ptr += 4 * num_samples;    output += 4 * num_samples;  *_output = output;  }/* 32 bit per sample with swapping */static void encode_s32_swap(quicktime_pcm_codec_t*codec, int num_samples, void * _input)  {  int i;  uint8_t * input = (uint8_t*)_input;  for(i = 0; i < num_samples; i++)    {    codec->chunk_buffer_ptr[0] = input[3];    codec->chunk_buffer_ptr[1] = input[2];    codec->chunk_buffer_ptr[2] = input[1];    codec->chunk_buffer_ptr[3] = input[0];    codec->chunk_buffer_ptr+=4;    input+=4;    }  }static void decode_s32_swap(quicktime_pcm_codec_t*codec, int num_samples, void ** _output)  {  int i;  uint8_t * output = (uint8_t*)(*_output);    for(i = 0; i < num_samples; i++)    {    output[0] = codec->chunk_buffer_ptr[3];    output[1] = codec->chunk_buffer_ptr[2];    output[2] = codec->chunk_buffer_ptr[1];    output[3] = codec->chunk_buffer_ptr[0];    codec->chunk_buffer_ptr+=4;    output+=4;    }  *_output = output;  }/* Floating point formats *//* Sample read/write functions, taken from libsndfile */static floatfloat32_be_read (unsigned char *cptr){       int             exponent, mantissa, negative ;        float   fvalue ;        negative = cptr [0] & 0x80 ;        exponent = ((cptr [0] & 0x7F) << 1) | ((cptr [1] & 0x80) ? 1 : 0) ;        mantissa = ((cptr [1] & 0x7F) << 16) | (cptr [2] << 8) | (cptr [3]) ;        if (! (exponent || mantissa))                return 0.0 ;        mantissa |= 0x800000 ;        exponent = exponent ? exponent - 127 : 0 ;        fvalue = mantissa ? ((float) mantissa) / ((float) 0x800000) : 0.0 ;        if (negative)                fvalue *= -1 ;        if (exponent > 0)                fvalue *= (1 << exponent) ;        else if (exponent < 0)                fvalue /= (1 << abs (exponent)) ;        return fvalue ;} /* float32_be_read */static floatfloat32_le_read (unsigned char *cptr){       int             exponent, mantissa, negative ;        float   fvalue ;        negative = cptr [3] & 0x80 ;        exponent = ((cptr [3] & 0x7F) << 1) | ((cptr [2] & 0x80) ? 1 : 0) ;        mantissa = ((cptr [2] & 0x7F) << 16) | (cptr [1] << 8) | (cptr [0]) ;        if (! (exponent || mantissa))                return 0.0 ;        mantissa |= 0x800000 ;        exponent = exponent ? exponent - 127 : 0 ;        fvalue = mantissa ? ((float) mantissa) / ((float) 0x800000) : 0.0 ;        if (negative)                fvalue *= -1 ;        if (exponent > 0)                fvalue *= (1 << exponent) ;        else if (exponent < 0)                fvalue /= (1 << abs (exponent)) ;        return fvalue ;} /* float32_le_read */static doubledouble64_be_read (unsigned char *cptr){       int             exponent, negative ;        double  dvalue ;        negative = (cptr [0] & 0x80) ? 1 : 0 ;        exponent = ((cptr [0] & 0x7F) << 4) | ((cptr [1] >> 4) & 0xF) ;        /* Might not have a 64 bit long, so load the mantissa into a double. */        dvalue = (((cptr [1] & 0xF) << 24) | (cptr [2] << 16) | (cptr [3] << 8) | cptr [4]) ;        dvalue += ((cptr [5] << 16) | (cptr [6] << 8) | cptr [7]) / ((double) 0x1000000) ;        if (exponent == 0 && dvalue == 0.0)                return 0.0 ;        dvalue += 0x10000000 ;        exponent = exponent - 0x3FF ;        dvalue = dvalue / ((double) 0x10000000) ;        if (negative)                dvalue *= -1 ;        if (exponent > 0)                dvalue *= (1 << exponent) ;        else if (exponent < 0)                dvalue /= (1 << abs (exponent)) ;        return dvalue ;} /* double64_be_read */static doubledouble64_le_read (unsigned char *cptr){       int             exponent, negative ;        double  dvalue ;        negative = (cptr [7] & 0x80) ? 1 : 0 ;        exponent = ((cptr [7] & 0x7F) << 4) | ((cptr [6] >> 4) & 0xF) ;        /* Might not have a 64 bit long, so load the mantissa into a double. */        dvalue = (((cptr [6] & 0xF) << 24) | (cptr [5] << 16) | (cptr [4] << 8) | cptr [3]) ;        dvalue += ((cptr [2] << 16) | (cptr [1] << 8) | cptr [0]) / ((double) 0x1000000) ;        if (exponent == 0 && dvalue == 0.0)                return 0.0 ;        dvalue += 0x10000000 ;        exponent = exponent - 0x3FF ;        dvalue = dvalue / ((double) 0x10000000) ;        if (negative)                dvalue *= -1 ;        if (exponent > 0)                dvalue *= (1 << exponent) ;        else if (exponent < 0)                dvalue /= (1 << abs (exponent)) ;        return dvalue ;} /* double64_le_read */static voidfloat32_le_write (float in, unsigned char *out){       int             exponent, mantissa, negative = 0 ;        memset (out, 0, sizeof (int)) ;        if (in == 0.0)                return ;        if (in < 0.0)        {       in *= -1.0 ;                negative = 1 ;                } ;        in = frexp (in, &exponent) ;        exponent += 126 ;        in *= (float) 0x1000000 ;        mantissa = (((int) in) & 0x7FFFFF) ;        if (negative)                out [3] |= 0x80 ;        if (exponent & 0x01)                out [2] |= 0x80 ;        out [0] = mantissa & 0xFF ;        out [1] = (mantissa >> 8) & 0xFF ;        out [2] |= (mantissa >> 16) & 0x7F ;        out [3] |= (exponent >> 1) & 0x7F ;        return ;} /* float32_le_write */static voidfloat32_be_write (float in, unsigned char *out){       int             exponent, mantissa, negative = 0 ;        memset (out, 0, sizeof (int)) ;        if (in == 0.0)                return ;        if (in < 0.0)        {       in *= -1.0 ;                negative = 1 ;                } ;        in = frexp (in, &exponent) ;        exponent += 126 ;        in *= (float) 0x1000000 ;        mantissa = (((int) in) & 0x7FFFFF) ;        if (negative)                out [0] |= 0x80 ;        if (exponent & 0x01)                out [1] |= 0x80 ;        out [3] = mantissa & 0xFF ;        out [2] = (mantissa >> 8) & 0xFF ;        out [1] |= (mantissa >> 16) & 0x7F ;        out [0] |= (exponent >> 1) & 0x7F ;        return ;} /* float32_be_write */static voiddouble64_be_write (double in, unsigned char *out){       int             exponent, mantissa ;        memset (out, 0, sizeof (double)) ;        if (in == 0.0)                return ;        if (in < 0.0)        {       in *= -1.0 ;                out [0] |= 0x80 ;                } ;        in = frexp (in, &exponent) ;        exponent += 1022 ;        out [0] |= (exponent >> 4) & 0x7F ;        out [1] |= (exponent << 4) & 0xF0 ;        in *= 0x20000000 ;        mantissa = lrint (floor (in)) ;        out [1] |= (mantissa >> 24) & 0xF ;        out [2] = (mantissa >> 16) & 0xFF ;        out [3] = (mantissa >> 8) & 0xFF ;        out [4] = mantissa & 0xFF ;        in = fmod (in, 1.0) ;        in *= 0x1000000 ;        mantissa = lrint (floor (in)) ;        out [5] = (mantissa >> 16) & 0xFF ;        out [6] = (mantissa >> 8) & 0xFF ;        out [7] = mantissa & 0xFF ;        return ;} /* double64_be_write */static voiddouble64_le_write (double in, unsigned char *out){       int             exponent, mantissa ;        memset (out, 0, sizeof (double)) ;        if (in == 0.0)                return ;        if (in < 0.0)        {       in *= -1.0 ;                out [7] |= 0x80 ;                } ;        in = frexp (in, &exponent) ;        exponent += 1022 ;        out [7] |= (exponent >> 4) & 0x7F ;        out [6] |= (exponent << 4) & 0xF0 ;        in *= 0x20000000 ;        mantissa = lrint (floor (in)) ;        out [6] |= (mantissa >> 24) & 0xF ;        out [5] = (mantissa >> 16) & 0xFF ;        out [4] = (mantissa >> 8) & 0xFF ;        out [3] = mantissa & 0xFF ;        in = fmod (in, 1.0) ;

⌨️ 快捷键说明

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