Speex手册(九)——代码示例

A 代码示例     

         这部分展示运用Speex API编码和解码语音的代码示例,可通过调用如下指令编码和解码一个文件:

                %  sampleenc  in_file.sw  |  sampledec  out_file.sw

其中的文件都是每个样本16比特编码(机器自然字节顺序)的原始文件(无文件头)。

A.1  sampleenc.c

        sampleenc读取一个原始的16位采样的文件,进行编码并输出Speex流到stdout。注意所用的数据包与speexenc/speexdec是不兼容的。

       

/*代码清单A.1:sampleenc源代码*/
#include 
  
  
   
   
#include 
   
   
    
    

/*The frame size in hardcoded for this sample code but it doesn't have to be*/
#define FRAME_SIZE 160                
int main(int argc, char **argv)
{
    char *inFile;
    FILE *fin;
    short in[FRAME_SIZE];
    float input[FRAME_SIZE];
    char cbits[200];
    int nbBytes;
    /*Holds the state of the encoder*/
    void *state;                      
    /*Holds bits so they can be read and written to by the Speex routines*/
    SpeexBits bits;                   
    int i, tmp;
    
    /*Create a new encoder state in narrowband mode*/
    state = speex_encoder_init(&speex_nb_mode);
    
    /*Set the quality to 8 (15 kbps)*/
    tmp = 8;
    speex_encoder_ctl(state, SPEEX_SET_QUALITY, &tmp);
    
    inFile = argv[1];
    fin = fopen(inFile, "r");
    
    /*Initialization of the structure that holds the bits*/
    speex_bits_init(&bits);
    while(1)
    {
        /*Read a 16 bits/sample audio frame*/
        fread(in, sizeof(short), FRAME_SIZE, fin);
        if (feof(fin))
            break;
        /*Copy the 16 bits values to float so Speex can work on them*/
        for (i = 0; i < FRAME_SIZE, i++)
            input[i] = in[i];
        
        /*Flusf all the bits in the struct so we can encode a new frame*/
        speex_bits_reset(&bits);
        
        /*Encode the frame*/
        speex_encode(state, input, &bits);
        /*Copy the bits to an array of char that can be written*/
        nbBytes = speex_bits_write(&bits, cbits, 200);
        
        /*Write the size of the frame first. This is what sampledec expects but
        it's likely to be different in your own application*/
        fwrite(&nbBytes, sizeof(int), 1, stdout);
        /*Write the compressed data*/
        fwrite(cbits, 1, nbBytes, stdout);
    }
    
    /*Destroy the encoder state*/
    speex_encoder_destroy(state);
    /*Destroy the bit-packing struct*/
    speex_bits_destroy(&bits);
    fclose(fin);
    return 0;
}

   
   
  
  

A.2  sampledec.c
        sampledec从stdin中读取Speex流,解码并输出到一个原始16位采样文件。注意所用的数据包与speexenc/speexdec是不兼容的。
       
/*清单A.2:sampledec源代码*/
#include 
   
   
    
    
#include 
    
    
     
     

/*The frame size in hardcoded for this sample code but it doesn't have to be*/
#define FRAME_SIZE 160
int main(int argc, char **argv)
{
    char *outFile;
    FILE *fout;
    /*Holds the audio that will be written to file (16 bits per sample)*/
    short out[FRAME_SIZE];
    /*Speex handle samples as float,so we need an array of floats*/
    float output[FRAME_SIZE];
    char cbits[200];
    int nbBytes;
    /*Holds the state of the decoder*/
    void * state;
    /*Holds bits so they can be read and written to by Speex routines*/
    SpeexBits bits;
    int i, tmp;
    
    /*Create a new decoder state in narrowband mode*/
    state = speex_decoder_init(&speex_nb_mode);
    /*Set the perceptual enhancement on*/
    tmp = 1;
    speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp);
    
    outFile = argv[1];
    fout = fopen(outFile, "w");
    
    /*Initialization of the structure that holds the bits*/
    speex_bits_init(&bits);
    while(1)
    {
        /*Read the size encoded by sampleenc, this part will likely be
          different in your application*/
        fread(&nbBytes, sizeof(int), 1, stdin);
        fprintf(stderr, "nbBytes: %d\n", nbBytes);
        if (feof(stdin))
            break;
        
        /*Read the "packet" encoded by sampleenc*/
        fread(cbits, 1, nbBytes, stdin);
        /*Copy the data into the bit-stream struct*/
        speex_bits_read_from(&bits, cbits, nbBytes);
        
        /*Decode the data*/
        speex_decode(state, &bits, output);
        
        /*Copy from float to short (16 bits) for output*/
        for (i = 0; i < FRAME_SIZE; i++)
            out[i] = output[i];
        
        /*Write the decoded audio to file*/
        fwrite(out, sizeof(short), FRAME_SIZE, fout);
    }
    
    /*Destroy the decoder state*/
    speex_decoder_destroy(state);
    /*Destroy the bit-stream truct*/
    speex_bits_destroy(&bits);
    fclose(fout);
    return 0;
}

    
    
   
   
B  Speex抖动缓冲器示例代码
       
/*清单B.1:对Speex数据包应用抖动缓冲器代码示例*/
#include 
   
   
    
    
#include "speex_jitter_buffer.h"

#ifndef NULL
#define NULL 0
#endif

void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate)
{
    jitter->dec = decoder;
    speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size);
    
    jitter->packets = jitter_buffer_init(jitter->frame_size);
    
    speex_bits_init(&jitter->current_packet);
    jitter->valid_bits = 0;
}

void speex_jitter_destroy(SpeexJitter *jitter)
{
    jitter_buffer_destroy(jitter->packets);
    speex_bits_destroy(&jitter->current_packet);
}

void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp)
{
    JitterBufferPacket p;
    p.data = packet;
    p.len = len;
    p.timestamp = timestamp;
    p.span = jitter->frame_size;
    jitter_buffer_put(jitter->packet, &p);
}

void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *current_timestamp)
{
    int i;
    int ret;
    spx_int32_t activity;
    char data[2048];
    JitterBufferPacket packet;
    packet.data = data;
    
    if(jitter->valid_bits)
    {
        /*Try decoding last received packet*/
        ret = speex_decode_init(jitter->dec, &jitter->current_packet, out);
        if(ret == 0)
        {
            jitter_buffer_tick(jitter->packets);
            return;
        }
        else
        {
            jitter->valid_bits = 0;
        }
    }
    
    ret = jitter_buffer_get(jitter->packet, &packet, jitter->frame_size, NULL);
    
    if (ret != JITTER_BUFFER_OK)
    {
        /*Packet is late or lost*/
        speex_decode_int(jitter->dec, NULL, out);
    }
    else
    {
        speex_bits_read_from(&jitter->current_packet, packet.data, packet.len);
        /*Decode packet*/
        ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
        if(ret == 0)
        {
            jitter->valid_bits = 1;
        }
        else
        {
            /*Error while decoding*/
            for (i = 0; i < jitter->frame_size; i++)
                out[i] = 0;
        }
    }
    
    speex_decoder_ctl(jitter->dec, SPEEX_GET_ACTIVITY, &activity);
    if (activity < 30)
        jitter_buffer_update_delay(jitter->packets, &packet, NULL);
    jitter_buffer_tick(jitter->packets);
}

int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter)
{
    return jitter_buffer_get_pointer_timestamp(jitter->packets);
}

   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值