Аудио данные (неподписанные символы), которыми манипулировали, не могут быть воспроизведены - PullRequest
1 голос
/ 29 марта 2012

У меня проблемы с воспроизведением аудиоданных после того, как ими манипулируют.Единственный API, который я использую - это API-интерфейс alsa lib в Linux (Ubuntu) на языке C. Я получаю данные из 16-битного целочисленного волнового файла в массиве без знака (называемом buffer1), используя read (), и buffer1 может воспроизводиться правильно.Я хочу, чтобы данные передавались в другой массив без знака (называемый buffer2) того же размера.Если я просто создаю цикл с buffer2 [i] = buffer1 [i], это работает: buffer2 может воспроизводиться правильно.Но для того, чтобы манипулировать данными, я конвертирую их в массив float, а затем обратно в unsigned char (До сих пор я не манипулировал аудио данными; я просто конвертировал их в float, а затем обратно в unsigned char, чтобы проверить, как это работает).Но теперь buffer2 не издает звук, хотя все его значения строго идентичны значениям buffer1 (я сделал printf из многих значений buffer1 и buffer2; все они идентичны) ... Все, что я сделал, это приведение из unsigned к floatи наоборот ...

Пожалуйста, есть идеи, что случилось?

Виктор

1 Ответ

0 голосов
/ 29 марта 2012

Значения в buffer1 и buffer2 не могут быть идентичными, иначе это будет работать. Возможно, форматирование, которое вы используете в своей команде printf, маскирует различия (% i,% f и т. Д.). Вместо того, чтобы использовать printf, попробуйте установить точку останова и посмотреть на значения, используя ваш отладчик. Это может помочь выявить, что на самом деле идет не так.

РЕДАКТИРОВАТЬ:

Учитывая ваши комментарии о том, как вы выполняете актерский состав, я думаю, что теперь могу помочь. Исходные данные имеют тип unsigned char. На большинстве платформ это будет целочисленное значение в диапазоне от 0 до 255. Вы хотите преобразовать это значение в число с плавающей точкой для выполнения ваших манипуляций. Чтобы сделать данные значимыми как тип с плавающей запятой для любых манипуляций, вы хотите масштабировать этот диапазон между +/- 1.0. Для этого и используется переменная «scale» в следующем коде.

#include <iostream>
#include <math.h>

int main()
{

    const int BUFFER_LEN = 6;
    const unsigned char channelDataIN[] = {0,255, 1, 254, 2, 253};

    unsigned char channelDataOUT[BUFFER_LEN];
    float channelDataF[BUFFER_LEN];

    std::cout.precision(5);

    float scale = powf(2.f, 8.f*sizeof(unsigned char) ) - 1.f;


    for (int mm = 0; mm < BUFFER_LEN; ++mm)
    {        
        std::cout << "Original = " << (int)channelDataIN[mm] << std::endl;

        channelDataF[mm] =  (float)(channelDataIN[mm]) * 2.f/scale - 1.f; //Float cast
        std::cout << "Float conversion = " << channelDataF[mm] << std::endl;

        channelDataOUT[mm] = (unsigned char) ceil(  ( 1.f+channelDataF[mm] ) * scale/2.f    );
        std::cout << "Recovered = " << (int)channelDataOUT[mm] << std::endl;

        if (channelDataIN[mm] == channelDataOUT[mm])
            std::cout << "The output precisely equals the input" << std::endl << std::endl;
        else
            std::cout << "The output != input" << std::endl << std::endl;
    }

    return 0;
}

Выходной массив символов без знака после преобразования значений обратно идентичен входному массиву. Это вывод из кода. , .

Original = 0
Float conversion = -1
Recovered = 0
The output precisely equals the input

Original = 255
Float conversion = 1
Recovered = 255
The output precisely equals the input

Original = 1
Float conversion = -0.99216
Recovered = 1
The output precisely equals the input

Original = 254
Float conversion = 0.99216
Recovered = 254
The output precisely equals the input

Original = 2
Float conversion = -0.98431
Recovered = 2
The output precisely equals the input

Original = 253
Float conversion = 0.98431
Recovered = 253
The output precisely equals the input
...