音频混音算法

混音相关代码来源于doubango,自己做了提取,个人感觉效果还不错 


#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
typedef int int16_t;
typedef unsigned int uint32_t;
typedef unsigned int tsk_size_t;
#define tsk_null NULL
#define TSK_DEBUG_ERROR(FMT, ...) fprintf(stderr, "***ERROR: function: \"%s()\" \nfile: \"%s\" \nline: \"%u\" \nMSG: " FMT "\n", __FUNCTION__,  __FILE__, __LINE__, ##__VA_ARGS__);
#define TSK_DEBUG_INFO(FMT, ...) fprintf(stderr, "***INFO: function: \"%s()\" \nfile: \"%s\" \nline: \"%u\" \nMSG: " FMT "\n", __FUNCTION__,  __FILE__, __LINE__, ##__VA_ARGS__);
#define TSK_DEBUG_WARN(FMT, ...) fprintf(stderr, "***WARN: function: \"%s()\" \nfile: \"%s\" \nline: \"%u\" \nMSG: " FMT "\n", __FUNCTION__,  __FILE__, __LINE__, ##__VA_ARGS__);
#define TSK_SAFE_FREE(ptr) (void)tsk_free((void**)(&ptr));
//音频包
typedef struct audio_buffer_s {
    int16_t* audio;
    size_t size;
    struct audio_buffer_s* next;
} audio_buffer_t;

void* tsk_calloc(tsk_size_t num, tsk_size_t size)
{
    void* ret = tsk_null;

    if(num && size) {
        ret = calloc(num, size);

        if(!ret) {
            TSK_DEBUG_ERROR("Memory allocation failed. num=%u and size=%u", num, size);
        }
    }

    return ret;
}
void* tsk_realloc (void* ptr, tsk_size_t size)
{
    void *ret = tsk_null;

    if(size) {
        if(ptr) {
            if(!(ret = realloc(ptr, size))) {
                TSK_DEBUG_ERROR("Memory reallocation failed");
            }
        }

        else {
            if(!(ret = calloc(size, 1))) {
                TSK_DEBUG_ERROR("Memory allocation (%u) failed", size);
            }
        }
    }

    return ret;
}
void tsk_free(void** ptr)
{
    if(ptr && *ptr) {
        free(*ptr);
        *ptr = tsk_null;
    }
}
static void _mix16(const int16_t* pInBufferPtr, float dInBufferVolume, int16_t* pOutBufferPtr, size_t nSizeToMixInBytes) {
    uint32_t i;
    float mixedSample;
    size_t nSizeToMixInSamples = (nSizeToMixInBytes >> 1);
    assert(pInBufferPtr&&pOutBufferPtr);

    for(i = 0; i < nSizeToMixInSamples; ++i) {
        mixedSample = ((float) pOutBufferPtr[i] / 32768.0f) + (((float) pInBufferPtr[i] / 32768.0f) * dInBufferVolume);

        if(mixedSample < -1.0f) { mixedSample = -1.0f; }

        if(mixedSample > +1.0f) { mixedSample = +1.0f; }

        pOutBufferPtr[i] = (int16_t)(mixedSample * 32768.0f);
    }
}
static audio_buffer_t* mix(audio_buffer_t* in_audios , float dInBufferVolume) {
    int i;
    audio_buffer_t* in=in_audios;
    audio_buffer_t* out=tsk_null; 
    if(!in_audios) { goto FAIL; }

    out=tsk_calloc(sizeof(audio_buffer_t),1);

    if(!out) { goto FAIL; }

    while(in) {
        if(!out->audio) { out->audio=tsk_calloc(1,in->size*2); }

        else if(out->size<in->size) {out->audio=tsk_realloc(out->audio,in->size*2); out->size=in->size;}

        if(!out->audio) { goto FAIL; }

        _mix16(in->audio,dInBufferVolume,out->audio,in->size);
		in=in->next;
    }

    return out;
FAIL:

    if(out&&out->audio) {
        TSK_SAFE_FREE(out->audio);
    }

    TSK_SAFE_FREE(out);
    return out;
} 
int main()
{
    int i;
    audio_buffer_t* in=tsk_calloc(sizeof(audio_buffer_t),8);
    audio_buffer_t* audio=in;
    audio_buffer_t* out=NULL;

    for(  i=0; i<8; i++) {
        audio->size=160;
        audio->audio=tsk_calloc(1,audio->size*2);

        if(i<7) {
            audio->next=tsk_calloc(sizeof(audio_buffer_t),8);
            audio=audio->next;
        }
    }

    out=mix(in,0.8f);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值