【问题标题】:OpenAL alBufferData returning unknown error when calledOpenAL alBufferData 调用时返回未知错误
【发布时间】:2019-10-09 14:30:12
【问题描述】:

我正在尝试让 OpenAL 为游戏引擎播放一个简单的音频剪辑。我一直无法找到一个好的库来处理 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

在我看来,这就像正确的数据类型......我在这里完全不知所措。试图从我的数据标记读取数据到我的大小会破坏数据。

【问题讨论】:

    标签: c++ openal


    【解决方案1】:

    原来我使用的 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;
        }
    

    【讨论】:

      猜你喜欢
      • 2011-08-20
      • 2012-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-28
      • 1970-01-01
      相关资源
      最近更新 更多