### Archive

Archive for the ‘Uncategorized’ Category

## Digital Signal Processing Notes

I’ve made some note relating to Digital Signal Processing and the Discrete Fourier Transform available at http://pzdsp.com/docs.

I intend to add more documents to this over time.

Categories: Uncategorized

## Code to extract music notation from Flowkey app

``````% Matlab code to extract music notation from flowkey screen grab video . See https://youtu.be/4oOMWkMRCCg

ind = 5*25;
im = frame(430:660 ,: ,:);
new_im = rgb2gray(im);
prev_x = sum(new_im); % used to find bes overlap of frames

while 1
ind = ind+5*25;
if(ind > v.NumFrames)
break
end
im = frame(430:660 ,: ,:);
img = rgb2gray(im); %conver to greyscale
x = sum(img);
xc =[]; %stores cross correlation result
seg2 = prev_x(end-600+1:end); %end of previous frame
for w = 1: 300
seg1 = x(1+w:600+w);
xc(w) = sum(seg1.*seg2)./(sqrt(sum(seg1.^2)*sum(seg2.^2))); %cross correlation
end
[val loc] = max(xc); % loc is where the max correlation occurs

[ r c d] = size(im);
new_seg =img(:,201:end);
[ r1 c1 d1] = size(new_seg);
new_im(:,end-600+1-loc+200:end-600-loc+200+c1) = new_seg;
prev_x = x;

end
img = new_im;
% find where the bars occur in the image
for k =1: length(img)
x(k) = sum(img(95:145,k)); %the bar lines cross are clear from rows 75 to 125
end
bars = find(x<5000); %obtained value of 5000 by visually inspecting plot(x)

op_image_max_width = 2000;
op_image_max_height = 1200;

overlap = 10;
start_pt = overlap+1;
prev_end_pt = bars(1);
op_img = img(1,1);
k = 1;
img_num = 1;
while(k<length(bars))
end_pt = bars(k);
if(end_pt-start_pt>op_image_max_width)
[rows cols ] = size(img(:,start_pt-overlap:prev_end_pt+overlap));
[rows1 cols1] = size(op_img);
if(rows+rows1 > op_image_max_height)
imwrite(op_img, ['notation_' num2str(img_num) '.jpg']);
op_img = img(1,1);

img_num = img_num + 1;
end
op_img(end+1:end+rows,1:cols,:) = img(:,start_pt-10:prev_end_pt+10);
start_pt = prev_end_pt;
end
prev_end_pt = end_pt;
k = k + 1;
end

imwrite(op_img, ['notation_' num2str(img_num) '.jpg']);
``````
Categories: Uncategorized

## Arduino sinuoidal waveform generator and signal capture

I have put together an example on how to use the Arduino nano as a signal generator and digital capture device. It runs a pretty low sampling rate 2 kHz but I thought it might be of some use. Check out a video explanation at  https://youtu.be/_31sQn1Cg9g.  Files used are available at http://pzdsp.com/shared/arduino_sin_gen.zip

Categories: Uncategorized

## Virtual Oscilloscope

I’ve created a virtual oscilloscope that hopefully will help students learn how to work with real ones! It doesn’t have too many features so students can focus on the fundamentals that appear on all scopes: scaling, positioning and triggering.

Check it out at pzdsp.com/elab

Categories: Uncategorized

## DSP Foundations Notes

I’ve put together a set of notes introducing Digital Signal Processing. There’s only 25 pages but I hope that its enough to get someone started.

Categories: Uncategorized

## interpLTspice

