打电话时返回未知错误

OpenAL alBufferData returning unknown error when called

本文关键字:错误 未知 返回 打电话      更新时间:2023-10-16

我试图开放式游戏引擎来播放一个简单的音频剪辑。我找不到一个好的库来处理WAV文件,因此我决定尝试自己解码它们。我一直在遇到一些问题,并正在重写我的问题以获得更有针对性的回应。

这是我正在处理WAV文件的代码。该代码专门跳过了一个额外的标头元数据,我发现这引起了我一些问题。然后,我将数据保存到返回呼叫的缓冲区中,然后将声音发送到OpenAL中。

in.read(buffer, 4);//"data" chunk. 
        while(strncmp(buffer, "data", 4) != 0)
        {
            if(strncmp(buffer, "LIST", 4) == 0)
            {
                in.read(buffer, 2);
                in.ignore(ConvertToInt(buffer, 2) - 1);
            }
            in.read(buffer, 4);
        }
        std::cout << "current place: " << buffer[0] << buffer[1] << buffer[2] << buffer[3] << std::endl;
        in.read(buffer, 4); //Get size of the data
        size = ConvertToInt(buffer, 4);
        std::cout << "size: " << size << std::endl;
        if(size < 0)
        {
            std::cout << "Error here, not a valid WAV file, size of file reports 0.n This was found instead: "
                      << size << std::endl;
        }
        char* data = new char[size];
        in.read(data, size);//Read audio data into buffer, return.
        in.close();
        return data;    

这是我的问题。没有音乐播放。我得到的只是一个非常短暂的挤压,然后当我杀死程序时,我会听到我的扬声器流行。当我打印出数据时,我会看到一些非常有趣的东西,这使我认为某些东西被打破了:

Print out data from caller -------------------------------------------------------
8   *   É   k   F   <   t   Å     C  ═   )  ç   ⌠   <  º  é  σ  J   α   6   *      2   » ² B   ë ·  ² 7 ≈ ≥ · É ⌠ F ∙ ` ≤ t ° y ⌠ 3 ∙ t ÷ i · ≈ ° ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ ═ 

我安装了一个名为riffpad的程序,并用它来查看WAV文件,并将第一个数据匹配的第一个数据匹配,但随后它们都变成了相等的符号,这似乎是错误的。我不确定为什么会发生这种情况。我以为也许是因为它的返回方式,但是这种打印是从创建数据的地方而不是使用的位置,并且在两个地方看起来都一样。有人知道我在这里做错了什么?

更新:

打印整个文件会产生此输出:

Print out data from caller -------------------------------------------------------
R I F F ~ 4 ü   W A V E f m t                D ¼      ▒          L I S T R      I N F O I A R T        K o m i k u     I C M T í       U R L :   h t t p : / / f r e e m u s i c a r c h i v e . o r g / m u s i c / K o m i k u / C a p t a i n _ G l o u g l o u s _ I n c r e d i b l e _ W e e k _ S o u n d t r a c k / S k a t e
 C o m m e n t s :   h t t p : / / f r e e m u s i c a r c h i v e . o r g /
 C u r a t o r :
 C o p y r i g h t :       I C R D        2 0 1 8 - 0 7 - 1 4 T 0 4 : 3 7 : 0 5   I G N R        E l e c t r o n i c     I N A M        S k a t e   I P R D .       C a p t a i n   G l o u g l o u ' s   I n c r e d i b l e   W e e k   S o u n d t r a c k   I P R T        4   I S F T        L a v f 5 8 . 2 7 . 1 0 3   d a t a   3 ü   8   *   É   k   F   <   t   Å     C  ═   )  ç   ⌠   <  º  é  σ  J   α   6   *      2   » ² B   ë ·  ² 7 ≈ ≥ · É ⌠ F ∙ ` ≤ t ° y ⌠ 3 ∙ t ÷ i · ≈ ° · ≈ °  ⁿ ╜ ⁿ    ▐   ú    H  :  Ü  ┴  _  1 l  ß  ∩   ≈  / 2  r  ó  ≡  U  ¥  C  W  4       :  ¬  r  G ƒ  å Γ   ─  1  ∞  π  ╓   z  ▒    ò  ∞  é  >    ╣  ô  J 
 ┌  ]  i

