annotate signals/@sigresample/construct.m @ 61:eff6bddf82e3 tip

Finally implemented perceptual brightness thing.
author samer
date Sun, 11 Oct 2015 10:20:42 +0100
parents 289445d368a7
children
rev   line source
samer@1 1 function s2=construct(sig)
samer@1 2
samer@1 3 fprintf('\nResampling %s to %g Hz...\n',tostring(sig.source),sig.rate);
samer@1 4 f1=rate(sig.source);
samer@1 5 f2=sig.rate;
samer@1 6 c=channels(sig);
samer@1 7
samer@1 8 [p,q]=rat(f2/f1,1e-12);
samer@1 9 sysobj=design(sig,p,q);
samer@1 10
samer@1 11
samer@1 12 delay=(length(sysobj.Numerator)-1)/2;
samer@1 13 outdelay = ceil(delay/q);
samer@1 14 indelay = ceil(delay/p);
samer@1 15 m=max(1,floor(sig.opts.bs/q)); % try to approximate requested input block size
samer@1 16 fprintf('Input/output delays are %d and %d.\n',indelay,outdelay);
samer@1 17 fprintf('Read block size is %d.\n\n',m*q);
samer@1 18
samer@1 19 s1=construct(sig.source & sigarray(zeros(channels(sig.source),indelay)));
samer@1 20 r1=s1.reader(m*q); % one and only input reader
samer@1 21 chunk=uint32(m*p); % filter output block size
samer@1 22 CHUNK=1:chunk;
samer@1 23 queue=[];
samer@1 24
samer@1 25 s2.start = s1.start;
samer@1 26 s2.stop = s1.stop;
samer@1 27 s2.dispose = @dispose;
samer@1 28 s2.reader = @reader;
samer@1 29
samer@1 30 % drop some samples to account for filter delay
samer@1 31 s2.start();
samer@1 32 sigreadn(s2,outdelay);
samer@1 33 s2.stop();
samer@1 34
samer@1 35 function dispose, s1.dispose(); release(sysobj); end
samer@1 36 function r2=reader(n)
samer@1 37 outbuf=zeros(c,n);
samer@1 38 r2=@next;
samer@1 39
samer@1 40 function [x,rem]=next
samer@1 41 % transfer up to n queued samples to outbuf
samer@1 42 pos=uint32(size(queue,2));
samer@1 43 if pos>=n % enough samples already waiting
samer@1 44 outbuf=queue(:,1:n);
samer@1 45 queue=queue(:,n+1:end);
samer@1 46 rem=0;
samer@1 47 else
samer@1 48 if pos==0, toread=n;
samer@1 49 else % use up queue
samer@1 50 outbuf(:,1:pos)=queue; queue=[];
samer@1 51 toread=n-pos;
samer@1 52 end
samer@1 53
samer@1 54 % transfer complete chunks
samer@1 55 while toread>=chunk
samer@1 56 [outbuf(:,pos+CHUNK),rem]=filter_next;
samer@1 57 toread=toread-chunk;
samer@1 58 pos=pos+chunk;
samer@1 59 if rem>0 % we ran out of samples
samer@1 60 rem=rem+toread; % account for rest of missing samples (not just this chunk)
samer@1 61 toread=0; % causes immediate exit after this
samer@1 62 end
samer@1 63 end
samer@1 64
samer@1 65 % transfer partial chunk if necessary
samer@1 66 if toread>0
samer@1 67 [y,rem]=filter_next;
samer@1 68 outbuf(:,pos+1:n)=y(:,1:toread);
samer@1 69 queue=y(:,toread+1:chunk-rem);
samer@1 70 rem=max(0,toread-(chunk-rem));
samer@1 71 end
samer@1 72 end
samer@1 73 x=outbuf;
samer@1 74 end
samer@1 75
samer@1 76 % returns the next block of m*p output samples
samer@1 77 function [x,rem]=filter_next
samer@1 78 [y,rem1]=r1();
samer@1 79 if rem1>0,
samer@1 80 y(:,end-rem1+1:end)=zeros(c,rem1); % pad with zeros
samer@1 81 rem=uint32(ceil(rem1*p/q)); % round down the number of valid samples
samer@1 82 else
samer@1 83 rem=rem1;
samer@1 84 end
samer@1 85 x=step(sysobj,y')';
samer@1 86 end
samer@1 87 end
samer@1 88 end