2016-09-26 6 views
1

Я делаю приложение ICA, где я пытаюсь отделить сигналы от наблюдения смешанного сигнала. Кажется, это работает теоретически, когда я смотрю на восстановленный сигнал ICA в numpy ndarray, сигнал отчетливо виден. Однако, когда я пытаюсь записать этот ndarray в .wav для воспроизведения, сигнал полностью исчезает. Это можно увидеть на следующем рисунке: enter image description hereScipy Write Audio Issue

Первый график показывает сигнал ndarray numpy сигнала восстановления ICA. Второй график показывает, где я просто загрузил файл, который предположительно был написан scipy .wav write, так как вы можете видеть, что он молчит.

Такое поведение вызывает недоумение, поскольку ранее я использовал ту же самую процедуру для создания моих наблюдений смешанного сигнала, используя матрицу смешивания (также в том же формате, numpy ndarrays). На следующем рисунке вы заметите, что все происходит точно так же, и все же, по какой-то причине, scipy write .wav работал - второй график подтверждает, что сигнал был загружен из .wav, который был записан с первый график (массив numpy nd).

enter image description here

Я хотел бы знать, что за условный успехом для этого. Я знаю, что плавать и целые числа нужно обрабатывать осторожно, но я уверен, что ничего не забыл.

Картины объясняют это очень хорошо, единственное, что я хотел бы уточнить, что функция play_wav делает, это в основном просто пишет .wav и создает звуковой объект:

def play_wav(file, fs, data): 
    wavfile.write(file, fs, data.astype(np.dtype('i2'))) 
    display(Audio(filename=file)) 

импорт:

import numpy as np 
from scipy.io import wavfile 
from IPython.display import display, Audio 
from sklearn.decomposition import FastICA 
+0

Вы не показать функцию 'load_wav'. Это поможет, если вы сможете предоставить [MVCE] (http://stackoverflow.com/help/mcve), которые мы могли бы скопировать и запустить, чтобы воссоздать проблему. –

+0

Справедливая точка, вот репозиторий со всем моим ноутбуком jupyter. Скорость загрузки на данный момент низкая, только 1 .wav, который я использовал по этой ссылке. Я попытаюсь обновить его в ближайшее время, включив в него все 3 WAV. Вы можете использовать свои собственные .wavs, если хотите. Конечно, если вы просто хотели видеть внутреннюю работу вещей, вы можете просто просмотреть файл ipynb для ноутбука. Вот он: https://github.com/diggetybo/ICA-Attachments –

+0

Хорошо, все 3 .wavs есть сейчас. Если кто-то хочет 100% повторно создать мою процедуру, это было бы возможно сейчас. Поместите .wavs в каталог ноутбуков jupyter. –

ответ

2

Похоже, что массив, который вы пытаетесь записать, содержит значения в диапазоне [-0.02, 0.02]. Когда вы передаете массив в 16 бит int перед записью его в WAV-файл, все эти значения будут усечены до нуля!

wavfile.write поддерживает массивы float32, поэтому вы можете просто пропустить шаг кастинга. В качестве альтернативы, масштабировать массив падать между 2 и -2 перед заливкой его в Int16, например .:

((data + data.min()) * (2 ** 15)/data.ptp()).astype(np.int16) 
+0

Отличная работа ali_m, вы нашли проблему! Я, вероятно, никогда бы этого не заметил. Просто из любопытства, почему вы выбрали 2^15? Не потому ли, что он будет интерполировать их близко к их первоначальным уровням? Знаете ли вы, что их первоначальные уровни смотрели на «истинный сигнал» из .wavs в начале ноутбука, я предполагаю? Я спрашиваю, потому что я хочу написать эту строку для общего случая, и в этом случае мне может понадобиться формула для какой базы и какой величины использовать. или 2^15 - какой-то стандарт? –

+0

16-битное целое число со знаком может представлять значения между 2^15 (фактически 2^15 - 1) и -2^15. Есть 15 бит для кодирования величины каждого целого числа, а затем одного бита для его знака. Когда вы бросаете из float в целые числа, каждое значение в вашем массиве будет округлено до ближайшего целого. Путем масштабирования значений для заполнения диапазона представляемых целых чисел вы можете минимизировать потерю точности из-за этого округления. –

+0

Делает полный смысл теперь, не мог получить это работать без вас! –