#matlab #16-bit
#matlab #16-разрядный
Вопрос:
У меня есть матрица (n,16)
, заполненная звуковыми образцами по 16 бит каждый.
Таким образом, матрица может выглядеть так:
[0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1; 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1]
и так далее. Как я могу на самом деле воспроизвести это как звук? sound()
использует double
плавающие точки (from -1 to 1 values)
. Если бы я мог просто преобразовать его в эти значения, я думаю, это сработало бы, но я не уверен. Есть предложения?
Комментарии:
1. Это будет работать, если данные верны. совместите со знаком double, нормализуйте и воспроизведите его. Попробуйте.
2. В каком формате эти биты? Я имею в виду: наиболее значимый бит слева или справа? Подписанный или неподписанный?
Ответ №1:
@AnderBiguri в значительной степени справился с этим. Возьмите свой массив, преобразуйте его в signed double, нормализуйте и воспроизведите его.
Поскольку у вас есть n x 16
матрица, где каждая строка является образцом, а каждый столбец представляет собой бит для этого числа, сначала нам нужно преобразовать эту матрицу в двойной формат. Мы можем использовать bin2dec
, чтобы помочь нам сделать это. Однако bin2dec
принимает string
. Таким образом, мы можем преобразовать нашу матрицу в строковый массив примерно так. Давайте предположим, что inSound
содержит вашу звуковую матрицу, которую вы указали ранее.
Я также предположу, что ваши биты находятся в формате Big-Endian, поэтому наиболее значимым битом является самый левый бит, следующий за самым правым битом.
Согласно вашим комментариям, цифры подписаны как дополнение 1. Это означает, что если старший бит будет равен 1, мы просто инвертируем все число. Таким образом, мы можем выяснить, какие строки являются отрицательными, проверив весь первый столбец, чтобы увидеть, есть ли 1
или 0
. Мы находим строки с 1
помощью и просто берем 1
и вычитаем каждый отдельный элемент в массиве. Как таковой:
checkSign = inSound(:,1) == 1;
inSound(checkSign,:) = 1 - inSound(checkSign,1);
Поэтому, когда мы преобразуем наше число в десятичное, мы просто снова находим те строки, которые должны быть отрицательными, и просто отрицаем их. Давайте сначала преобразуем наши числа.
inSoundString = char(inSound '0');
char
преобразует каждое число в матрице или векторе в его строковое представление, предполагая, что ввод в char
является ASCII-кодом. Таким образом, когда мы добавляем с 0
помощью, мы добавляем каждое число inSound
с числовым кодом ASCII, который представляет то, что 0
находится в ASCII. Это наш базовый уровень для начала. После этого inSound
добавим либо 0
или 1
к этому числовому коду, чтобы, когда мы преобразуем всю эту матрицу в строку, мы, наконец, получим строковое представление этих чисел.
Теперь преобразуйте двоичные строки в фактические числа:
outSoundDec = bin2dec(inSoundString);
Это займет каждую строку и преобразует ее в десятичный эквивалент. Теперь, если ваши биты находятся в младшем конце, вы можете использовать swapbytes
для переворачивания битов, чтобы преобразовать биты в порядковый номер, прежде чем продолжить. Теперь, когда мы преобразовали наши числа, нам нужно отрицать те строки, которые должны были быть отрицательными.
Как таковой:
outSoundDec(checkSign) = -outSoundDec(checkSign);
Теперь нам нужно нормализовать это, чтобы диапазон был между -1
to 1
. Учитывая, что вы указали, что диапазон находится между [-32768, 32767]
ними, мы просто делим все наши числа на 32768
. Поэтому:
outSound = outSoundDec / 32768;
Приведенный выше код теперь нормализует ваш сигнал, чтобы он переходил от -1
к 1
. Вы можете использовать sound(outSound, Fs);
для воспроизведения своего звука, где Fs
указана частота дискретизации, с которой был получен ваш сигнал.
Удачи!
Комментарии:
1. Это именно то, что мне было нужно, но мои значения находятся в диапазоне [-32768-32767], а не от 0 и выше, что приводит к искажению моих отрицательных значений (одно дополнено), например, ‘1101011100000110’ становится 55046 вместо -10489 с формой bin2dec. Поэтому, я думаю, мне нужно каждый раз проверять первое значение в строке и использовать typecast(uint16(bin2dec(‘the_negative_number’) 1), ‘int16’) каждый раз, когда это отрицательное значение с циклом. Или есть более разумный способ? Но пока что это мне уже очень помогло!
2. @user3752959 Я могу ответить на этот вопрос, но мне нужно знать, в каком формате находятся ваши отрицательные числа. Подписано? Один комплимент или комплимент двоих? Мы все еще можем сделать это без цикла
3. Подписанные дополняют.
4. @user3752959 Хорошо, дайте мне минутку, чтобы изменить мой ответ.
5. @user3752959 — Готово. Удачи.