OpenAL alBufferData возвращает неизвестную ошибку при вызове - PullRequest
2 голосов
/ 23 мая 2019

Я пытаюсь заставить 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

, который выглядит мне как правильный тип данных ... Я в полномпотеря здесь.Что-то о попытке прочитать данные из моего маркера данных в мой размер повреждает данные.

1 Ответ

0 голосов
/ 24 мая 2019

Оказывается, что-то не так с функцией 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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...