AMR encoding based on third-party opencore-amr-0.1.5 libraries
Support PCM2AMR,WAV2AMR
Test directory: PCM2AMR.C pcm2amr.c,linux environment, ready to migrate to Android phone
Resources Download Link: http://download.csdn.net/detail/yuanchunsi/9917689
//------------------------------------------------------------------------------------------------------------- -------------//
The Pcm2amr.h code is as follows:
#ifndef Pcm2amr_h
#define Pcm2amr_h
#include <stdio.h>
#include <stdint.h>
#include <interf_enc.h>
#include <unistd.h>
#include <stdlib.h>
#include "Wavreader.h"
#define Amr_magic_number "#! Amr\n "
#define PCM_FRAME_SIZE//8khz 8000*0.02=160
#define MAX_AMR_FRAME_SIZE 32
#define AMR_FRAME_COUNT_PER_SECOND 50
int amrencodemode[] = {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200}; AMR Encoding Method
typedef struct
{
Char chchunkid[4];
int nchunksize;
}xchunkheader;
typedef struct
{
Short Nformattag;
Short nchannels;
int nsamplespersec;
int navgbytespersec;
Short nblockalign;
Short nbitspersample;
}waveformat;
typedef struct
{
Short Nformattag;
Short nchannels;
int nsamplespersec;
int navgbytespersec;
Short nblockalign;
Short nbitspersample;
Short nexsize;
}waveformatx;
typedef struct
{
Char chriffid[4];
int nriffsize;
Char chriffformat[4];
}riffheader;
typedef struct
{
Char chfmtid[4];
int nfmtsize;
Waveformat WF;
}fmtblock;
Wave Audio sampling frequency is 8khz
Number of audio sample units = 8000*0.02 = 160 (determined by sampling frequency)
Number of channels 1:160
2:160*2 = 320
BPS decision Sample size
bps = 8--and 8-bit unsigned char
--16-bit unsigned short
int Encodewavefiletoamrfile (const char* pchwavefilename, const char* pchamrfilename, int nchannels, int nbitspersample );
Decode AMR file into wave file
int Decodeamrfiletowavefile (const char* pchamrfilename, const char* pchwavefilename);
#endif
The PCM2AMR.C code is as follows:
#include "Pcm2amr.h"
Skip wave file header from wave file, direct to PCM audio data
void Skiptopcmaudiodata (file* fpwave)
{
Riffheader riff;
Fmtblock FMT;
Xchunkheader Chunk;
Waveformatx wfx;
int bdatablock = 0;
1. Read RIFF Head
Fread (&riff, 1, sizeof (Riffheader), fpwave);
2. Read the FMT block-if the fmt.nfmtsize>16 description needs to have a secondary size that is not read
Fread (&chunk, 1, sizeof (Xchunkheader), fpwave);
if (chunk.nchunksize>16)
{
Fread (&WFX, 1, sizeof (WAVEFORMATX), fpwave);
}
Else
{
memcpy (Fmt.chfmtid, Chunk.chchunkid, 4);
Fmt.nfmtsize = chunk.nchunksize;
Fread (&FMT.WF, 1, sizeof (Waveformat), fpwave);
}
3. Go to data block-some also have fact blocks and so on.
while (!bdatablock)
{
Fread (&chunk, 1, sizeof (Xchunkheader), fpwave);
if (!memcmp (Chunk.chchunkid, "Data", 4))
{
Bdatablock = 1;
Break
}
Because this is not a data block, we skip the block.
Fseek (Fpwave, Chunk.nchunksize, seek_cur);
}
}
Read a full PCM audio frame from the wave file
Return value: 0-Error >0: Full frame size
int Readpcmframe (short speech[], file* fpwave, int nchannels, int nbitspersample)
{
int nread = 0;
int x = 0, y=0;
unsigned short ush1=0, ush2=0, ush=0;
Raw PCM Audio frame data
unsigned char pcmframe_8b1[pcm_frame_size];
unsigned char pcmframe_8b2[pcm_frame_size<<1];
unsigned short pcmframe_16b1[pcm_frame_size];
unsigned short pcmframe_16b2[pcm_frame_size<<1];
if (nbitspersample==8 && nchannels==1)
{
Nread = Fread (pcmframe_8b1, (NBITSPERSAMPLE/8), Pcm_frame_size*nchannels, Fpwave);
for (x=0; x<pcm_frame_size; x + +)
{
SPEECH[X] = (short) ((short) pcmframe_8b1[x] << 7);
}
}
Else
if (nbitspersample==8 && nchannels==2)
{
Nread = Fread (pcmframe_8b2, (NBITSPERSAMPLE/8), Pcm_frame_size*nchannels, Fpwave);
For (x=0, y=0; y<pcm_frame_size; y++,x+=2)
{
1-Take the left channel of two channels
Speech[y] = (short) ((short) pcmframe_8b2[x+0] << 7);
2-Take the right channel of two channels
Speech[y] = (short) ((short) pcmframe_8b2[x+1] << 7);
3-Take the average of two channels
USH1 = (short) pcmframe_8b2[x+0];
USH2 = (short) pcmframe_8b2[x+1];
Ush = (ush1 + ush2) >> 1;
Speech[y] = (short) ((short) Ush << 7);
}
}
Else
if (nbitspersample==16 && nchannels==1)
{
Nread = Fread (pcmframe_16b1, (NBITSPERSAMPLE/8), Pcm_frame_size*nchannels, Fpwave);
if (nread = = pcm_frame_size*nchannels) {
for (x=0; x<pcm_frame_size; x + +)
{
SPEECH[X] = (short) pcmframe_16b1[x+0];
}
}
}
Else
if (nbitspersample==16 && nchannels==2)
{
Nread = Fread (pcmframe_16b2, (NBITSPERSAMPLE/8), Pcm_frame_size*nchannels, Fpwave);
For (x=0, y=0; y<pcm_frame_size; y++,x+=2)
{
Speech[y] = (short) pcmframe_16b2[x+0];
Speech[y] = (short) ((int) ((int) pcmframe_16b2[x+0] + (int) pcmframe_16b2[x+1])) >> 1;
}
}
if (nread! = pcm_frame_size*nchannels) return-1;
printf ("Readpcmframe done\n");
return nread;
}
Wave Audio sampling frequency is 8khz
Number of audio sample units = 8000*0.02 = 160 (determined by sampling frequency)
Number of channels 1:160
2:160*2 = 320
BPS decision Sample size
bps = 8--and 8-bit unsigned char
--16-bit unsigned short
int Encodewavefiletoamrfile (const char* pchwavefilename, const char* pchamrfilename, int nchannels, int nbitspersample )
int main ()
{
File* Fpwave;
File* Fpamr;
/* Input speech vector */
Short speech[160];
/* Counters */
int Byte_counter, frames = 0, bytes = 0;
/* Pointer to encoder State structure */
int *enstate;
/* Requested mode */
Enum Mode req_mode = MR122;
int DTX = 0;
/* bitstream filetype */
unsigned char amrframe[max_amr_frame_size];
#if 0
WAV and PCM data differences are only WAV more data header
Fpwave = fopen ("./input.wav", "RB");
#else
Fpwave = fopen ("./AUDIO.PCM", "RB");
#endif
if (Fpwave = = NULL)
{
return 0;
}
Create and initialize AMR files
FPAMR = fopen ("./out.amr", "WB");
if (fpamr = = NULL)
{
Fclose (Fpwave);
return 0;
}
/* Write magic number to indicate single channel AMR file storage format */
bytes = fwrite (amr_magic_number, sizeof (char), strlen (Amr_magic_number), FPAMR);
#if 0
/* Skip to PCM audio data*/
Skip WAV header is both PCM raw data
Skiptopcmaudiodata (Fpwave);
#endif
Enstate = Encoder_interface_init (DTX);
while (1)
{
Read one PCM frame
if (! Readpcmframe (Speech, Fpwave, Nchannels, nbitspersample)) break;
if ( -1 = = Readpcmframe (speech, Fpwave, 1, 16)) {
printf ("Readpcmframe failed\n");
Break
}
frames++;
/* Call Encoder */
Byte_counter = Encoder_interface_encode (Enstate, Req_mode, speech, Amrframe, 0);
printf ("Byte_counter = =%d\n", byte_counter);
bytes + = Byte_counter;
Fwrite (amrframe, sizeof (unsigned char), byte_counter, FPAMR);
}
Encoder_interface_exit (enstate);
Fclose (FPAMR);
Fclose (Fpwave);
return frames;
}
//--------------------------------------------------------------------------------------------------------- -----------------//