2015-07-27 3 views
0

В настоящее время я пытаюсь собрать декодированные аудиоданные (из нескольких форматов) для выполнения определенных звуковых манипуляций (используя * .wav-файл для тестирования).Соберите декодированный звук из libav как двухместные

У меня есть класс, который обрабатывает все декодирование через FFmpeg libav. Если извлечь данные как unit8_t в вектор, и

for (int i = 0; i < bytevector.size(); i++) { 
    fwrite(&bytevector[i], sizeof (uint8_t), 1, outfile2); 
} 

к исходному файлу и воспроизвести его с помощью play -t raw -r 44100 -b16 -c 1 -e signed sound.raw это звучит прекрасно.

Однако, как это возможно, чтобы иметь все правильную информацию о как удваивается, когда файл, например, составляет 2 байта на образце и информация frame->data дается в uint8_t? Файлы wav, которые я тестировал, это 44100/16бит/1 канал. (У меня уже есть код, который изменит uint8_t * на двойной)

Открытие тех же файлов с помощью Scilab покажет половину размера байтового вектора как удвоение.

WAV файл в Scilab как массив двойников показывает:
-0,1, -0,099, -0,098, ..., 0,099, +0,1

против байт вектора:
51, 243, 84, 243, 117, 243, ...

Can 51 и 243 действительно образуют двойной? Любые предложения о том, как пройти эту проблему?

код ниже для справки:

while ((av_read_frame(formatContext, &readingPacket)) == 0) { 
     if (readingPacket.stream_index == audioStreamIdx) { 
      AVPacket decodingPacket = readingPacket; 

      while (decodingPacket.size > 0) { 
       int gotFrame = 0; 
       int result = avcodec_decode_audio4(context, frame, &gotFrame, &decodingPacket); 

       if (result < 0) { 
        break; 
       } 

       decoded = FFMIN(result, decodingPacket.size); 

       if (gotFrame) { 
        data_size = (av_get_bytes_per_sample(context->sample_fmt)); 
        if (data_size < 0) { 
        } 

        // Only for 1 channel temporarily 
        for (int i = 0; i < frame->nb_samples; i++) { 
         for (int ch = 0; ch < context->channels; ch++) { 
          for (int j = 0; j < data_size; j++) { 
           bytevector.push_back(*(frame->data[ch] + data_size * i + j)); 
          } 
         } 
        } 
       } else { 
        decodingPacket.size = 0; 
        decodingPacket.data = NULL; 
       } 
       decodingPacket.size -= result; 
       decodingPacket.data += result; 
      } 
     } 
     av_free_packet(&readingPacket); 
    } 
+0

'double'? Это, вероятно, 52 бит точности, 11 бит динамического диапазона или 6000 дБ. Это безумие. И '-b16' в вашей командной строке означает 16 бит, ** не ** 8 бит. – MSalters

+0

Двойной, безусловно, переборщить за то, что делается с аудио. Я был отброшен тем фактом, что Scilab отображает значения как «удваивает», когда массив открывается в средстве просмотра. Но да, ниже приведен ответ о том, как представлять данные двух uint8_t (или 2 байта) так же, как Scilab (от -1,0 до +1.0). Благодарю. – gapc

+0

@MSalters - самые достойные приложения DAW используют 64-битную внутреннюю обработку, таким образом вы теряете меньшую точность, даже если вы все еще выдаете 24-битный мастер. – dtech

ответ

0

Быстрый способ превратить два байта в поплавка:

byte bits[] = {195,255}; //first sample in the test s16 wav file 
int16_t sample; 
memcpy(&sample,&bits,sizeof(bits)); 
std::cout<<sample*(1.0f/32768.0f)<<std::endl; 

Этот код урожайности -0.001861572265625 при печати (с более высокой точностью setprecision (xx);), который является первым числом, заданным Scilab с тем же файлом.

Я надеюсь, что это поможет любому, у кого есть подобные проблемы.

0

Аудиоданные хранятся в различных форматах. То, что вы получаете массив uint8_t[], означает немного. Это не один байт на массив. Вместо этого вам нужно знать формат. Здесь -b16 сообщает мне, что данные uint8_t[] являются фактически 16-битными PCM-кодированными данными, то есть по шкале от -32768 до +32767. Scilab предпочитает шкалу с плавающей запятой и поэтому делит на 32768.0. Это просто изменение представления; он просто уменьшает масштаб до -1.0, +1.0.

Сравните это с углами: правый угол составляет 90 градусов по pi/2 радианам; точное число не имеет значения, но оба они равны 1/4 полного круга.