Как волновые файлы хранят несколько каналов?

Я создал два волновых файла с помощью Audacity. Оба имеют частоту дискретизации 44100 Гц, 32-битные сэмплы с плавающей запятой, были сохранены в формате WAV (Microsoft) с 16-битным знаком и содержат 1 с тишины (согласно Audacity). Разница в том, что один файл содержит один канал, а другой два (стерео). При чтении файла одного канала я получил такие кадры:

0x00 0x00  
...  ...  

Как и ожидалось, но при чтении второго файла я получил:

0x00 0x00 0x00 0x00  
0x01 0x00 0xff 0xff  
0x00 0x00 0x00 0x00  
0x00 0x00 0x01 0x00  
0xff 0xff 0x01 0x00  
0xfe 0xff 0x03 0x00  

Мне кажется, это случайная закономерность. Это как-то связано с тем, как каналы хранятся в волновом файле? Разве это не должно быть что-то вроде:

0x00 0x00 0x00 0x00  
...  ...  ...  ...  

?

PS: я использовал встроенный модуль python «wave» для чтения файлов.


person ygormutti    schedule 04.06.2010    source источник
comment
Мне нужен ответ, чтобы написать программу, которая читает из файла моно волны, дублирует его каналы и добавляет 0,2 секунды тишины в начале одного канала, между прочим.   -  person ygormutti    schedule 04.06.2010


Ответы (5)


Сигнал очень низкого уровня там, где ожидалось молчание, мог быть вызван дизерингом, использованным при преобразовании. с 32-битной на 16-битную.

person Han    schedule 04.06.2010
comment
В этом есть смысл. Я забыл о дизеринге. - person ygormutti; 05.06.2010

Данные не случайны

Глядя на это, я, кажется, вижу 2 значения int в строке, каждые 2 байта с прямым порядком байтов:

0x00 0x00 0x00 0x00  
0x01 0x00 0xff 0xff  
0x00 0x00 0x00 0x00  
0x00 0x00 0x01 0x00  
0xff 0xff 0x01 0x00  
0xfe 0xff 0x03 0x00  

Расшифровывается как:

 0  0
 1 -1
 0  0
 0  1
-1  1
-2  3

Итак, вы видите числа, очень близкие к 0 (почти тишина), похоже на дрожание, как предполагали другие.

person Nas Banov    schedule 15.12.2010

Насколько я помню, каналы должны чередоваться, поэтому 1 секунда 44,1 кГц будет потоком из 88 200 тыс. сэмплов, чередующихся влево и вправо или как говорится в спецификации.

Также в Audacity не должно быть неправильного преобразования float -> int, только наоборот. Попробуйте начать с целочисленных выборок, а не с плавающей запятой. Или иметь один канал с известным значением (т. е. Ox8f8f), а другой — 0, это может быть легче вычислить.

person user318904    schedule 04.06.2010
comment
Теперь я знаю, что это хорошая идея. Я как раз думал сделать то же самое. :Р Спасибо. - person ygormutti; 05.06.2010

Удален код и предыдущий пост.

Тишина: «Настоящая» тишина должна быть нулевой. Иначе его часто называют «комнатной» тишиной, очень слабым шумом, который присутствует везде, если не использовать нойзгейт. (запись) Это просто идея: помните, что использование значений со знаком приведет к тому, что 1 бит будет использоваться для маркера со знаком/без знака. Может быть (я не знаю), это то, что вы видите после преобразования его в подписанный файл волны с помощью Audacity. Извините, но у меня нет времени, чтобы проверить это.

Волновые файлы: я не знаю, как много вы знаете о звуковых файлах, но: Если вы просто хотите добавить тишину, попробуйте сделать это следующим образом: Каждый семпл имеет размер X бит: поэтому вам нужно X/8 байтов для одного семпла. Вы знаете частоту дискретизации, поэтому вы можете просто скопировать исходный необработанный массив байтов в один из размеров (silence_length_in_samplesбайт_на_кадр)+(исходный)+(silence_length_in_samplesбайт_на_кадр) и просто записать его обратно в звуковой файл с помощью инструменты Python, которые, я надеюсь, могут это сделать.

2 канала: необработанные байты организованы в: [выборка1 (байты_канала1, байты_канала2)][выборка2(байты_канала1,байты_канала2).... Надеюсь, понятно, что я имею в виду :)

person InsertNickHere    schedule 04.06.2010
comment
Я думаю, что это ответ на мой вопрос. Рутина очень помогла. Спасибо. PS: меня все еще смущает случайный байтовый шаблон стереофайла тишины. Возможно, действительно есть ошибка в Audacity или модуле волны. - person ygormutti; 05.06.2010
comment
Пожалуйста, обратите внимание на рутину - это только testet для 16-битных подписанных файлов с little_endian и 1 каналом. (на данный момент частота дискретизации не имеет значения) Вот почему я удалил его. Принцип правильный, но я думаю, что мне нужно переработать подписанную/неподписанную вещь. - person InsertNickHere; 05.06.2010

Вы можете увидеть, что это за числа, с помощью этого кода:

import struct
struct.unpack("f", struct.pack("I", 0xfeff0300))
(-1.6948435790786458e+38,)

Все они кажутся очень маленькими, возможно, молчаливыми числами. Я сгенерировал молчание и сохранил его как 32-битный WAV с плавающей запятой и не получил маленьких чисел. Мой файл содержал нули, исключая заголовок.

0,2 секунды молчания, 2-канальные данные с плавающей запятой могут быть сгенерированы следующим образом:

import array
silence = array.array("f", [0] * int(44100 * 2 * 0.2))
person James Roth    schedule 04.06.2010
comment
На самом деле -1,6948435790786458e+38 — это ОЧЕНЬ большое отрицательное число, и оно не является частью тишины. Вы не должны смотреть на данные как на 4 байта с плавающей запятой, это 2 канала x 2 байта (little endian) - person Nas Banov; 15.12.2010