```% This function interpolates data returned from the runLTspice function so
% as to make the time vector evenly spaced.
%
% example usage:
%   asc_file = 'filename.asc';
%   volt_curr_list =  runLTspice(asc_file);
%   results = runLTspice(asc_file, volt_curr_list);
%   fs = 10000;
%   interp_results = interpLTspice(results, fs);
%
% By David Dorran (david.dorran@dit.ie)
function data_struct = interpLTspice(data_struct, fs)
%check if the data is structured as expected
data_ok = 0;
if(isstruct(data_struct))
data_ok = 1;
if ~(isfield(data_struct,'data') && isfield(data_struct,'data_name') && isfield(data_struct,'time_vec'))
data_ok = 0;
end
end
if(~data_ok)
error('The variable passed to this function is not a data structure returned from runLTspice and cannot be processed')
end

if~(isnumeric(fs) && length(fs) ==  1 && fs > 0)
error('The second parameter used in this function should be a positive number representing the sampling frequency')
end

try t = data_struct.time_vec(1):1/fs:data_struct.time_vec(end);
catch
error(sprintf('A sampling rate of %f resulted in too much data (memory limits exceeded).\n\nTry a different sampling frequency using interpLTspcice(data_struct,fs);', fs));
end
for k = 1:length(data_struct.data)
data_struct.data{k} =  interp1(data_struct.time_vec, data_struct.data{k}, t);
end
data_struct.time_vec = t;

```
Categories: Uncategorized

## runLTspice demo

```%% Demonstration of the runLTspice function
%
% Demo video at http://youtu.be/ax9H4eKuZv4
%
%
%
% LTspice schematic available from:
%       https://www.dropbox.com/s/y7j1vmyscvppsn4/RC.asc?dl=0
%

%% read the voltage and currents from the circuit
result = runLTspice('C:\Temp\RC.asc', 'V(n002)');

plot(result.time_vec, result.data{1})
xlabel('Time(seconds)')
ylabel('Voltage')
title(result.data_name{1})

%% apply a step input and plot the capacitor current and voltage wavforms
fs = 200;
step = [zeros(1, fs/2) ones(1, fs/2)];

res = runLTspice('C:\Temp\RC.asc', 'V(n002), I(C1)' , 'V1', step, fs);

plot(res.time_vec, res.data{1})
hold on
plot(res.time_vec, res.data{2}*1000,'r')
xlabel('Time(seconds)')
ylabel('Amplitude')
hold off
legend([ res.data_name{1} ' (v)'],  [res.data_name{2} ' (mA)'])

%% apply a noisy square wave and compare the supply voltage with capacitor voltage
sq_wav = [step step step step];
high_f_noise = filter(1, [1 0.9], randn(1, length(sq_wav))*0.1);
ns_sq_wav = sq_wav + high_f_noise;

r = runLTspice('C:\Temp\RC.asc', 'V(n001), V(n002)' , 'V1', ns_sq_wav, fs);

plot(r.time_vec, r.data{1})
hold on
plot(r.time_vec, r.data{2},'r')
legend('supply voltage','smoothed voltage')
hold off

```
Categories: Uncategorized

## Audio time-scale modification – VSOLA algorithm in matlab

