Error using comm.PhaseFrequencyOffset/parenReference Changing the size on input 1 is not allowed without first calling the release() method.
6 views (last 30 days)
Show older comments
How i use release method to generate oqpsk modulation on Audion wav file.
Code is
modulationTypes = categorical(["BPSK", "OQPSK",]);
trainNow = false;
if trainNow == true
numFramesPerModType = 10000;
else
numFramesPerModType = 10;
end
percentTrainingSamples = 80;
percentValidationSamples = 10;
percentTestSamples = 10;
sps = 8; % Samples per symbol
spf = 1024; % Samples per frame
symbolsPerFrame = spf / sps;
fs = 200e3; % Sample rate
[902e6 100e6]; % Center frequencies
rng(1235)
tic
numModulationTypes = length(modulationTypes);
channel = helperModClassTestChannel(...
'SampleRate', fs, ...
'SNR', SNR, ...
'PathDelays', [0 1.8 3.4] / fs, ...
'AveragePathGains', [0 -2 -10], ...
'KFactor', 4, ...
'MaximumDopplerShift', 4, ...
'MaximumClockOffset', 5, ...
'CenterFrequency', 902e6)
channelInfo = info(channel);
transDelay = 50;
dataDirectory = fullfile(tempdir,"ModClassDataFiles");
disp("Data file directory is " + dataDirectory)
fileNameRoot = "frame";
% Check if data files exist
dataFilesExist = false;
if exist(dataDirectory,'dir')
files = dir(fullfile(dataDirectory,sprintf("%s*",fileNameRoot)));
if length(files) == numModulationTypes*numFramesPerModType
dataFilesExist = true;
end
end
if ~dataFilesExist
disp("Generating data and saving in data files...")
[success,msg,msgID] = mkdir(dataDirectory);
if ~success
error(msgID,msg)
end
for modType = 1:numModulationTypes
fprintf('%s - Generating %s frames\n', ...
datestr(toc/86400,'HH:MM:SS'), modulationTypes(modType))
label = modulationTypes(modType);
numSymbols = (numFramesPerModType / sps);
dataSrc = helperModClassGetSource(modulationTypes(modType), sps, 2*spf, fs);
modulator = helperModClassGetModulator(modulationTypes(modType), sps, fs);
if contains(char(modulationTypes(modType)), {'B-FM','DSB-AM','SSB-AM'})
% Analog modulation types use a center frequency of 100 MHz
channel.CenterFrequency = 100e6;
else
% Digital modulation types use a center frequency of 902 MHz
channel.CenterFrequency = 902e6;
end
for p=1:numFramesPerModType
% Generate random data
x = dataSrc();
% Modulate
y = modulator(x);
% Pass through independent channels
rxSamples = channel(y);
% Remove transients from the beginning, trim to size, and normalize
frame = helperModClassFrameGenerator(rxSamples, spf, spf, transDelay, sps);
% Save data file
fileName = fullfile(dataDirectory,...
sprintf("%s%s%03d",fileNameRoot,modulationTypes(modType),p));
save(fileName,"frame","label")
end
end
else
disp("Data files exist. Skip data generation.")
end
%%%%
function modulator = helperModClassGetModulator(modType, sps)
switch modType
case "BPSK"
modulator = @(x)bpskModulator(x,sps);
case "OQPSK"
modulator = @(x)oqpskModulator(x,sps);
end
function y = oqpskModulator(x,sps)
persistent filterCoeffs
if isempty(filterCoeffs)
filterCoeffs = rcosdesign(0.35, 4, sps);
end
modulator = comm.OQPSKModulator('BitInput', true, 'SamplesPerSymbol', sps, 'PulseShape', 'Root raised cosine');
y = modulator(x);
%release(x)
end
function y = bpskModulator(x,sps)
%bpskModulator BPSK modulator with pulse shaping
% Y = bpskModulator(X,SPS) BPSK modulates the input X, and returns the
% root-raised cosine pulse shaped signal Y. X must be a column vector
% of values in the set [0 1]. The root-raised cosine filter has a
% roll-off factor of 0.35 and spans four symbols. The output signal
% Y has unit power.
persistent filterCoeffs
if isempty(filterCoeffs)
filterCoeffs = rcosdesign(0.35, 4, sps);
end
% Modulate
syms = pskmod(x,2);
% Pulse shape
y = filter(filterCoeffs, 1, upsample(syms,sps));
end
end
%%%%
function y = helperModClassFrameGenerator(x, windowLength, stepSize, offset, sps)
%helperModClassFrameGenerator Generate frames for machine learning
% Y = helperModClassFrameGenerator(X,WLEN,STEP,OFFSET,SPS) segments the
% input, X, to generate frames to be used in machine learning algorithms.
% X must be a complex-valued column vector. The output, Y, is a size
% WLENxN complex-valued array, where N is the number of output frames.
% Each individual frame has WLEN samples. The window is progressed STEP
% samples for the new frame. STEP can be smaller or greater than WLEN.
% The function starts segmenting the input, X, after it calculates an
% initial offset based on the OFFSET value. OFFSET is the deterministic
% offset value specified as a real-valued scalar. SPS is the number of
% samples per symbol. Total offset is OFFSET+randi([0 SPS]) samples. The
% deterministic part of the offset removes transients, while the random
% part enables the network to adapt to unknown delay values. Each frame
% is normalized to have unit energy.
%
% See also ModulationClassificationWithDeepLearningExample.
% Copyright 2018 The MathWorks, Inc.
numSamples = length(x);
numFrames = ...
floor(((numSamples-offset)-(windowLength-stepSize))/stepSize);
y = zeros([windowLength,numFrames],class(x));
startIdx = offset + randi([0 sps]);
frameCnt = 1;
while startIdx + windowLength < numSamples
xWindowed = x(startIdx+(0:windowLength-1),1);
framePower = mean(abs(xWindowed).^2);
xWindowed = xWindowed / sqrt(framePower);
y(:,frameCnt) = xWindowed;
frameCnt = frameCnt + 1;
startIdx = startIdx + stepSize;
end
%%%%
function src = helperModClassGetSource(modType, sps, spf, fs)
%helperModClassGetSource Source selector for modulation types
% SRC = helperModClassGetSource(TYPE,SPS,SPF,FS) returns the data source
% for the modulation type TYPE, with the number of samples per symbol
% SPS, the number of samples per frame SPF, and the sampling frequency
% FS.
%
% See also ModulationClassificationWithDeepLearningExample.
% Copyright 2019 The MathWorks, Inc.
switch modType
case {"BPSK","GFSK","CPFSK"}
M = 2;
src = @()randi([0 M-1],spf/sps,1);
case {"QPSK","PAM4"}
M = 4;
src = @()randi([0 M-1],spf/sps,1);
case "8PSK"
M = 8;
src = @()randi([0 M-1],spf/sps,1);
case "16PSK"
M = 16;
src = @()randi([0 M-1],spf/sps,1);
case "32PSK"
M = 32;
src = @()randi([0 M-1],spf/sps,1);
case "16QAM"
M = 16;
src = @()randi([0 M-1],spf/sps,1);
case "32QAM"
M = 32;
src = @()randi([0 M-1],spf/sps,1);
case "64QAM"
M = 64;
src = @()randi([0 M-1],spf/sps,1);
case "128QAM"
M = 128;
src = @()randi([0 M-1],spf/sps,1);
case "256QAM"
M = 256;
src = @()randi([0 M-1],spf/sps,1);
case "GMSK"
M = 2;
src = @()randi([0 M-1],spf/sps,1);
case "OQPSK"
M = 2;
src = @()randi([0 M-1],spf/sps,1);
% case "16APSK"
% M = 16;
%modOrder = sum(M);
% src = @()randi([0 M-1],spf/sps,1);
case {"B-FM","DSB-AM","SSB-AM"}
src = @()getAudio(spf,fs);
end
end
function x = getAudio(spf,fs)
%getAudio Audio source for analog modulation types
% A = getAudio(SPF,FS) returns the audio source A, with the
% number of samples per frame SPF, and the sample rate FS.
persistent audioSrc audioRC
if isempty(audioSrc)
audioSrc = dsp.AudioFileReader('audio_mix_441.wav',...
'SamplesPerFrame',spf,'PlayCount',inf);
audioRC = dsp.SampleRateConverter('Bandwidth',30e3,...
'InputSampleRate',audioSrc.SampleRate,...
'OutputSampleRate',fs);
[~,decimFactor] = getRateChangeFactors(audioRC);
audioSrc.SamplesPerFrame = ceil(spf / fs * audioSrc.SampleRate / decimFactor) * decimFactor;
end
x = audioRC(audioSrc());
x = x(1:spf,1);
end
%%%%
classdef helperModClassTestChannel < matlab.System
%helperModClassTestChannel Test channel for modulation classification
% CH = helperModClassTestChannel creates an channel System object, CH.
% This object adds multipath fading, clock offset effects, and white
% Gaussian noise to a framed signal.
%
% CH = helperModClassTestChannel(Name,Value) creates a channel object,
% CH, with the specified property Name set to the specified Value. You
% can specify additional name-value pair arguments in any order as
% (Name1,Value1,...,NameN,ValueN).
%
% The channel object uses the default MATLAB random stream. Reset the
% default stream for repeatable simulations. Type 'help RandStream' for
% more information.
%
% Step method syntax:
%
% Y = step(CH,X) adds multipath fading, clock offset effects, and white
% Gaussian noise to input X and returns the result in Y. The input X must
% be a double or single precision data type column vector. Each frame is
% impaired with an independent channel. The channel applies following
% impairments in the given order:
%
% 1) Add Rician multipath fading to input, X, based on PathDelays,
% AveragePathGains, KFactor, and MaximumDopplerShift settings. Channel
% path gains are regenerated for each frame, which provides independent
% path gain values for each frame.
%
% 2) Add clock offset effects.
% a) Frequency offset, which is determined by the clock offset (ppm)
% and the center frequency, as fOffset = -(C-1)*fc, where fc is the
% center frequency in Hz and C is the clock offset factor. clock offset
% factor, C, is calculated as C = (1+offset/1e6), where offset is the
% clock offset in ppm.
% b) Sampling offset, which is determined by the clock offset (ppm) and
% sampling rate, fs. This method first generates a clock offset value,
% offset, in ppm, based on the specified maximum clock offset and
% calculates the offset factor, C, as C = (1+offset/1e6), where offset
% is the clock offset in ppm. The signal is resampled using interp1
% function at a new sampling rate of C*fs.
%
% 3) Add Gaussian noise based on the specified SNR value. Channel object,
% CH, assumes that the input signal is normalized to unity power.
%
% System objects may be called directly like a function instead of using
% the step method. For example, y = step(obj, x) and y = obj(x) are
% equivalent.
%
% helperModClassTestChannel methods:
%
% step - Add channel impairments to input signal (see above)
% release - Allow property value and input characteristics changes
% clone - Create a channel object with same property values
% isLocked - Locked status (logical)
% reset - Reset channel object
%
% helperModClassTestChannel properties:
%
% SNR - SNR (dB)
% CenterFrequency - Center frequency (Hz)
% SampleRate - Input signal sample rate (Hz)
% PathDelays - Discrete path delay vector (s)
% AveragePathGains - Average path gain vector (dB)
% KFactor - Rician K-factor (linear scale)
% MaximumDopplerShift - Maximum Doppler shift (Hz)
% MaximumClockOffset - Maximum clock offset (ppm)
%
% See also ModulationClassificationWithDeepLearningExample.
% Copyright 2018 The MathWorks, Inc.
properties
%SNR SNR (dB)
% Specify the SNR value in decibels. Set this property to a numeric,
% real scalar. The default is 20 dB. This property is tunable.
SNR = 20
%CenterFrequency Center frequency (Hz)
% Specify the center frequency as a double precision nonnegative
% scalar. The default is 2.4 GHz. Center frequency value is used to
% calculate expected frequency offset in the received signal based on
% the maximum clock offset value. This property is tunable.
CenterFrequency = 2.4e9
end
properties (Nontunable)
%SampleRate Sample rate (Hz)
% Specify the sample rate of the input signal in Hz as a double
% precision, real, positive scalar. The default is 1 Hz.
SampleRate = 1
%PathDelays Discrete path delays (s)
% Specify the delays of the discrete paths in seconds as a double
% precision, real, scalar or row vector. When PathDelays is a scalar,
% the channel is frequency-flat; When PathDelays is a vector, the
% channel is frequency-selective. The default is 0.
PathDelays = 0
%AveragePathGains Average path gains (dB)
% Specify the average gains of the discrete paths in dB as a double
% precision, real, scalar or row vector. AveragePathGains must have
% the same size as PathDelays. The default is 0.
AveragePathGains = 0
%KFactor K-factors
% Specify the K factor of a Rician fading channel as a double
% precision, real, positive scalar. The first discrete path is a
% Rician fading process with a Rician K-factor of KFactor and the
% remaining discrete paths are independent Rayleigh fading processes.
% The default is 3.
KFactor = 3
%MaximumDopplerShift Maximum Doppler shift (Hz)
% Specify the maximum Doppler shift for the path(s) of the channel in
% Hz as a double precision, real, nonnegative scalar. It applies to
% all the paths of the channel. When MaximumDopplerShift is 0, the
% channel is static for the entire input and you can use the reset
% method to generate a new channel realization. The
% MaximumDopplerShift must be smaller than SampleRate/10 for each
% path. The default is 0.
MaximumDopplerShift = 0
%MaximumClockOffset Maximum clock offset (ppm)
% Specify the maximum clock offset in ppm as a double precision,
% real, non-negative scalar. Channel generates a uniformly
% distributed random clock offset value between -MaximumClockOffset
% and MaximumClockOffset for each frame. This clock offset value is
% used to calculate frequency and timing offset for the current
% frame. The default is 0.
MaximumClockOffset = 0
end
properties(Access = private)
MultipathChannel
FrequencyShifter
TimingShifter
C % 1+(ppm/1e6)
end
methods
function obj = helperModClassTestChannel(varargin)
% Support name-value pair arguments when constructing object
setProperties(obj,nargin,varargin{:})
end
end
methods(Access = protected)
function setupImpl(obj)
obj.MultipathChannel = comm.RicianChannel(...
'SampleRate', obj.SampleRate, ...
'PathDelays', obj.PathDelays, ...
'AveragePathGains', obj.AveragePathGains, ...
'KFactor', obj.KFactor, ...
'MaximumDopplerShift', obj.MaximumDopplerShift);
obj.FrequencyShifter = comm.PhaseFrequencyOffset(...
'SampleRate', obj.SampleRate);
end
function y = stepImpl(obj,x)
% Add channel impairments
yInt1 = addMultipathFading(obj,x);
yInt2 = addClockOffset(obj, yInt1);
y = addNoise(obj, yInt2);
end
function out = addMultipathFading(obj, in)
%addMultipathFading Add Rician multipath fading
% Y=addMultipathFading(CH,X) adds Rician multipath fading effects
% to input, X, based on PathDelays, AveragePathGains, KFactor, and
% MaximumDopplerShift settings. Channel path gains are regenerated
% for each frame, which provides independent path gain values for
% each frame.
% Get new path gains
reset(obj.MultipathChannel)
% Pass input through the new channel
out = obj.MultipathChannel(in);
end
function out = addClockOffset(obj, in)
%addClockOffset Add effects of clock offset
% Y=addClockOffset(CH,X) adds effects of clock offset. Clock offset
% has two effects on the received signal: 1) Frequency offset,
% which is determined by the clock offset (ppm) and the carrier
% frequency; 2) Sampling time drift, which is determined by the
% clock offset (ppm) and sampling rate. This method first generates
% a clock offset value in ppm, based on the specified maximum clock
% offset and calculates the offset factor, C, as
%
% C = (1+offset/1e6), where offset is the clock offset in ppm.
%
% applyFrequencyOffset and applyTimingDrift add frequency offset
% and sampling time drift to the signal, respectively.
% Determine clock offset factor
maxOffset = obj.MaximumClockOffset;
clockOffset = (rand() * 2*maxOffset) - maxOffset;
obj.C = 1 + clockOffset / 1e6;
% Add frequency offset
outInt1 = applyFrequencyOffset(obj, in);
% Add sampling time drift
out = applyTimingDrift(obj, outInt1);
end
function out = applyFrequencyOffset(obj, in)
%applyFrequencyOffset Apply frequency offset
% Y=applyFrequencyOffset(CH,X) applies frequency offset to input,
% X, based on the clock offset for the current frame and center
% frequency.
%
% fOffset = -(C-1)*fc, where fc is center frequency in Hz
% y = x .* exp(1i*2*pi*fOffset*t)
obj.FrequencyShifter.FrequencyOffset = ...
-(obj.C-1)*obj.CenterFrequency;
out = obj.FrequencyShifter(in);
end
function out = applyTimingDrift(obj, in)
%applyTimingDrift Apply sampling time drift
% Y=applyTimingDrift(CH,X) applies sampling time drift to
% input, X, based on the clock offset for the current frame and
% specified sampling rate, Fs. X is resampled at C*Fs Hz using
% linear interpolation.
originalFs = obj.SampleRate;
x = (0:length(in)-1)' / originalFs;
newFs = originalFs * obj.C;
xp = (0:length(in)-1)' / newFs;
out = interp1(x, in, xp);
end
function out = addNoise(obj, in)
%addNoise Add Gaussian noise
% Y=addNoise(CH,X) adds Gaussian noise to input, X, based on the
% specified SNR value. Channel object, CH, assumes that the input
% signal is normalized to unity power.
out = awgn(in,obj.SNR);
end
function resetImpl(obj)
reset(obj.MultipathChannel);
reset(obj.FrequencyShifter);
end
function s = infoImpl(obj)
if isempty(obj.MultipathChannel)
setupImpl(obj);
end
% Get channel delay from fading channel object delay
mpInfo = info(obj.MultipathChannel);
% Calculate maximum frequency offset
maxClockOffset = obj.MaximumClockOffset;
maxFreqOffset = (maxClockOffset / 1e6) * obj.CenterFrequency;
% Calculate maximum timing offset
maxClockOffset = obj.MaximumClockOffset;
maxSampleRateOffset = (maxClockOffset / 1e6) * obj.SampleRate;
s = struct('ChannelDelay', ...
mpInfo.ChannelFilterDelay, ...
'MaximumFrequencyOffset', maxFreqOffset, ...
'MaximumSampleRateOffset', maxSampleRateOffset);
end
end
end
0 Comments
Answers (0)
See Also
Categories
Find more on Modulation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!