clear; %%%%%%%% % "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_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 const_fade_speed = 0.975; % signal "generator" signal = @(freq) (freq ./ const_Fs .* 2 .* pi .* const_sample_range); % time given for calculation 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 % runtime variables P = NaN(1000000,3); count = 1; done = false; x_one = 0; x_two = 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; % time gestures, used for program termination gesture_count = 0; %while count < 100000 && gesture_count < 3 while gesture_count < (1 * (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, offset_one] = get_theremin_sound_bit(x_one, y_one * const_fade_speed, offset_one, signal); [signal_two, offset_two] = get_theremin_sound_bit(x_two, y_two * const_fade_speed, offset_two, signal); % TODO elseif isequal(one_hand, handCount) % fade hand two out [signal_two, offset_two] = get_theremin_sound_bit(x_two, y_two * const_fade_speed, offset_two, signal); pos = frame.hands(1).palm.position; %pos = frame.hands(1).palm.stabilized_position; x_one = pos(1); y_one = pos(2); [signal_one, offset_one] = get_theremin_sound_bit(x_one, y_one, offset_one, 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.position; %pos = frame.hands(1).palm.stabilized_position; x_one = pos(1); y_one = pos(2); [signal_two, offset_two] = get_theremin_sound_bit(x_two, y_two * const_fade_speed, offset_two, signal); P(count, 1:3) = pos; count = count + 1; pos = frame.hands(2).palm.position; %pos = frame.hands(2).palm.stabilized_position; x_two = pos(1); y_two = pos(2); [signal_two, offset_two] = get_theremin_sound_bit(x_two, y_two, offset_two, signal); else disp("That should not happen:"); disp(handCount); return; end % play current sound 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); end release(deviceWriter) %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,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) % --> -300 < x < 300 % --> 0 < y < 600 % therefore 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 base = generator(frequency) + offset; offset = base(end); sound = sin(base) .* volume; end