Digitized Waveform Generator

Hello everybody,

I am a newby to C++. I have to do a time calibration on a piece of electronics. The idea is to build a standalone program for the time calibration:
i.e., take some sinus waveforms, write them to disk, read them back,
perform the time calibration, write the new calibrations values in a ascii file (as floats). I already was given a complicated piece of code that does a time calibration and I am supposed to write my own stand-alone modeled after this code. I would like to start by generating a digitized sine waveform. Can anybody give me some hints on how to do that? Here is my first attempt at it, but I am sure there is a better way to do it. Thanks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
#include<cmath>

using namespace std;

#define PI 3.14159365

int main(){

int n = 100; //number of points on the curve

	for(int i=0;i<n;i++){
		double u = sin((2*PI/n)*i);
		cout << u << endl;
	}
	return 0;
}

Raw audio takes a lot of space, so in a loop I'd read part of it it into a short buffer then output to a file as soon as the buffer was full.

You do need to decide on how many samples per second this sine wave is going to have and tone/frequency; that is an important part of your calculations.

I've followed one or two tutorials on creating raw audio data which is kind of what you're asking for. I'm thinking you're asking for calibration of an audio device with this program acting like a tuning fork kind of deal?

This is something I have in my files, it is nearly a direct copy from a stackoverflow question: http://stackoverflow.com/questions/30405354/binary-files-in-c-changing-the-content-of-raw-data-on-an-audio-file


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <fstream>
#include <cmath>
#include <limits>
#include <iostream>

int main() {

  double tone_frequency = 440;
  int samples_per_second = 44100;

  double output_duration_seconds = 5.0;

  int output_sample_count = (int)(output_duration_seconds * samples_per_second);

  std::ofstream out("signed-16-bit_mono-channel_44.1kHz-sample-rate.raw", std::ios::binary);

  for (int sample_i = 0; sample_i < output_sample_count; ++sample_i) 
  {
     double t = sample_i / (double)(samples_per_second);
     double sound_amplitude = sin(t * tone_frequency *M_PI);

    // encode amplitude as a 16-bit, signed integral value
      short sample_value = (short)(sound_amplitude * std::numeric_limits<short>::max());
      out.write((char const *)(&sample_value), sizeof sample_value);
  }
}


If you track through their process, you'll see that output_sample_count is the number of samples to achieve 5 seconds of sound, and the sound_amplitude is generated by the sin() of the iteration number times frequency times pi divided by the samples per second.

What actually goes in the file is the sound_amplitude times the maximum size of a short int.

And it is being written in binary because that's what raw audio is expected to be written into.

The reason that I multiply by pi rather than 2pi is because I generated sound like they wrote it, then played a sound file from wikipedia for 440 hz. and 2pi genearted a much higher sound, while pi worked. I didn't do any research to answer why...

Please read Chervil's summary of what can harm your speakers before you extend the time that the above code will generate sound for, this is a solid tone being generated and I feel 5 seconds might even be a bit too long;
http://www.cplusplus.com/forum/general/207487/

Fortunately it is a sine wave, so it's not the worst-case scenario, and I think Chervil was more concerned about large exterior speakers over the ones in a laptop. Just don't play it too loud and maybe reduce the playing time to less than a second while you're testing to be kinder to your speakers. (You could also multiply the sample value by .75 before writing to file to reduce audio volume of the file by 1/4)
Last edited on
Thank you for your reply, but I am confused; I don't need to generate sound at all. The sine wave is required just so that I can later use those digitized points as sample points in the calibration of the chip.

Am I missing something?
No, you're not missing much of anything, I went left when you were expecting right. It's just that sound is a sine wave as it relates to time. That's basically what you needed right?

I was trying to guess at the device and I was hoping it had to do with audio output, but outputting to audio is just one way to represent the data. Luckily you can ignore the concerns about harming your speaker (which was a worry if this data was being sent to a device as levels of power rather than being read as data)

Can you tell us what device you are trying to calibrate? I'm guessing an oscilloscope at this point, but really I have no clue. Do you know what frequency you are needing on the sine wave?


Edit:
The above code should work for you since it is raw data without compression. You will have to figure out how to get the data to this chip.
You MUST get the required frequency and samples per second for your device correct for this data to be useful.
Last edited on
And you might end up with a mismatch with the whole pi thing, I think it has to do with amplitude being hit twice per period in an audio output... It's a good thing you have example code to test against.

I'm also unsure with how you phrased your question whether you need the data in binary in the originating file, or ascii all throughout?
Last edited on
I know that a sound wave is a sinusoidal wave, I just did not see the need for suing the sound concept at first, but I see what you are saying.

I actually need to calibrate a sca (Switched Capacitor Array). I need to inject sine waveforms of 100 MHz and calibrate the chip by sampling points and estimating the zero crossings.

Thanks again for your help.
Topic archived. No new replies allowed.