```function op = vsola(ip, tsm_factor, P)
% Implementation of the variable parameter  synchronised overlap add VSOLA algorithm
% This implementation makes use of the standard SOLA algorithm (Rocus and Wilgus, ICASSP 1986) and some efficient paramter settings for the SOLA algorithm (Dorran, Lawlor and Coyle, ICASSP 2003) and (Dorran, Lawlor and Coyle, DAFX 2003)
% Given an input, ip, the longest likely pitch period, P, and  and a time scale modification factor, tsm_factor, return an output, op, that is a time scaled version of the input. The synthesis_overlap_size is the length, in samples of the lowest likely fundametal period of the input.
% for speech synthesis_overlap_size is set to (16/1000)*fs samples and for music synthesis_overlap_size is typically set to (20/1000)*fs samples
%
% David Dorran, Audio Research Group, Dublin Institute of Technology
% david.dorran@dit.ie
% http://eleceng.dit.ie/dorran
% http://eleceng.dit.ie/arg
%

% make sure input is mono and transpose if necessary
[r, c] = size(ip);
if r > 1
ip = ip';
end;
[r, c] = size(ip);
if r > 1
disp('Note :only works on mono signals');
op = [];
return
end;

% initialize the values of analysis_frame_length, analysis_window_offset, synthesis_frame_offset and length_of_overlap
desired_tsm_len = round(length(ip)*tsm_factor);
P = round(P); %longest likely pitch period in samples
Lmax = round(P * 1.5);% found this to a reasonable value for the Lmax- Lmax is the duration over which the correlation function is applied
stationary_length = (P * 1.5); % found this to a reasonable value for the stationary length - This is the max duration that could be discarded/repeated

analysis_window_offset = round((stationary_length - P)/abs(tsm_factor - 1)); % this equation was derived.
synthesis_window_offset = round(analysis_window_offset * tsm_factor);
analysis_frame_length = round(Lmax + synthesis_window_offset);
number_of_analysis_frames = floor((length(ip)- analysis_frame_length)/analysis_window_offset);

if number_of_analysis_frames < 2 %not much time-scaling being done just return the input
op = ip;
return;
end;

%the next two lines just ensure that the last frame finishes at the very end of the signal (not essential)
zpad = zeros(1, (number_of_analysis_frames*analysis_window_offset) + analysis_frame_length - length(ip));

%initialize the output
op = zeros(1, desired_tsm_len);
%initialize the first output frame
op(1 : analysis_frame_length) = ip(1 : analysis_frame_length);

min_overlap = round(Lmax - P); %ensure that there is some minimum overlap
count = 0;

% Loop for the 2nd analysis frame to the number_of_analysis_frames
for m = 1 : number_of_analysis_frames

%grab the mth input frame
ip_frame = ip(analysis_window_offset * m : (analysis_window_offset * m) + analysis_frame_length - 1);

%grab the maximum overlapping segments from the inout frame and the current output
seg_1 = op(round(synthesis_window_offset*(m-1))+analysis_frame_length - Lmax : round(synthesis_window_offset*(m-1))+analysis_frame_length -1);
seg_2 = ip_frame(1: Lmax);

%compute the correlation of these segments
correlation   = xcorr(seg_2, seg_1,'coeff');

%Find the best point to overlap (opt_overlap_length) making sure not to exceed the maximum or go below the minimum overlap.
correlation(length(correlation) - Lmax -1: length(correlation)) = -100;
correlation(1: min_overlap) = -100;
[max_correlation, opt_overlap_length] = max(correlation);

if(max_correlation == 0)
opt_overlap_length = Lmax;
end;
%     offset = Lmax - opt_overlap_length;
%     if ((offset + analysis_window_offset -  synthesis_window_offset) >= 0 & (offset + analysis_window_offset -  synthesis_window_offset) <= P)
%         count = count +1;
%     end;

% append mth analysis frame to the current synthesised output using a linear cross fade
ov_len =(round(synthesis_window_offset*m)+analysis_frame_length) - (round(synthesis_window_offset*(m-1))+analysis_frame_length - Lmax) + 1;
ov_seg = ov_seg(1:ov_len);
op(round(synthesis_window_offset*(m-1))+analysis_frame_length - Lmax: round(synthesis_window_offset*m)+analysis_frame_length) = ov_seg;

end; % end of for loop

% linear cross fade the first segment with the second segment given a certain amount of overlap
% |----------seg1----------|
%			   |---------------seg2-----------------------|
%              |--overlap-|

error(nargchk(3,4,nargin));
if nargin < 4
end
end
% overlap the end of seg_1 with the start of seg_2 using a linear cross-fade
if (length(seg_1) < overlap_length),
seg_2 = seg_2(overlap_length - length(seg_1) + 1: length(seg_2));
overlap_length = length(seg_1);
end; % end of if statement

if (length(seg_2) < overlap_length),
seg_1 = seg_1(length(seg_1) - (overlap_length - overlap_length): length(seg_1));
overlap_length = length(seg_2);
end; % end of if statement

overlapping_region = zeros(1, cross_fade_duration); % initialize the overlapping region
seg_1 = seg_1(1: length(seg_1) - (overlap_length - cross_fade_duration));

op = zeros(1, length(seg_1) + length(seg_2) - cross_fade_duration);

if(overlap_length ~= 1)
end;

```

## pic18f4620 xc8 compiler bundle

Here’s a small (5.2 MB) bundle that I use to compile and program c code on my pic18f4620 using a pickit2 on my PC. I’ve only tested this on XP.

It doesn’t have all the features of a full blown IDE like MPLABX (no stepping through code I’m afraid) but is a nice concise package that encourages the use of command line scripting.