看上去像正确的数据一样……我在这里完全亏损。关于尝试从数据标记到我的大小的数据的一些事情会破坏数据。

事实证明我正在使用的ifstream.read((函数有问题。这是我的解决方案可行的解决方案,没有错误检查,我将在重构到接口时添加。

static int ConvertToInt(char* buffer, int len)
    {
        int a = 0;
        if(!IsBigEndian())
        {
            for(int i = 0; i < len; ++i)
            {
                ((char*)&a)[i] = buffer[i];
            }
        }
        else
        {
            for(int i = 0; i < len; ++i)
            {
                ((char*)&a)[3-i] = buffer[i];
            }
        }
        return a;
    }
//Header values for WAV file. Values are in bytes. 
    const U32 WAV_CHANNELS_OFFSET = 22;
    const U32 WAV_CHANNELS_SIZE = 2;
    const U32 WAV_SAMPLE_RATE_OFFSET = 24;
    const U32 WAV_SAMPLE_RATE_SIZE = 4;
    const U32 WAV_BYTE_RATE_OFFSET = 34;
    const U32 WAV_BYTE_RATE_SIZE = 2;
    const U32 WAV_DATA_OFFSET = 36;
    const U32 WAV_DATA_HEADER_SIZE = 4;
    const U32 WAV_DATA_SIZE_INFO_SIZE = 2;
    static void GetIndexRange(char* source, char* dest, int offset, int len)
    {
        for(int i = 0; i < len; ++i)
        {
            dest[i] = source[offset + i];
        }
    }
    //Location and size of data is found here: http://www.topherlee.com/software/pcm-tut-wavformat.html
    static char* LoadWAV(string filename, int& channels, int& sampleRate, int& bps, int& size)
    {
        std::ifstream in(filename.c_str());
        //Get the total size of the file
        in.seekg(0, in.end);
        int totalSize = (int)in.tellg();
        in.seekg(0, in.beg);
        //Save the whole file to a buffer using read
        char* buffer = new char[totalSize];
        in.read(buffer, totalSize);
        //Extract info about the audio file.
        char info[4];
        GetIndexRange(buffer, info, WAV_CHANNELS_OFFSET, WAV_CHANNELS_SIZE);
        channels = ConvertToInt(info, WAV_CHANNELS_SIZE);
        GetIndexRange(buffer, info, WAV_SAMPLE_RATE_OFFSET, WAV_SAMPLE_RATE_SIZE);
        sampleRate = ConvertToInt(info, WAV_SAMPLE_RATE_SIZE);
        GetIndexRange(buffer, info, WAV_BYTE_RATE_OFFSET, WAV_BYTE_RATE_SIZE);
        bps = ConvertToInt(info, WAV_BYTE_RATE_SIZE);
        //Extract the data itself.
        GetIndexRange(buffer, info, WAV_DATA_OFFSET, WAV_DATA_HEADER_SIZE);
        U32 POSITION = WAV_DATA_OFFSET + WAV_DATA_HEADER_SIZE;
        U32 moveTo = 0;
        while(strncmp(info, "data", 4) != 0)
        {
            if(strncmp(info, "LIST", 4) == 0)
            {
                GetIndexRange(buffer, info, POSITION, WAV_DATA_SIZE_INFO_SIZE);
                moveTo = ConvertToInt(info, WAV_DATA_SIZE_INFO_SIZE);           
            }
            //Set new position, move foreward one for rough check
            GetIndexRange(buffer, info, moveTo, WAV_DATA_HEADER_SIZE);
            POSITION = moveTo;
            moveTo = ++POSITION;
        }
        U32 DATA_SIZE_POSITION = POSITION - 1 + WAV_DATA_HEADER_SIZE;
        GetIndexRange(buffer, info, DATA_SIZE_POSITION, 4);
        size = ConvertToInt(info, 4);
        return buffer;
    }