필터 지우기
필터 지우기

Making a Square Wave Gradually

조회 수: 3 (최근 30일)
Cody Gass
Cody Gass 2014년 5월 21일
댓글: Cody Gass 2014년 5월 22일
I made a script where I have a square wave audioplayer made from sine waves based off of
for k = 1:2:order
x = x + (sin(k*2*pi.*f.*t))/k;
y((k+1)/2,:) = x;
pause(.01)
end
where f is an array based off the equation 2^x, and t is another array 0:1/fs:T used for sampling. f is used to select frequencies in an exponential manner so that the pitch goes up linearly. This worked very well, but I wanted to try the same thing but flipped around. The script I'm working on takes a certain frequency and creates a waveform that gradually evolves from a sine wave to a square wave. This is what I have so far:
function GradualSquareWave(order,f,T,fs)
tic
t = 0:1/fs:T;
timeDomain = 0:1:(fs * T);
y = zeros(size(t * order));
x = zeros(size(t));
h = waitbar(0,'Initializing Fourier Series');
for k = 1:2:order
x = x + (sin(k*2*pi*f.*t))/k;
y(1 + timeDomain + (((k+1)/2)-1)*fs) = x;
if k/order > .05
waitbar(k/order,h,sprintf('Computing Fourier Series %6.2g%%',(100 * k)/order))
end
pause(.01)
end
elapsedTime = toc;
if elapsedTime < 1
waitbar(1,h,sprintf('Playing Square Wave to Order %d after %6.4g seconds',order,elapsedTime))
end
if elapsedTime >= 1
waitbar(1,h,sprintf('Playing Square Wave to Order %d after%6.4g seconds',order,elapsedTime))
end
player = audioplayer(y,fs);
play(player)
pause(T)
close(h)
It seems that most of it is working just fine and dandy, but I'm not getting the full transition. For each k value, the audioplayer plays a one-second section of the wave form and cuts off at T seconds. If there aren't T sections to play, the last section is extended to T. I have no idea why each section is played for precisely one second. I want each section to last T/((order+1)/2) seconds so that each section of the wave form is played equally throughout time T. If anybody could help me out, I'd really appreciate it.
  댓글 수: 1
Walter Roberson
Walter Roberson 2014년 5월 22일
As a debugging step, examine size(y) before the "for k" loop, and also after the "for k" loop. Also give us some sample input parameters to test with.

댓글을 달려면 로그인하십시오.

채택된 답변

Hugo
Hugo 2014년 5월 22일
Each section is being played for one second because you are setting that in the line
y(1 + timeDomain + (((k+1)/2)-1)*fs) = x;
The key is in the part ((k+1)/2)-1)*fs. When k=1, ((k+1)/2)-1)*fs=0, but when k=3 (which is the next loop in the for statement) ((k+1)/2)-1)*fs=fs. But fs is the number of samples in one second, so the new segment starts one second after the previous one, making the previous one of one second in length.
Notice however that the last segment will have a length equal to T.
To solve this, you should write
y(1 + timeDomain + (((k+1)/2)-1)*fs*T/((order+1)/2)) = x;
This statement will give you a length of T/((order+1)/2) as you requested, but be careful that the number should be an integer.
Just in case, notice that the for loop advances in steps of 2.
Hope this helps.
  댓글 수: 1
Cody Gass
Cody Gass 2014년 5월 22일
I had a feeling that was what was wrong. The only problem is that it limits my ability to set the order. Is there any way to get around that without rewriting the whole code? If not, I'll use what you've told me. Thank you, I appreciate it.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by