-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjp_maketoneinnoise.m
120 lines (82 loc) · 2.44 KB
/
jp_maketoneinnoise.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
function [y, fs] = jp_maketoneinnoise(delayToneSec, SNR, Cfg)
%JP_MAKETONEINNOISE Make tone in noise (possibly following AM noise).
%
% Y = JP_MAKETONEINNOISE(DELAY) presents the tone after DELAY (seconds).
%
% JP_MAKETONEINNOISE(DELAY,CFG) allows specifying copius amount of other
% options in CFG. Not documented yet (sorry), so just look at the code for
% options.
%
%
%
% [Y, FS] = JP_MAKETONEINENOISE... also returns the sampling rate FS.
%
%
%
%
% See also JP_MAKETONEINNOISE_WRAPPER.
if nargin < 2
SNR = 0;
end
if nargin < 3
Cfg = [];
end
if ~isfield(Cfg, 'fs') || isempty(Cfg.fs)
Cfg.fs = 22050;
end
if ~isfield(Cfg, 'toneFreqHz') || isempty(Cfg.toneFreqHz)
Cfg.toneFreqHz = 1000;
end
if ~isfield(Cfg, 'toneDurationSec') || isempty(Cfg.toneDurationSec)
Cfg.toneDurationSec = 0.25;
end
if ~isfield(Cfg, 'AMFreqHz') || isempty(Cfg.AMFreqHz)
Cfg.AMFreqHz = 3;
end
if ~isfield(Cfg, 'AMdurationSec') || isempty(Cfg.AMdurationSec)
Cfg.AMdurationSec = 3;
end
if ~isfield(Cfg, 'steadyNoiseDurationSec') || isempty(Cfg.steadyNoiseDurationSec)
Cfg.steadyNoiseDurationSec = 3;
end
yMax = 0.4; % +/- max of noise
yMaxTone = .1; % max of tone
AMCfg = [];
AMCfg.plot = 0;
AMCfg.modulationDepth = .8;
AMCfg.fs = Cfg.fs;
%% Make a tone
toneCfg = [];
toneCfg.fs = Cfg.fs;
[yTone, fs] = jp_maketone(Cfg.toneFreqHz, Cfg.toneDurationSec, toneCfg);
yTone = yTone / (max(yTone)/yMaxTone);
%% Make the AM noise
[yAM, fs] = jp_makeAMnoise(Cfg.AMFreqHz, Cfg.AMdurationSec, AMCfg);
yAM = yAM / (max(yAM)/yMax);
yNoise = yMax * (2*rand(Cfg.steadyNoiseDurationSec * fs, 1) - 1);
%% Figure out dB, scale
rmsTone = jp_rms(yTone);
dbTone = jp_mag2db(rmsTone);
rmsNoise = jp_rms(yNoise);
dbNoise = jp_mag2db(rmsNoise);
targetDb = dbTone - SNR; % target for noise dB
targetRMS = 10^(targetDb/20);
scaleFactor = targetRMS/rmsNoise;
scaledNoise = yNoise * scaleFactor;
rmsScaledNoise = jp_rms(scaledNoise);
dbScaledNoise = jp_mag2db(rmsScaledNoise);
fprintf('SNR %g:\tsignal = %.1f, noise = %.1f dB\n', SNR, dbTone, dbScaledNoise);
yNoiseTone = scaledNoise;
delayToneSamples = round(delayToneSec * fs);
lengthToneSamples = length(yTone);
yNoiseTone(delayToneSamples:delayToneSamples+lengthToneSamples-1) = yNoiseTone(delayToneSamples:delayToneSamples+lengthToneSamples-1) + yTone;
%% Add
y = [yAM; yNoiseTone];
if max(y) > 1
warning('Signal clipping at %g.', max(yNoiseTone));
end
%%
% figure
%
% plot(yNoiseTone)
% you can play this: soundsc(y, fs)