From e5dd70fa6273c030c32336257ed630fe377de6fd Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sun, 6 Dec 2020 12:01:17 +0100 Subject: much better --- theremine.m | 94 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 32 deletions(-) (limited to 'theremine.m') diff --git a/theremine.m b/theremine.m index f6fb28c..11f0dc0 100644 --- a/theremine.m +++ b/theremine.m @@ -5,42 +5,50 @@ clear; %%%%%%%% % how many updates per second, determines the length of audio snippets -const_frames_per_second = 60; +const_frames_per_second = 100; -const_Fs = 96000; % sampling rate in Hz +const_Fs = 44100; % sampling rate in Hz const_te = 1/const_frames_per_second; % signal duration in seconds -const_samples_per_frame = const_Fs * const_te; +const_samples_per_frame = ceil(const_Fs * const_te); const_sample_range = 0:const_samples_per_frame-1; -const_fade_speed = 0.2; +% factor the last read frame is multiplied by +const_fade_speed = 0.975; % signal "generator" -signal = @(freq, amp) sin(freq ./ const_Fs .* 2 .* pi .* const_sample_range) * amp; +signal = @(freq) (freq ./ const_Fs .* 2 .* pi .* const_sample_range); % time given for calculation -const_calc_offset = 5; +const_calc_offset = 0; % 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)); +deviceWriter = audioDeviceWriter('SampleRate', const_Fs, 'SupportVariableSizeInput', true, 'BufferSize', 3 * const_samples_per_frame); %%%%%%%%%%%%%%%%%%% % init matleap by calling for first frame % %%%%%%%%%%%%%%%%%%% -matleap_frame; +matleap_frame -% runtime vars -P = NaN(100000,3); +% runtime variables +P = NaN(1000000,3); count = 1; done = false; -freq_one = 0; -freq_two = 0; +x_one = 0; +x_two = 0; -signal_one = signal(0,0); -signal_two = signal(0,0); +y_one = 0; +y_two = 0; + +offset_one = 0; +offset_two = 0; + +signal_one = sin(signal(0)); +signal_two = sin(signal(0)); full_signal = signal_one + signal_two; complete_signal = full_signal; @@ -49,7 +57,7 @@ complete_signal = full_signal; gesture_count = 0; %while count < 100000 && gesture_count < 3 -while gesture_count < (1.5 * (const_frames_per_second - const_calc_offset)) +while gesture_count < (1 * (const_frames_per_second - const_calc_offset)) frame = matleap_frame; handCount = size(frame.hands); @@ -57,16 +65,20 @@ while gesture_count < (1.5 * (const_frames_per_second - const_calc_offset)) gesture_count = 0; % slowly lower volume if no hand is there - signal_one = signal_one * const_fade_speed; - signal_two = signal_two * const_fade_speed; + y_one = y_one * const_fade_speed; + y_two = y_two * const_fade_speed; % TODO elseif isequal(one_hand, handCount) % fade hand two out - signla_two = signal_two * const_fade_speed; + y_two = y_two * const_fade_speed; + + pos = frame.hands(1).palm.position; + %pos = frame.hands(1).palm.stabilized_position; + + x_one = pos(1); + y_one = pos(2); - pos = frame.hands(1).palm.stabilized_position; - signal_one = get_theremin_sound_bit(pos(1), pos(2), signal); P(count, 1:3) = pos; count = count + 1; @@ -78,29 +90,43 @@ while gesture_count < (1.5 * (const_frames_per_second - const_calc_offset)) elseif isequal(two_hands, handCount) gesture_count = 0; - pos = frame.hands(1).palm.stabilized_position; - signal_one = get_theremin_sound_bit(pos(1), pos(2), signal); + pos = frame.hands(1).palm.position; + %pos = frame.hands(1).palm.stabilized_position; + + x_one = pos(1); + y_one = pos(2); + P(count, 1:3) = pos; count = count + 1; - pos = frame.hands(2).palm.stabilized_position; - signal_two = get_theremin_sound_bit(pos(1), pos(2), signal); + pos = frame.hands(2).palm.position; + %pos = frame.hands(2).palm.stabilized_position; + + x_two = pos(1); + y_two = pos(2); else - "That should not happen:" - handCount + disp("That should not happen:"); + disp(handCount); return; end % play current sound + [signal_one, offset_one] = get_theremin_sound_bit(x_one, y_one, offset_one, signal); + [signal_two, offset_two] = get_theremin_sound_bit(x_two, y_two, offset_two, signal); full_signal = signal_one + signal_two; + if deviceWriter(full_signal(:)) ~= 0 + disp("Buffer ran empty!"); + end complete_signal = [complete_signal full_signal]; % enforce frame rate, leaving a bit of room for calculation - java.lang.Thread.sleep((1/(const_frames_per_second - const_calc_offset)) * 1000); + %java.lang.Thread.sleep((1/(const_frames_per_second - const_calc_offset)) * 1000); end -theremin_player = audioplayer(complete_signal, const_Fs); -play(theremin_player); +release(deviceWriter) + +%theremin_player = audioplayer(complete_signal, const_Fs); +%play(theremin_player); % extract values x = P(:,1); % links (-) rechconst_Ts (+) (LED zu uns) @@ -129,7 +155,7 @@ xlabel('depth'); ylabel('left right'); zlabel('height'); -function sound = get_theremin_sound_bit(x, y, generator) +function [sound,offset] = get_theremin_sound_bit(x, y, offset, generator) % finding ranges for x and y: %'x' %min(x) @@ -141,8 +167,12 @@ function sound = get_theremin_sound_bit(x, y, generator) % --> 0 < y < 600 % therefore - volume = y / 600; - frequency = (x + 300) / 600 * 3000; % https://web.physics.ucsb.edu/~lecturedemonstrations/Composer/Pages/60.17.html # How it works + volume = y / 2000; + frequency = max(0.0001, (x + 400) / 1200) * 3000; % https://web.physics.ucsb.edu/~lecturedemonstrations/Composer/Pages/60.17.html # How it works - sound = generator(frequency, volume); + base = generator(frequency) + offset; + + offset = base(end); + + sound = sin(base) .* volume; end \ No newline at end of file -- cgit v1.2.3-54-g00ecf