clear; %%%%%%%% % "constants" % %%%%%%%% % how many updates per second, determines the length of audio snippets const_frames_per_second = 60; const_Fs = 96000; % sampling rate in Hz const_te = 1/const_frames_per_second; % signal duration in seconds const_samples_per_frame = const_Fs * const_te; const_sample_range = 0:const_samples_per_frame-1; const_fade_speed = 0.2; % signal "generator" signal = @(freq, amp) sin(freq ./ const_Fs .* 2 .* pi .* const_sample_range) * amp; % time given for calculation const_calc_offset = 5; % 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)); %%%%%%%%%%%%%%%%%%% % init matleap by calling for first frame % %%%%%%%%%%%%%%%%%%% matleap_frame; % runtime vars P = NaN(100000,3); count = 1; done = false; freq_one = 0; freq_two = 0; signal_one = signal(0,0); signal_two = signal(0,0); full_signal = signal_one + signal_two; complete_signal = full_signal; % time gestures, used for program termination gesture_count = 0; %while count < 100000 && gesture_count < 3 while gesture_count < (1.5 * (const_frames_per_second - const_calc_offset)) frame = matleap_frame; handCount = size(frame.hands); if isequal(zero_hands, handCount) 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; % TODO elseif isequal(one_hand, handCount) % fade hand two out signla_two = signal_two * const_fade_speed; 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; if frame.gesture > 0 gesture_count = gesture_count + 1; else gesture_count = 0; end 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); 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); else "That should not happen:" handCount return; end % play current sound full_signal = signal_one + signal_two; 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); end theremin_player = audioplayer(complete_signal, const_Fs); play(theremin_player); % extract values x = P(:,1); % links (-) rechconst_Ts (+) (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'); function sound = get_theremin_sound_bit(x, y, generator) % finding ranges for x and y: %'x' %min(x) %max(x) %'y' %min(y) %max(y) % --> -300 < x < 300 % --> 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 sound = generator(frequency, volume); end