如何合并(混合)两个立体声mp3音频文件

时间:2018-12-19 05:09:40

标签: c++ c audio mp3 voice

我有两个立体声文件: 1.mp3、2.mp3 我想以特殊方式合并这两个音频文件

使用此代码,我可以合并它们,以便当我播放 3.mp3 3.mp3 包含两个文件的数据。 >然后 2.mp3 一吹一吹

#include <windows.h>


INT ReadMyFile(LPCWSTR lpcszFilePath, PBYTE* pbytReadBuffer, DWORD* dwSize)
{
    HANDLE hndlRead;
    OVERLAPPED ol = {0};
    BOOL bRetValCheck;
    INT nReturnValue = TRUE;

    hndlRead = CreateFileW(lpcszFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hndlRead != INVALID_HANDLE_VALUE)
    {
        *dwSize = GetFileSize(hndlRead, NULL);
        *pbytReadBuffer = (PBYTE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *dwSize);

        if (pbytReadBuffer != NULL)
        {
            bRetValCheck = ReadFile(hndlRead, *pbytReadBuffer, *dwSize, NULL, &ol);

            if (!bRetValCheck)
            {
                nReturnValue = FALSE;
                HeapFree(GetProcessHeap(), 0, pbytReadBuffer);
            }
        }
        else
        {       
            nReturnValue = FALSE;
        }
        CloseHandle(hndlRead);
    }
    else
    {
        nReturnValue = FALSE;
    }   
    return nReturnValue;
}
int main()
{
    DWORD dwSiaze_IN = 0;
    DWORD dwSiaze_OUT = 0;
    PBYTE pbytPlainText_IN = NULL;
    PBYTE pbytPlainText_OUT = NULL;
    PBYTE pOutputBuffer;
    DWORD dwOutputSize = 0;
    DWORD dwBytesWritten;
    HANDLE hndlWrite;

    if (ReadMyFile(L"1.mp3", &pbytPlainText_IN, &dwSiaze_IN) && ReadMyFile(L"2.mp3", &pbytPlainText_OUT, &dwSiaze_OUT))
    {

        dwOutputSize = dwSiaze_IN + dwSiaze_OUT;
        pOutputBuffer = (PBYTE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwOutputSize);

        int i = 0;
        // For mp3 Header
        for (i=0; i<11; i++)
        {
            pOutputBuffer[i] = pbytPlainText_IN[i];
        }

        for (i=11; i<dwOutputSize/2; i++)
        {
            pOutputBuffer[i] = pbytPlainText_IN[i];
        }
        int tmp = 11;
        for (i=dwOutputSize/2; i<dwOutputSize; i++)
        {
            pOutputBuffer[i] = pbytPlainText_OUT[tmp];
            tmp++;
        }

        hndlWrite = CreateFileW(L"3.mp3", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hndlWrite != INVALID_HANDLE_VALUE)
        {
            SetFilePointer(hndlWrite, 0, 0, FILE_END);
            WriteFile(hndlWrite, pOutputBuffer, dwOutputSize, &dwBytesWritten, NULL);
            CloseHandle(hndlWrite);
        }
    }
    return 0;
}

但是我想让数据同步...

我的意思是我希望 3.mp3 是一个立体声文件,其左声道具有 1.mp3 ,而在其立体声通道中具有 2.mp3 正确的频道

2 个答案:

答案 0 :(得分:0)

您可以通过执行以下步骤来实现:

  1. 解码1.mp3和2.mp3文件

  2. 保存解码后的原始数据(在不同的WAVE格式的文件中或在内存中)

  3. 将1.mp3解码的原始数据的第一或第二通道值替换为2.mp3解码的原始数据的第一或第二通道值(请注意,这会导致音频质量下降)

  4. 基于合并的音频数据特征构造WAVE(原始音频数据格式)标头

  5. 使用构造的WAVE标头和合并的音频数据创建WAVE格式的3.wav文件

  6. 将3.wav文件转换为3.mp3文件格式

执行这些步骤需要您了解:

  • 如何解码mp3文件以获取原始数据

  • 如何处理缓冲区中的数据字节

  • WAVE声音文件格式

  • 如何将wav转换为mp3

要对不同格式的音频文件进行解码和编码,可以使用一些适当的声音库(例如BASS),这可以帮助您执行1和6步。要构造WAVE格式的音频数据,您应该熟悉WAVE File Format以及如何在缓冲区中对齐音频数据通道-这有助于您执行3、4和5步

答案 1 :(得分:0)

mp3是压缩的音频数据。您不能使用文件操作直接混合它们。 您可以做的一件事是使用ffmpeg库将mp3转换为原始PCM,混合通道,然后再将其转换回mp3。