Buffering, Timing, and Phase Errors

Một phần của tài liệu Digital signal processing using MATLAB for students and researchers john w leis (Trang 140 - 144)

5.3 DISCRETE - TIME WAVEFORM GENERATION

5.3.4 Buffering, Timing, and Phase Errors

Once an appropriate method of generating the wave samples has been decided upon, it is necessary to think about how the samples are to be used in practice. If we are developing an audio or communications system, for example, the actual output of the sample values to the D/A hardware will likely be done by a separate digital signal processor chip. The reason for this is that the actual output of individual samples is usually done by interrupting the processor, which must then execute a routine to fetch the next sample from memory and send it to the hardware to generate the analog representation. If the sample rate is reasonably high, this constitutes a sig- nifi cant burden on the host CPU. For this reason, the underlying DSP processor subsystem does not usually deal with individual samples, but rather blocks of samples. The size of the block is necessarily a trade - off between lower processor requirements (using a larger block) and the amount of delay which can be tolerated (requiring a smaller block). It is the responsibility of the operating system and application using the signal to arrange for a block to be generated. There are two practical problems which arise in this scenario: The phase of the generated wave- form, and the timing of gaps in the blocks. We look at each in turn.

cosnw = 1;

sinnw = 0;

% arrays to store resulting sine/cosine values

%(not needed in practice, only to show the

% computed waveform values in this example) sinvals = [];

cosvals = [];

% note that no trig functions are used in this

% loop only multiply and add/subtract for n = 0:N −1

% save values in array sinvals = [sinvals sinnw];

cosvals = [cosvals cosnw];

% recurrence relations for new values of % sin(nw + w) and cos(nw + w)

newcos = cosnw * cosw − sinnw * sinw;

newsin = sinnw * cosw + cosnw * sinw;

% new values become current ones cosnw = newcos;

sinnw = newsin;

end fi gure (1);

stem (sinvals);

fi gure (2);

stem (cosvals);

c05.indd 133

c05.indd 133 4/13/2011 5:22:10 PM4/13/2011 5:22:10 PM

134 CHAPTER 5 REPRESENTING SIGNALS AND SYSTEMS

Suppose we have a block of output samples calculated and ready to transfer to the output device. We do this, and then start work on the next block. A problem arises if we start the next buffer using zero initial conditions. The blocks should seamlessly overlap, since the blocking is done only as a convenience to the hardware and software, and should not be visible in the output waveform. Figure 5.4 shows the situation which may arise. The middle of the upper plot is aligned with the block boundary. The waveform from block m may terminate at any amplitude, according to the frequency of the wave and the number of samples. As illustrated, it appears that the waveform abruptly ends at a particular phase. Block ( m + 1) then starts at zero phase.

What does this mean in practice? Consider an audio system which is required to generate a waveform. Some typical fi gures will help fi x the idea. Suppose the sampling rate is 8 kHz, and we wish to generate a 250 Hz sinewave. Suppose the block size is 400 samples. This equates to 20 blocks per second. If we do not take into account the block boundaries, the situation depicted in Figure 5.5 arises. The discontinuities at the end of each block manifest themselves as an additional com- ponent at a rate equal to the block rate — in this case, 20 Hz. In audio systems, the noise thus introduced can be particularly objectionable at this frequency.

FIGURE 5.4 Illustrating the problem of matching the end of one block with the start of the next. Here, the block boundary occurs at index 100. In the upper plot, the subsequent block starts generating the sinusoid anew. The lower block starts the waveform using a phase which is adjusted so as to make the transition seamless. This phase is φ = θ + ω , where θ is the ending phase of the previous block, and ω is the phase increment per sample.

0 20 40 60 80 100 120 140 160 180 200

−2

−1 0 1

2 No phase correction

0 20 40 60 80 100 120 140 160 180 200

−2

−1 0 1

2 With phase correction

c05.indd 134

c05.indd 134 4/13/2011 5:22:10 PM4/13/2011 5:22:10 PM

5.3 DISCRETE-TIME WAVEFORM GENERATION 135

The following shows how we initialize the system in order to generate such a waveform. The block buffer is Bbuf, and this is the buffer which is prepared by the main CPU and passed to the DSP subsystem. The buffer Sbuf contains all the sound samples. In practice, this would not be required, but since we are generating the entire waveform for subsequent playback, it is necessary for this demonstration. In this case, it stores 4 seconds of audio.

FIGURE 5.5 Showing multiple blocks and the discontinuity that can result at block boundaries. If this waveform were an audio waveform, the relative frequency of the blocks as compared with the waveform itself would mean that objectionable audible artifacts would be present.

0 200 400 600 800 1,000 1,200 1,400 1,600

−2

−1 0 1 2

Output waveform with no phase correction

Sample index (block size = 400 samples)

f = 250; % frequency in Hz fs = 8000; % sampling frequency B = 20; % blocks/sec

L = 400; % samples per block D = 4; % duration in seconds

% block buffer and output buffer Bbuf = zeros (L, 1);

Sbuf = zeros (fs * D, 1); % = B * L * D Omega = 2 * pi * f;

T = 1/fs;

omega = Omega * T;

NBlocks = B * D;

The following shows how we generate the samples for each block of audio.

Note that the phase increment per sample is ω radians per sample as per earlier theory, and in the code is denoted as omega. At the end of each individual block calculation, we copy the data into the fi nal output buffer. In a real - time system, this step would not be necessary, and would be replaced with a system call to transfer the data block of L samples to the output DSP subsystem.

c05.indd 135

c05.indd 135 4/13/2011 5:22:10 PM4/13/2011 5:22:10 PM

136 CHAPTER 5 REPRESENTING SIGNALS AND SYSTEMS

Now we address the problem of aligning the waveform, so that the transition between buffers is seamless. There are several ways to accomplish this, and the method below simply uses a phase start φ (phi) in the per - sample calculation. The phase angle at the end of the block is then stored for the start of the next block.

Since this phase would continue to increment, at some point it might overfl ow.

But because any phase over 2 π can be mapped back into the range 0 – 2 π , we subtract the overfl ow as shown in the loop.

pSbuf = 1;

phi = 0;

for b = 1:NBlocks

% generate one block worth of samples, correct phase % offset

for n = 1:L

theta = (n − 1) * omega + phi;

x = sin (theta);

Bbufpc(n) = x;

end

% phase for next block

phi = theta + omega; % 1 * omega at next sample % correct if over 2pi

while ( phi > 2 * pi ) phi = phi − 2 * pi ; end

% save block in output buffer

Sbufpc(pSbuf:pSbuf + L − 1) = Bbufpc;

% point to start of next output block pSbuf = pSbuf + L;

end

pSbuf = 1;

for b = 1:NBlocks

% generate one block worth of samples, phase % independent

for n = 1:L

theta = (n − 1) * omega;

x = sin (theta);

Bbuf(n) = x;

end

% save the block in the output buffer Sbuf (pSbuf:pSbuf + L − 1) = Bbuf;

% point to start of next output block pSbuf = pSbuf + L;

end

c05.indd 136

c05.indd 136 4/13/2011 5:22:10 PM4/13/2011 5:22:10 PM

Một phần của tài liệu Digital signal processing using MATLAB for students and researchers john w leis (Trang 140 - 144)

Tải bản đầy đủ (PDF)

(386 trang)