Getting Started

• Extract the files to a folder on your PC or USB key The extracted folder contains the xc8 compiler files (modified to work with the pic18f4620 only), the pk2cmd software tool which is used to communicate with the PICkit2, and Notepad++, which can be used to write and modify code.

To create a new project do the following:

1. First create a new folder inside the “robosumo_files” folder and copy the build.bat file into that folder.
2.  Run the Notepad++  editor and paste the example code (flashing LED) given below. Save the code in the new folder as a file called “main.c” (don’t include quotes in the filename).
3. Make sure the PICkit2 programmer is correctly connected to the PIC18f4620 and finally double click the build.bat file.
4. If there are no errors in the code and the hardware is set up correctly then the PIC18f4620 will be programmed.

## Example Code – Flashing LED

This is a pared back example program for the PIC18F4620. It blinks an LED connected to pin 19 (RD0). See this circuit

```//
// PIC18F4620 example program
// Written by Ted Burke (ted.burke@dit.ie)
// Last update 28-2-2013
//

#include &lt;xc.h&gt;

#pragma config OSC=INTIO67,MCLRE=OFF,WDT=OFF,LVP=OFF,BOREN=OFF

int main(void)
{
// Make RD0 a digital output
TRISD = 0b11111110;

while(1)
{
LATDbits.LATD0 = 1; // Set pin RD0 high
_delay(125000);     // 0.5 second delay
LATDbits.LATD0 = 0; // Set pin RD0 low
_delay(125000);     // 0.5 second delay
}
}
```
Categories: pic18f, Uncategorized

## pic18f4620 assembly bundle

Here’s a small (3.6 MB) bundle that I use to program my pic18f4620 using a pickit2 with assembly code on my PC. I’ve only tested this on XP.

It doesn’t have all the features of a full blown IDE like MPLABX (no stepping through code I’m afraid) but is a nice concise package that encourages the use of command line scripting.

The bundle also includes some example code.

### Getting Started

The extracted folder contains the mpasmx assembler files, the pk2cmd software tool which is used to communicate with the PICkit2, and Notepad++ text editor, which can be used to write and modify code.

The bundle includes 6 example projects.

To create a new project do the following:

1. First create a new folder inside the “pic18f4620_asm” folder and copy the build.bat file into that folder.
2. Run the Notepad++ editor and paste the example code (flashing LED) given below. Save the code in the new folder as a file called “main.asm” (don’t include quotes in the filename).
3. Make sure the PICkit2 programmer is correctly connected to the PIC18f4620 and finally double click the build.bat file.
4. If there are no errors in the code and the hardware is set up correctly then the PIC18f4620 will be programmed.

Example Code to work with this circuit
This code will flash the LED connected to pin 19 (RD0)

```;configure the  assembler directive 'list' so as to set processor to 18f4620 and set the radix used for data expressions to decimal (can be HEX|DEC|OCT)
list p=18f4620, r=DEC
#include <p18f4620.inc>
; configure the micro so that the watchdog timer is off, low-voltage programming is off, master clear is off and the clock works off the internal oscillator
config WDT=OFF, LVP=OFF, MCLRE=OFF, OSC=INTIO67
;The org directive tells the compiler where to position the code in memory
org 0x0000 ;The following code will be programmed in reset address location i.e. This is where the micro jumps to on reset

;--------------------------------------------------------------------------
; Main Program
;--------------------------------------------------------------------------

org 0x0100
Main
clrf TRISD ; All PORT D IO pins are configured as outputs

; Set up timer 0 so it can be used to control flash rate
bcf T0CON, T0CS; use internal instruction cycle clock
bcf T0CON, T08BIT; use 16 bit mode
bcf INTCON, TMR0IF; reset timer overflow flag
bsf T0CON, TMR0ON; turn on timer 0

loop
; check if the timer0 overflow flag has been set
btfss INTCON, TMR0IF
goto loop
bcf INTCON, TMR0IF; reset timer overflow flag

;invert LATD0
movlw 0x1
XORWF LATD,F

goto loop
END

```
Categories: pic18f, Uncategorized