04-07-2008 04:59 PM
04-07-2008 05:11 PM - edited 04-07-2008 05:14 PM
04-08-2008 08:58 AM
04-08-2008 05:25 PM - edited 04-08-2008 05:26 PM
Mark M.
After experimenting with your code I came to the following conclusions. The only thing you are really interested in is the frequency content of the signal. As long as this concept is preserved you will be able to extract a smooth tone to your sound cards output.
In order to accomplish the sample rate needs to be at least twice the rate of the waveform. I would still sample a little faster than that to make sure you are guaranteed the frequency content of your tone. The link I provided talks about analog input, but the same rules apply in your application.
To handle the “spurs” you are hearing you will need to have the number of samples be a multiple of your sample rate because otherwise you will have discontinuities between each sample set. The reason is because we need to have enough samples to reconstruct your waveform. However, if the multiple number of samples you choose is too small then you will still here the same effects as before. To better explain refer to the screenshots below.
The Yellow signal is your 1kHz sine wave sampled at 4000 S/s taking 4000 samples. You can see that this doesn’t give you a nice smooth waveform, but the frequency content is still there, which will produce a nice smooth tone.
As far as the number of samples is concerned, if you perform your test with the sample rate at 48k with 1200 samples then you will still hear spurs in your sound. Even though this is a multiple of 48k, 1200 samples is not enough samples to complete the waveform.
Because I am not sampling enough points the next pass of this experiment the waveform looked like this.

You can see that the two white signals do not line up like the yellow signal which will cause spurs in your tone. If you have decided that 4096 is the optimal number of samples to get a smooth tone then just make sure your sample rate is a multiple like 40960 and you will get your desired waveform.
I hope this helps!
04-09-2008 09:17 AM
Ryan N.,
Thanks for your response. The 48000 S/s output sample rate is a requirement from the hardware team, so the number of samples/ch and #s will need to divide into that value. I'll experiment further with your input in mind. Since the samples retrieved from the lower level application are variable, it appears as if we'll need to develop a method for feeding this variable stream at a steady rate into Sound Output Write.vi.
Any thoughts on my second question about how Sound Output Write.vi handles buffer overflow? What does Sound Output Write.vi do when its buffer, as configured by the number of samples/ch input to Sound Output Configure.vi, cannot contain the samples being written to it? For example, if in the example SoundOutputTester.vi the number of samples/ch input to Sound Output Configure.vi is set to 4800 and the #s input to Sound Output Write.vi is set to 4000, what does Sound Output Write.vi do when, on the second pass, the output buffer has 1600 samples left in it (it consumes 2400 samples every 50 ms period) but the code is attempting to write another 4000 samples into the buffer, which will exceed the buffer size? Does Sound Output Write.vi wait until enough room is available in the buffer or does it overwrite (old) data in the buffer with the new samples?
Regards,
Mark M.
04-09-2008 03:32 PM - edited 04-09-2008 03:34 PM
Mark M.
I’d like to clarify a few things. When you say:
“For example, if in the example SoundOutputTester.vi the number of samples/ch input to Sound Output Configure.vi is set to 4800 and the #s input to Sound Output Write.vi is set to 4000, what does Sound Output Write.vi do when, on the second pass, the output buffer has 1600 samples left in it (it consumes 2400 samples every 50 ms period) but the code is attempting to write another 4000 samples into the buffer, which will exceed the buffer size?”
I do not see an input on “Sound Output Write.vi” that takes in the input “#’s”. I am going to assume you are speaking about the”#’s input for the Sine Wave.vi.

These parameters are strictly used in creating the 1KHz sine wave in your application. This creates a Sine Wave (digitally) with 4096 points sampled at 48 kS/s. The Sound VI’s then interprets the sine wave using its own parameters and converts it to an analog signal.
The parameters used in the picture below takes the digital
sine wave and samples it yet again then converts it to an analog signal. 
Every interation through the while loop the “Sound Output.vi”
will sample the Sine Wave we have just created and write that to the sound
card. So every pass through the while
loop we are overwriting the previous data with new samples. The sound card then interprets these new
samples and outputs them. If you create
a control instead of a constant for the frequency input on the Sine Wave.vi you
can change this frequency on the fly and hear the effects through your
speakers. This is because we are
overwriting the samples in memory with new data.

I hope this helps!
04-09-2008 05:00 PM
Ryan N.,
Thanks for the correction. You're right; my reference to #s was to the cluster element input to Sine Waveform.vi as you assumed.
Ryan N. wrote:
Every iteration through the while loop the “Sound Output.vi” will sample the Sine Wave we have just created and write that to the sound card. So every pass through the while loop we are overwriting the previous data with new samples. The sound card then interprets these new samples and outputs them. If you create a control instead of a constant for the frequency input on the Sine Wave.vi you can change this frequency on the fly and hear the effects through your speakers. This is because we are overwriting the samples in memory with new data.
04-16-2008 12:40 PM
Ryan,
I am having similar problems with the SO Write.vi. From what I can tell, the VI completely ignores the Timeout value input - I have tried setting verious timeouts that are shorter than the time it would take to play the clip, and it makes no difference in the VI execution time. According to NI's documentation, if I enter a timeout of 0, the VI should return immediately and continue to play. I thought maybe it was just adding the data to a buffer, but I only get an immediate return the first time the VI is called. The second time it takes two seconds to complete, and the remaining times it takes 1 second. What I am trying to do is stream 16-bit PCM samples via UDP to a program that will play the sound in near real-time. I had planned on just queuing the waveforms in on loop, and dequeuing them and playing them in anopther loop once I had a sufficient buffer built up. The way SO Write vi is behaving does not permit that, because it is taking too long to complete. Can you please answer Mark's (and my) question - how does the vi do its buffering? I figured it would let you call it with a 0 timeout as many times as you could until the buffer was full, at which time there would be an error. This does not seem to be how it works.
04-16-2008 02:40 PM
wired,
An NI applications engineer confirmed to me that there is indeed a bug in Sound Output Write.vi which ignores the Timeout value input. This problem is a known issue and is scheduled to be fixed in the LabVIEW 8.6 release.
Regards,
Mark M.
04-16-2008 03:10 PM