summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Halle <niklas@niklashalle.net>2021-04-05 15:23:02 +0200
committerNiklas Halle <niklas@niklashalle.net>2021-04-05 15:23:02 +0200
commitcf424d42e34700b72173c265c75485ae81a5ab05 (patch)
tree557b6e3a7f5bb5c7865d17d331547ae085511b79
parentea698a54a82ff5c20236ff09e592354dfe25798a (diff)
downloadwdti_project-cf424d42e34700b72173c265c75485ae81a5ab05.tar.gz
wdti_project-cf424d42e34700b72173c265c75485ae81a5ab05.zip
bettering
-rw-r--r--matleap.cpp2
-rw-r--r--theremin.m137
2 files changed, 78 insertions, 61 deletions
diff --git a/matleap.cpp b/matleap.cpp
index 4a24d3d..7f109c9 100644
--- a/matleap.cpp
+++ b/matleap.cpp
@@ -252,7 +252,7 @@ void matleap::frame_grabber::open_connection() {
}
void matleap::frame_grabber::close_connection() {
- mexPrintf("Good bye.");
+ mexPrintf("Good bye.\n");
}
matleap::frame_grabber::~frame_grabber() {
diff --git a/theremin.m b/theremin.m
index 22f9991..3a1ebfe 100644
--- a/theremin.m
+++ b/theremin.m
@@ -1,33 +1,37 @@
clear;
-%%%%%%%%
+show_graphs = false;
+
+%%%%%%%%%%%%%%%
% "constants" %
-%%%%%%%%
+%%%%%%%%%%%%%%%
% how many updates per second, determines the length of audio snippets
const_frames_per_second = 100;
-const_Fs = 44100; % sampling rate in Hz
+const_Fs = 44100; % sample rate in Hz
const_te = 1/const_frames_per_second; % signal duration in seconds
const_samples_per_frame = ceil(const_Fs * const_te);
const_sample_range = 0:const_samples_per_frame-1;
-% factor the last read frame is multiplied by
+% the smaller the value, the quicker the fade out
const_fade_speed = 0.975;
-% signal "generator"
-signal = @(freq) (freq ./ const_Fs .* 2 .* pi .* const_sample_range);
+% signal "generator" - only gives the input for sin()
+% it does not apply the sin function yet, see below for reasoning
+signal_f = @(freq) (freq ./ const_Fs .* 2 .* pi .* const_sample_range);
% dimensions to use for detecting number of hands in frame
zero_hands = size(NaN(0,0));
-one_hand = size(NaN(1,1));
-two_hands = size(NaN(1,2));
+one_hand = size(NaN(1,1));
+two_hands = size(NaN(1,2));
-deviceWriter = audioDeviceWriter('SampleRate', const_Fs, 'SupportVariableSizeInput', true, 'BufferSize', 3 * const_samples_per_frame);
+deviceWriter = audioDeviceWriter('SampleRate', const_Fs, ...
+ 'SupportVariableSizeInput', true, 'BufferSize', 3 * const_samples_per_frame);
-%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% init matleap by calling for first frame %
-%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
matleap_frame;
% runtime variables
@@ -38,18 +42,16 @@ done = false;
frequency_pos = 0;
height_pos = 0;
-offset_one = 0;
-offset_two = 0;
+offset = 0;
-signal_one = sin(signal(0));
-signal_two = sin(signal(0));
+signal = sin(signal_f(0));
-full_signal = signal_one + signal_two;
-complete_signal = full_signal;
+complete_signal = signal;
% time gestures, used for program termination
gesture_count = 0;
+% main loop
while gesture_count < const_frames_per_second
frame = matleap_frame;
handCount = size(frame.hands);
@@ -95,17 +97,15 @@ while gesture_count < const_frames_per_second
end
% play current sound
- [signal_one, offset_one] = get_theremin_sound_bit(frequency_pos, height_pos, offset_one, signal);
- %[signal_two, offset_two] = get_theremin_sound_bit(x_two, y_two, offset_two, signal);
- full_signal = signal_one;% + signal_two;
+ [signal, offset] = get_theremin_sound_bit(frequency_pos, height_pos, offset, signal_f);
- buffer_under_flow = deviceWriter(full_signal(:));
+ buffer_under_flow = deviceWriter(signal(:));
if buffer_under_flow ~= 0
disp("Buffer ran empty!");
end
- complete_signal = [complete_signal full_signal];
+ complete_signal = [complete_signal signal];
end
release(deviceWriter)
@@ -113,50 +113,67 @@ release(deviceWriter)
%theremin_player = audioplayer(complete_signal, const_Fs);
%play(theremin_player);
-% extract values
-x = P(:,1); % links (-) rechts (+) (LED zu uns)
-y = P(:,2); % oben unten
-z = P(:,3); % vorne (+) hinten (-) (LED zu uns)
-
-% plot
-figure("Position",[0,0, 1200, 2400]);
-t = tiledlayout(4,1);
-
-nexttile;
-plot(x);
-ylabel('left right');
-
-nexttile;
-plot(y);
-ylabel('height');
-
-nexttile;
-plot(z);
-ylabel('depth');
+if show_graphs == true
+ % extract values
+ x = P(:,1); % links (-) rechts (+) (LED zu uns)
+ y = P(:,2); % oben unten
+ z = P(:,3); % vorne (+) hinten (-) (LED zu uns)
+
+ % plot
+ figure("Position",[0,0, 1200, 2400]);
+ t = tiledlayout(4,1);
+
+ nexttile;
+ plot(x);
+ ylabel('left right');
+
+ nexttile;
+ plot(y);
+ ylabel('height');
+
+ nexttile;
+ plot(z);
+ ylabel('depth');
+
+ nexttile;
+ plot3(z,x,y);
+ xlabel('depth');
+ ylabel('left right');
+ zlabel('height');
+
+ %{
+ % Plot both audio channels
+ N = size(complete_signal,2); % Determine total number of samples in audio file
+ figure;
+ subplot(1,1,1);
+ stem(1:N, complete_signal(1,:));
+ title('Audio Channel');
+ % Plot the spectrum
+ df = const_Fs / N;
+ w = (-(N/2):(N/2)-1)*df;
+ y = fft(complete_signal(1,:), N) / N; % For normalizing, but not needed for our analysis
+ y2 = fftshift(y);
+ figure;
+ plot(w,abs(y2));
+ %}
+end
-nexttile;
-plot3(z,x,y);
-xlabel('depth');
-ylabel('left right');
-zlabel('height');
+disp('If you want to save your audio, run `audiowrite(<.wav filename>, complete_signal, const_Fs)`');
function [sound,offset] = get_theremin_sound_bit(x, y, offset, generator)
- % finding ranges for x and y:
- %'x'
- %min(x)
- %max(x)
- %'y'
- %min(y)
- %max(y)
- % --> 50 < x < 270
- % --> 90 < y < 350
-
- volume = (y) / 1300;
- frequency = max(0.003, (x - 50) / 220) * 1000; % https://web.physics.ucsb.edu/~lecturedemonstrations/Composer/Pages/60.17.html # How it works
-
+ % the values used here are mostly empirical
+ volume = y / 1300;
+ % How it works:
+ % https://web.physics.ucsb.edu/~lecturedemonstrations/Composer/Pages/60.17.html
+ frequency = max(0.003, (x - 50) / 220) * 1000; % have at least 3Hz
+
+ % here we generate the array to put into sin(), but offset it with the
+ % the previous frames offset..
base = generator(frequency) + offset;
+ % ..which we take from here - doing so stops us from phase jumping
offset = base(end);
+ % at last, apply the volume
sound = sin(base) .* volume;
end \ No newline at end of file