Возможность обработки звука в реальном времени с помощью App Designer в Matlab?

Я хочу закодировать приложение простого аудио-фильтра, используя App Designer в Matlab. Нужно иметь возможность загружать аудиофайл, нажимать кнопку воспроизведения и изменять параметры, такие как входное усиление, частота отсечки и т. Д. Во время воспроизведения файла.

Я просто не могу оборачивать голову тем, как можно изменить параметры в реальном времени и обновить соответствующие переменные, чтобы можно было услышать, как изменяется фильтр.

Это код, который я написал сейчас:

classdef EulerFilter < matlab.apps.AppBase

% Properties that correspond to app components
properties (Access = public)
    UIFigure         matlab.ui.Figure
    CutoffKnobLabel  matlab.ui.control.Label
    CutoffKnob       matlab.ui.control.Knob
    PlayButton       matlab.ui.control.StateButton
end


properties (Access = public)
    inputGain % input Gain
    CutoffHz % cutoff frequency in Hz
end

methods (Access = public)

    function play(app)
        % setup file stream
        frameLength = 256;
        fileReader = dsp.AudioFileReader(...
            'Sun Behind CloudsDry.wav',...
            'SamplesPerFrame',frameLength);
        deviceWriter = audioDeviceWriter(...
            'SampleRate',fileReader.SampleRate);

        % code snippet

        % porcessing of frames
        while ~isDone(fileReader)
            % code snippet
        end

        release(fileReader);
        release(deviceWriter);
    end

end


methods (Access = private)

    % Code that executes after component creation
    function startupFcn(app)
        app.inputGain = 1;
        app.CutoffHz = 22000;
    end

    % Value changed function: PlayButton
    function PlayButtonValueChanged(app, event)
        value = app.PlayButton.Value;
        play(app);
    end

    % Value changing function: CutoffKnob
    function CutoffKnobValueChanging(app, event)
        %display(event)
        changingValue = event.Value;
        app.CutoffHz = changingValue;
    end
end

% App initialization and construction
methods (Access = private)

    % Create UIFigure and components
    function createComponents(app)

        % Create UIFigure
        app.UIFigure = uifigure;
        app.UIFigure.Position = [100 100 640 480];
        app.UIFigure.Name = 'UI Figure';

        % Create CutoffKnobLabel
        app.CutoffKnobLabel = uilabel(app.UIFigure);
        app.CutoffKnobLabel.HorizontalAlignment = 'center';
        app.CutoffKnobLabel.Position = [159 322 37 22];
        app.CutoffKnobLabel.Text = 'Cutoff';

        % Create CutoffKnob
        app.CutoffKnob = uiknob(app.UIFigure, 'continuous');
        app.CutoffKnob.Limits = [10 22000];
        app.CutoffKnob.MajorTicks = [10 1000 5000 22000];
        app.CutoffKnob.ValueChangingFcn = createCallbackFcn(app, @CutoffKnobValueChanging, true);
        app.CutoffKnob.Position = [155 367 45 45];
        app.CutoffKnob.Value = 22000;

        % Create PlayButton
        app.PlayButton = uibutton(app.UIFigure, 'state');
        app.PlayButton.ValueChangedFcn = createCallbackFcn(app, @PlayButtonValueChanged, true);
        app.PlayButton.Text = 'Play';
        app.PlayButton.Position = [60 40 100 22];
    end
end

methods (Access = public)

    % Construct app
    function app = EulerFilter

        % Create and configure components
        createComponents(app)

        % Register the app with App Designer
        registerApp(app, app.UIFigure)

        % Execute the startup function
        runStartupFcn(app, @startupFcn)

        if nargout == 0
            clear app
        end
    end

    % Code that executes before app deletion
    function delete(app)

        % Delete UIFigure when app is deleted
        delete(app.UIFigure)
    end
end
end

Это главным образом функции, которые Matlab генерирует для GUI. Я добавил некоторые свойства, которые содержат значения для входного усиления, обрезания и т. Д., А также функцию play (), которая выполняет обработку сигнала. Я могу запустить приложение, нажать кнопку воспроизведения и услышать звуковой файл, который воспроизводится, но когда я изменяю частоту среза, например, ничего не меняется. Я предполагаю, что это происходит потому, что я выполняю функцию play () внутри функции обратного вызова, когда нажата кнопка воспроизведения, и, таким образом, функции обратного вызова, когда ручка отсечки повернута, не могут быть выполнены до того, как другой закончен.

Когда я сначала меняю параметры, а затем нажимаю кнопку воспроизведения, все правильно, за исключением того, что я не могу изменить параметры во время воспроизведения файла.

Я пробовал следующее без успеха:

  • вызов функции обратного вызова внутри цикла while в функции play (), но я не знаю, какой аргумент я должен передать для события (Matlab всегда говорит мне, что он не знает, что команда или аргументы отсутствуют), или если это даже полезно
  • выполните функцию play () внутри runStartupFcn (), но эта функция выполняется до отображения GUI, что бесполезно, конечно
  • Насколько я могу сказать, я не могу добавлять функции в другое место

Итак, теперь возникает вопрос: могу ли я заставить приложение работать в режиме реального времени?

Я с нетерпением жду ваших ответов!

matlab,callback,signal-processing,real-time,matlab-app-designer,

-2

Ответов: 2


0

Я думаю, что решение вашей проблемы - создание второго потока. В основной теме вы имеете доступ к своим ручкам и переменным, а ваш второй поток запускает звук. Моя идея включала бы изменения, которые вы делаете в потоке A, в поток B. К несчастью, вы можете просто использовать многопоточность с помощью MatLab Parallel Processing Toolbox. Надеюсь, есть еще один способ.

Приветствия, Пабло


0

Кажется, что есть много решений / примеров для руководства Matlab, но еще не для дизайнера приложений.

Похоже, ваш лучший выбор - вызвать функцию паузы в цикле while, чтобы дать вашему программному времени получить обновленные значения. Поэкспериментируйте с разным pauseвременем, чтобы убедиться, что у вашей программы достаточно времени для обновления. Matlab может приостановить текущий исполняемый поток, используя:

pause(0.001) % 0.001 sec

Или сделать прямой вызов Java для большей точности

java.lang.Thread.sleep(duration)  % duration in msec

Я уверен, что это даст вашей программе время для доступа к переменным и обновления. Таким образом, вы можете проверять каждый цикл цикла 10/20/50/1000 и обновлять параметры так часто, как вы хотели бы свести к минимуму любые звуковые артефакты.

% Init counter to see how many loops have passed
counter = 0;

% processing of frames
while ~isDone(fileReader)

    % Do your playback process stuff

    if(counter > 10) % Updates every 10 loops or so
        pause(0.001);
        counter = 0;
    end

    counter = counter + 1;

end

Примечание: Код не проверен, пожалуйста, дайте мне знать

В противном случае, возможно, посмотрите на подход обратного вызова .

Вот почему графические интерфейсы в Matlab не всегда являются такой хорошей идеей :-) Я понимаю, почему вы, возможно, делаете это для учебной цели, но в противном случае я мог бы исследовать большую интеграцию с Java в ваш графический интерфейс Matlab для обработки всех потоков ( или даже дизайн GUI с самой Java). Для начала...

MATLAB, обратный вызов, обработки сигналов в реальном масштабе времени, Matlab-приложение-дизайнер,
Похожие вопросы