gpt4 book ai didi

matlab - 实时音频调制

转载 作者:行者123 更新时间:2023-12-02 22:27:52 25 4
gpt4 key购买 nike

我在弄清楚如何继续进行我的项目时遇到了麻烦。简而言之,我正在尝试使用来自加速度计的数据来创建FM合成器,以实时更改FM和Pitch参数。

这是我基于的一些代码:

% X axis data will be used for fc parameter
% Y axis data will be used for fm parameter

function y = fmSynth(fc, dur, fm)

fs = 48000;
T = 1/fs; % seconds
t = 0:T:dur; % time vector

% FM parameters
Imin = 0;
Imax = 20;
I = t.*(Imax - Imin)/dur + Imin;

y = sin(2*pi*fc*t + I.*sin(2*pi*fm*t));
plot(t(1:10000), y(1:10000));
sound(y, fs);

我确实有一个生成波的函数,但是只能在设定的时间内(由于内置的​​matlab函数的局限性)。我希望它是连续的(直到用户输入停止它),并且能够“实时”对其进行调制(稍有滞后就可以了)。

为此,我找到了一个实时音频处理器代码 here

但是,这是用面向对象的编程语言编写的,这是我不熟悉的。

是否有一种简单的方法可以将上述功能实现到此代码(输出rtap),或者我必须编写子类?如果是这样,怎么办?

对于那些不愿意下载代码的人,这里是主要的类:
% RealTimeAudioProcessor
%
% The RealTimeAudioProcessor object allows the user to process consecutive
% frames of audio in real-time (it lags real-time by the frame size plus
% hardware overhead). The object can easily be extended for any type of
% audio processing by overloading the stepImpl method in a derived class.
%
% Use:
%
% % Create the processor with a number of input channels, number of output
% % channels, sample rate, frame size, and device name.
% rtap = RealTimeAudioProcessor(1, 2, 48000, 256, 'Default');
%
% % Play. This will start *immediately* and block until all audio output is
% % complete.
% rtap.Play();
%
% % Release the audio resource for others (be nice).
% rtap.release();
%
% % The RTAP records some timing values while playing. Show the results.
% rtap.Analyze();
%
% It is recommended that an ASIO audio driver with appropriate hardware be
% used for the audio interface. (ASIO is an open standard from Steinberg
% Media Technologies GmbH).
%
% Tucker McClure @ The MathWorks
% Copyright 2012 The MathWorks, Inc.

classdef RealTimeAudioProcessor < matlab.system.System

properties (Nontunable, Access = protected)

% Settings
frame_size = 256; % Number of samples in the buffer
sample_rate = 48000; % Number of samples per second [samples/s]
end_time = inf; % Number of seconds until playback stops [s]
in_channels = 2; % Number of input channels
out_channels = 2; % Number of output channels
device_name = 'Default';
draw_rate = 0.02; % Rate to update graphics [s]

% Derived quantities
time_step; % Length of frame [s]
time_window; % Array of time values from [0 time_step) [s]

% Device interfaces
ap; % AudioPlayer object to manage output
ar; % AudioRecorder object to manage input

end

properties

% UI handles
figure_handle; % Handle of UI figure
text_handle; % Handle of text in figure

samples_until_draw = 0; % Samples left before updating GUI

% Analysis stuff
max_in_step_time = 0;
max_process_step_time = 0;
max_out_step_time = 0;

end

methods

% Constructor; creates the RTAP and its internal dsp.AudioPlayer.
% After creation, the RTAP is ready to play.
function rtap = RealTimeAudioProcessor(ins, outs, Fs, w, device)

fprintf('Initializing a RealTimeAudioProcessor on %s... ', ...
device);

% Set some internals.
rtap.frame_size = w;
rtap.sample_rate = Fs;
rtap.in_channels = ins;
rtap.out_channels = outs;
rtap.device_name = device;

% Calculate the period.
rtap.time_step = w/Fs;

% Create all the time values for a window.
rtap.time_window = (0:w-1)'/Fs;

% Ok, we set everything up.
fprintf('done.\n');

% Display latency to user.
fprintf('Minimum latency due to buffering: %5.1fms\n', ...
1000 * rtap.time_step);

end

% Enter a quasi-real-time loop in which audio is acquired/generated
% and plugged into the output buffer (if a buffer exists).
function Play(rtap)

% If not set up, setup.
if ~rtap.isLocked

setup(rtap, ...
zeros(rtap.frame_size, 1), ...
zeros(rtap.frame_size, rtap.in_channels));

% Otherwise, if we need a new figure, open one.
elseif ~ishandle(rtap.figure_handle)

rtap.GenerateFigure();

end

% Keep track of time since 'tic'.
t_clock = 0;

% Keep track of how much material we've played since 'tic'.
% At t_clock, this should reach to t_clock + time_step.
t_played = 0;

% Initialize the input.
in = zeros(rtap.frame_size, rtap.in_channels); %#ok<NASGU>

% Start a timer.
tic();

% Loop until the end time has been reached or the figure has
% been closed.
while t_clock < rtap.end_time && ishandle(rtap.figure_handle)

% Play steps until we're |buffer| into the future.
if t_played < t_clock + rtap.time_step

% Create the times for this frame.
time = t_played + rtap.time_window;

% Get the input for one frame.
if rtap.in_channels > 0
step_timer = tic();
in = step(rtap.ar);
rtap.max_in_step_time = ...
max(rtap.max_in_step_time, toc(step_timer));
else
in = zeros(rtap.frame_size, rtap.in_channels);
end

