04-04-2012 03:44 AM
Hi,
Little problem that I'm struggling to solve in Measurement Studio.
I have an audio waveform that I am sampling at 44.1KHz for 10 seconds. I then want to display this on a waveform graph.
That bit is easy enough, but by default the XAxis scales to have a range of 0 to 441,000 to display all the samples, what I want is to change this so that instead the xAxis has the scale 0 to 10.
I have played around with different chart types but cannot work out how to do this.
Any help gratefully received.
Thanks,
Dave
04-04-2012 09:09 AM
Hello there,
The properties you should be playing around with are,
Axis.Range --> Range on the xaxis
Axis.Mode --> This calculates range depending on the plotted data
WaveformPlot.DefaultStart --> This overrides the range minimum value on the graph
WaveformPlot.DefaultPlotIncrement --> This overrides the increment with which the data is plotted on the graph
WaveformPlot.HistoryCapacity --> This is the number of points the graph actually displays. Increase it to the number of points you want to see on the graph.
One nice trick to make sure to ensure that the data plotted correctly is to zoom in and out or do panning, [See the WaveformGraph.InteractionMode property for zoom/pan options].
Hope this helps!
Regards
Vijet Patankar
04-05-2012 07:40 AM
Hi Vijet,
Thanks for the reply - unfortunately it doesn't really solve my problem as I am aware of all those properties and playing around with all of them doesn't seem to give me what I want i.e. I want to display every sample, but then have those samples mapped to the time domain on the X-Axis - there must be a way of doing it.
I'll keep plugging away and post back if I figure it out.
Thanks,
Dave
04-05-2012 10:32 AM - edited 04-05-2012 10:38 AM
Hi there,
I understand what the problem is, earlier I had missed the point that you were trying to plot a waveform, and not a double[]. Sorry about that!
The AnalogWaveform is meant to provide the timing information to the Graph while plotting. And hence it doesn't take the WaveformPlot.DefaultStart, and WaveformPlot.DefaultIncrement properties into account.
WorkAround1 (Recommended): If you don't care about the timing information that the AnalogWaveform provides, then I would suggest that you get the the double[] from the waveform, and then use the WaveformGraph.PlotY(). When the data is passed as double[] the DefaultStart and DefaultIncrement properties will effect how the data is dislpayed automatically. See the following code snippet.
// Set appropriate increment. // in your case it would be (max-min)/numberOfSamples; waveformPlot1.DefaultIncrement = 0.1; // set it here
waveformPlot1.DefaultStart = minimum;
double[] data = analogWaveform.GetRawData(); waveformGraph1.PlotY(data);
WorkAround2 (Not so recommended):
If you don't want to convert the waveform into a double array, and still want to get the graph to display range from say (0, 10), you will have to handle different things by some code!
One way to trick the graph is to modify the label strings, by writing a custom FormatString. I have written some code below!
Note: This method is much much more powerful. If you just want to display the data, and don't want to interact (EditRange intaraction) with the graph in any way, this is the method I would recommed. But if you want ot interact with the graph or you are using the XAxis range in some calculations you must be very careful. Because what is displayed is not the actual value of the range, since what is displayed is completely in control of the custom FormatString.
public partial class Form2 : Form
{
int numberOfDataPoints = 44100;
Random r = new Random();
public Form2()
{
InitializeComponent();
double minimum = 0;
double maximum = 10;
double increment = (maximum - minimum) / numberOfDataPoints;
//double increment = 1;
// xAxis1.Range = new NationalInstruments.UI.Range(minimum, maximum); //set range here
// waveformPlot1.DefaultIncrement = increment;
xAxis1.MajorDivisions.LabelFormat = new MyFormatString(minimum, maximum);
AnalogWaveform<double> aw = new AnalogWaveform<double>(numberOfDataPoints);
waveformGraph1.PlotWaveform(GetAWData());
}
// method to generate a double[] sample data
private double[] GetData()
{
double[] d = new double[numberOfDataPoints];
for (int i = 0; i < numberOfDataPoints; i++ )
{
d[i] = 10 * Math.Sin(0.0001 * i) + 0.5 * r.NextDouble();
}
return d; // some sample data here.
}
// method to generate a AnalogWaveform<double> data
private AnalogWaveform<double> GetAWData()
{
AnalogWaveform<double> aw = new AnalogWaveform<double>(numberOfDataPoints);
for (int i = 0; i < numberOfDataPoints; i++)
{
aw.Samples[i].Value = 10 * Math.Sin(0.0001 * i) + 0.5 * r.NextDouble(); // some math calculation!
}
return aw; // some sample data here in the waveform.
}
}
// my custom FromatString to adjust the values that is displayed as labels on the x-axis.
public class MyFormatString : FormatString
{
double minimum;
double maximum;
double niceNumber = 50000;
public MyFormatString(double min, double max)
{
minimum = min;
maximum = max;
}
public override string FormatDouble(double value)
{
return base.FormatDouble(ModifyValue(value));
// play around this method.
// return "I LIKE THIS API";
}
private double ModifyValue(double value)
{
return (maximum - minimum) * value / (niceNumber);
}
}
// I had used the same piece of code to generate and plot double[] and AnalogWaveform<double> data,
// just by modifying code here and there.
Here are some screenshots I got!
Hope this helps!!
Regards,
Vijet Patankar,
National Instruments
04-11-2012 05:52 AM
Hi Vijet,
Thankyou very much for your detailed reply - I think this is what I'm looking for - haven't had a chance to try it out yet, but will get back to you when I have.
Thanks,
Dave