% Process one frame.
step_timer = tic();
out = step(rtap, time, in);
rtap.max_process_step_time = ...
max(rtap.max_process_step_time, toc(step_timer));

% Step the AudioPlayer. Time the step for analysis
% purposes.
if rtap.out_channels > 0
step_timer = tic();
step(rtap.ap, out);
rtap.max_out_step_time = ...
max(rtap.max_out_step_time, toc(step_timer));
end

% Update the time.
t_played = t_played + rtap.time_step;

end

% Release focus so that figure callbacks can occur.
if rtap.samples_until_draw <= 0
drawnow();
rtap.UpdateGraphics();
rtap.samples_until_draw = ...
rtap.sample_rate * rtap.draw_rate;
else
rtap.samples_until_draw = ...
rtap.samples_until_draw - rtap.frame_size;
end

% Update the clock.
t_clock = toc();

end

% Wait for audio to end before exiting. We may have just
% written out a frame, and there may have already been a frame
% in the buffer, so chill for 2 frames.
pause(2*rtap.time_step);

end

% Display timing results from last play.
function Analyze(rtap)
fprintf(['Results for last play:\n', ...
'Maximum input step time: %5.1fms\n', ...
'Maximum process step time: %5.1fms\n', ...
'Maximum output step time: %5.1fms\n'], ...
1000*rtap.max_in_step_time, ...
1000*rtap.max_process_step_time, ...
1000*rtap.max_out_step_time);
end

end

methods (Access = protected)

% Set up the internal System Objects and the figure.
function setupImpl(rtap, ~, ~)

% Create the AudioPlayer.
if rtap.out_channels > 0

rtap.ap = dsp.AudioPlayer(...
'DeviceName', rtap.device_name, ...
'BufferSizeSource', 'Property', ...
'BufferSize', rtap.frame_size, ...
'QueueDuration', 0, ...
'SampleRate', rtap.sample_rate);


% Start with silence. This initializes the AudioPlayer to
% the window size and number of channels and takes longer
% than any subsequent call will take.
step(rtap.ap, zeros(rtap.frame_size, rtap.out_channels));

end

% Create the AudioRecorder (if requested).
if rtap.in_channels > 0

rtap.ar = dsp.AudioRecorder(...
'DeviceName', 'Default', ...
'SampleRate', rtap.sample_rate, ...
'BufferSizeSource', 'Property', ...
'BufferSize', rtap.frame_size, ...
'SamplesPerFrame', rtap.frame_size, ...
'QueueDuration', 0, ...
'OutputDataType', 'double', ...
'NumChannels', rtap.in_channels);

% Initialize the input.
step(rtap.ar);

end

if ishandle(rtap.figure_handle)
close(rtap.figure_handle);
end
rtap.GenerateFigure();

% Draw it.
drawnow();

% Chill out for a second before rushing forward with sound.
pause(rtap.time_step);

end

% Process one frame of audio, given the inputs corresponding to the
% frame and the times.
function out = stepImpl(rtap, time, in) %#ok<INUSD>
out = zeros(rtap.frame_size, rtap.out_channels);
end

% Specify that the step requires 2 inputs.
function n = getNumInputsImpl(~)
n = 2;
end

% Specify that the step requires 1 output.
function n = getNumOutputsImpl(~)
n = 1;
end

% Clean up the AudioPlayer.
function releaseImpl(rtap)

% Release the dsp.AudioPlayer resource.
if rtap.out_channels > 0
release(rtap.ap);
end

% Release the dsp.AudioRecorder too.
if rtap.in_channels > 0
release(rtap.ar);
end

% Close the figure if it's still open.
if ishandle(rtap.figure_handle)
set(rtap.text_handle, 'String', 'Closing.');
close(rtap.figure_handle);
rtap.figure_handle = [];
end

end

% Generate a figure that stays open with updates for the user.
% Closing this figure ends playback.
function GenerateFigure(rtap)

% Get the screen dimensions for centering the figure.
screen_dims = get(0, 'ScreenSize');
figure_width_height = [640 160];
figure_dims = [floor(0.5*( screen_dims(3:4) ...
- figure_width_height)) ...
figure_width_height];

% Generate a figure.
rtap.figure_handle = figure(...
'Name', 'Real-Time Audio Processor Controller',...
'NumberTitle', 'off', ...
'Position', figure_dims);
axes('Position', [0 0 1 1], ...
'Visible', 'off');
rtap.text_handle = text(0.5, 0.5, ...
'Real Time Audio Processor is active.', ...
'HorizontalAlignment', 'center', ...
'VerticalAlignment', 'middle', ...
'Interpreter', 'none');

end

function UpdateGraphics(rtap) %#ok<*MANU>
end

end

end

包中还有其他文件用作示例,但我无法成功对其进行修改。另外,对于没有发布用于读取和过滤加速度计数据的代码(有点长),我深表歉意。

最佳答案

一个不使用OOP的粗略解决方案是将声音生成代码放在一个循环中,例如在伪代码中:

Fs = ...;
while 1
% generate your signal here ...
signal = ....
% ...
wavplay(signal,Fs,'sync')
end

但是,您希望包含一个转义子句以一种很好的方式摆脱循环。您最终将希望拥有一些类似于OOP的解决方案,基本上是一个侦听器,以便您可以摆脱循环并有选择地交互修改信号。监听器可以是非常基本的,例如实现为带有按钮的图形。

关于matlab - 实时音频调制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18434967/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com