Convert scientific data to tones

Help for Audacity on Windows.
Forum rules
ImageThis forum is for Audacity on Windows.
Please state which version of Windows you are using,
and the exact three-section version number of Audacity from "Help menu > About Audacity".


Audacity 1.2.x and 1.3.x are obsolete and no longer supported. If you still have those versions, please upgrade at https://www.audacityteam.org/download/.
The old forums for those versions are now closed, but you can still read the archives of the 1.2.x and 1.3.x forums.
Alosa
Posts: 8
Joined: Tue Dec 23, 2014 12:02 pm
Operating System: Please select

Convert scientific data to tones

Post by Alosa » Tue Dec 23, 2014 12:22 pm

Hello - I am totally new. I'm a scientist who collects at a lot of data. For some time, I've thought it would be interesting to convert some of these data (time series, look like wiggly curves) into musical tones to "play" the data.

A tip online suggested to try Audacity, since it can import raw text files. However, there must be lots more to it than that. As an example, I've tried to convert one data set, consisting of 107 observations, into tones by calculating the mean of the data (4.85), setting that equal to 440 Hz (the tone A, yes?), and then converting the rest of the data to ratios of that (see attached image, a graph of the data).
Data normalized to the mean as A.png
Normalized data set graph
Data normalized to the mean as A.png (8.38 KiB) Viewed 1040 times
No matter what settings I choose for importing the raw data file, what shows up is a data set that looks pretty much like the next image (filename = window000), and when I play it, it sounds buzzy.
window000.png
Screen shot of imported data set
window000.png (33.07 KiB) Viewed 1040 times


Ideally, for each of the 107 data observations, I would like to play a note that has a duration of about 1/8 to 1/4 second, so I can hear it, and that the value of 1 would be equivalent to the musical note A (for this example).

Any help is much appreciated, thanks!

steve
Site Admin
Posts: 81649
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Convert scientific data to tones

Post by steve » Tue Dec 23, 2014 1:52 pm

"Tones" are by definition "periodic" waveforms. Simply repeating a series of data will fulfil that definition, but 99.9% of the time it will sound "buzzy" because of the abrupt jump from the end of one cycle to the start of the next. That "jump" will create a complex series of harmonics right up to the Nyquist frequency (half the sample rate) and will dominate the timbre of the sound.

I also note that in your example data set (graph), the y values are all positive (approx. +0.75 to +2.25). To create a waveform that is correctly centred on the audio track you would need to find the average value of the data, then offset each sample value by that amount. Your modified data set will then be signed values, which you can normalize to fit in the range +/- 1.0 (0 dB).
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Alosa
Posts: 8
Joined: Tue Dec 23, 2014 12:02 pm
Operating System: Please select

Re: Convert scientific data to tones

Post by Alosa » Tue Dec 23, 2014 2:03 pm

Thank you, steve. I will re-normalize the data to fall between +/- 1.

However, how does one convert a single data point into a single musical note? That may be the crux of my problem.

steve
Site Admin
Posts: 81649
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Convert scientific data to tones

Post by steve » Tue Dec 23, 2014 2:14 pm

Alosa wrote:However, how does one convert a single data point into a single musical note?
Audacity is designed to be an audio recorded and editor, so that feature is not directly built in, but yes there are ways of doing it.
As you deduced, "Import Raw" is one method, but the "trick" is to ensure that the format of your data and the format of the import are the same.

"Import Raw" is expecting to see a series of binary values. It supports a number of binary formats, such as "16 bit signed integer". For example, if you have a file that contains one "signed 16 bit integer value" and import as "signed 16 bit integer", then that value will appear in the audio track as one data point (a "sample").

What format is your data?
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Alosa
Posts: 8
Joined: Tue Dec 23, 2014 12:02 pm
Operating System: Please select

Re: Convert scientific data to tones

Post by Alosa » Tue Dec 23, 2014 2:50 pm

My data are numerical. I re-normalized them to fall between +1 and -1. The first 10 points look like this:

0.090
0.112
0.153
0.223
0.288
0.358
0.417
0.472
0.505
0.535
...

This is saved as a "plain vanilla" MS-DOS .txt file, using the Windows accessory called Notepad. When looking at the Properties of the file, it's not apparent what sort of bit file it is stored as, e.g., 8-bit signed or unsigned, etc. Is there a way to determine that?

Thank you again.

steve
Site Admin
Posts: 81649
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Convert scientific data to tones

Post by steve » Tue Dec 23, 2014 3:54 pm

Alosa wrote:My data are numerical.
Your data is numerical text.

Text characters are not the same as pure (data) numerical values. For example, in ASCII encoding, the numerical value of the text character "3" is (decimal) 51 http://en.wikipedia.org/wiki/ASCII#ASCI ... code_chart

What is required is that your text values are converted into raw numerical data. That is, the text characters "0.123" are converted to a "value" of 0.123

There are several ways that can be done. Normally it would be done through programming. If you have any programming experience (almost any language) it should be fairly straightforward to convert from plain ASCII text to numerical values and output a file containing the raw binary data. That output file could then be imported into Audacity using "Import Raw".

If you don't have previous programming experience, then fortunately Audacity includes a relatively simple scripting language called "Nyquist" that allows users to write custom code for use in Audacity. The simplest way to enter Nyquist commands is via the "Nyquist Prompt" http://manual.audacityteam.org/o/man/ny ... rompt.html
More complex Nyquist code can be written as "plugins". For example, the "Sample Data Export" tool (http://manual.audacityteam.org/o/man/sa ... xport.html) is written in Nyquist. If you want to spend some time learning how to do this in Nyquist, then that is something that we can help with (could be very useful for you as a scientist ;)) You will find a list of useful reference material for Nyquist in this forum post: http://forum.audacityteam.org/viewtopic ... 38#p235338
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Gale Andrews
Quality Assurance
Posts: 41761
Joined: Fri Jul 27, 2007 12:02 am
Operating System: Windows 10

Re: Convert scientific data to tones

Post by Gale Andrews » Tue Dec 23, 2014 4:05 pm

________________________________________FOR INSTANT HELP: (Click on Link below)
* * * * * Tips * * * * * Tutorials * * * * * Quick Start Guide * * * * * Audacity Manual

Robert J. H.
Posts: 3633
Joined: Thu May 31, 2012 8:33 am
Operating System: Windows 10

Re: Convert scientific data to tones

Post by Robert J. H. » Tue Dec 23, 2014 7:12 pm

Alosa wrote:Thank you, steve. I will re-normalize the data to fall between +/- 1.

However, how does one convert a single data point into a single musical note? That may be the crux of my problem.
Keep the points positive.
They are just the frequency.
Use the nyquist prompt to produce a envelope signal from those.
(Select some audio in a mono track and go to Effects-->Nyquist Prompt)
The first part would be:

Code: Select all

(setf control-signal (snd-from-array 0 8
   #( <your pasted data without commata> )))
the signal will start at 0 (the selection start) and have a sample rate of 8 times per second
The final sine wave will therefore last for 13.375 s (with 107 points), no matter how the selected audio is.

Let's try it with random values as input:

Code: Select all

;; white noise as input data
(setf control-signal (snd-white 0 8 (/ 107 8.0)))
;; bring from -1/1 into an appropriate range
;; 200 Hz to 4200 Hz in this exampple
(setf control-signal (sum 2200 (mult 2000 control-signal)))
(abs-env (scale-db -18 (hzosc control-signal)))
You would replace the first line after the comment with the code from the very beginning to do the same with your observations.

It might be necessary to smooth the data with a sliding average.
We also resample to 2205 Hz (for a track sample-rate of 44100), as this control-sample-rate is better suited for the calculations.

Code: Select all

;; white noise as input data
(setf control-signal (snd-white 0 8.0 (/ 107 8.0)))
;; smoothing
;; 'smooth-over' observations are averaged to get a new data point
(setf smooth-over 11)
(setf total-len (truncate (snd-length control-signal ny:all)))
(setf mean 
   (sref
      (snd-avg control-signal 
       total-len total-len op-average) 0))
;; new sample rate
(setf old-sr (snd-srate control-signal))
(setf control-signal (force-srate *control-srate* control-signal))
(setf smooth-over (round (/ (* smooth-over (snd-srate control-signal)) old-sr)))
(setf control-signal 
   (sum mean 
      (snd-avg (diff control-signal mean) 
       smooth-over 1 op-average)))
;; bring from -1/1 into an appropriate range
;; 200 Hz to 4200 Hz in this exampple
(setf control-signal (sum 2200 (mult 2000 control-signal)))
(abs-env (scale-db -18 (hzosc control-signal)))
Change the first '(setf smooth-over...' to control the smoothing (1 = none)
You have also to adapt the second last line to bring your values into the right range. We calculate here with min and max instead of the mean.
However,, the variable 'mean' could also be used in this context.
Last edited by Robert J. H. on Fri Apr 24, 2015 4:45 pm, edited 3 times in total.
Reason: fixed code tag

Alosa
Posts: 8
Joined: Tue Dec 23, 2014 12:02 pm
Operating System: Please select

Re: Convert scientific data to tones

Post by Alosa » Tue Dec 23, 2014 10:05 pm

Thanks for trying to help me, folks.

So far, I'm not coming up with much.

I've tried pasting in code, as suggested, into the Nyquist prompt. I tried just pasting in the first 5 data points"

(setf control-signal (snd-from-array 0 8
(0.590 0.612 0.653 0.723 0.788)))
(setf control-signal (sum 2200 (mult 2000 control-signal)))
(abs-env (scale-db -18 (hzosc control-signal)))

Clicking on "OK" I received an error message ("error: bad function - 0.59", plus a lot more) and the admonition, "Nyquist did not return audio."

If I convert those data points to ASCII numeric, I still get the same error and admonition.

Thanks again...
(setf control-signal (snd-from-array 0 8
(048 046 053 057 048 032 048 046 054 049 050 032 048 046 054 053 051 032 048 046 055 050 051 032 048 046 055 056 056 013 010)))
(setf control-signal (sum 2200 (mult 2000 control-signal)))
(abs-env (scale-db -18 (hzosc control-signal)))

Obviously, at this point I don't understand the code very well, so don't really know what I'm doing.

Incidentally, in order to activate the Nyquist prompt, I had to have some data imported. So, I imported a file, saved by Notepad in the format "Unicode big endian" which I gather is a 16-bit format, and that file doesn't do much (see screen shot)
window002.png
window002.png (31.25 KiB) Viewed 1013 times

steve
Site Admin
Posts: 81649
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Convert scientific data to tones

Post by steve » Wed Dec 24, 2014 2:58 am

What Robert has described is an alternative approach to the question of converting data to tones.
Rather than making tones out of the actual data, he is using the data to control the pitch of a generated tone.
Alosa wrote:how does one convert a single data point into a single musical note? That may be the crux of my problem.
What Robert has described is one approach - take the value of the data point to determine the pitch.

Taking a simple example, if your data is scaled for value between, say 100 and 1000, then you could generate a tone between 100 Hz and 1000 Hz.
In Nyquist, this could be written as:

Code: Select all

(setq datapoint 440) 
(hzosc datapoint)
In the above example, the "single point of data" is "440". We then use that value to generate a tone (using the "hzosc" function) at that frequency.

Coming back to your original idea, here is a bit of code (below) that takes a series of values as a list, where the (arbitrary) values that I have chosen are:
0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0 -0.1 -0.2 -0.3 -0.4 -0.5 -0.6 -0.7 -0.8 -0.9 -1

The list of numbers is assigned as the value of "data".

To use that data to create a sound, Nyquist has a function for converting "arrays" into sounds, so I have looped through the values of "data" and put those values into an array called "data-array".

The final line is the Nyquist function "snd-from-array" which produces a sound from an array - in this case, the array contains our data (transferred from the "data" list.

Note that the sound returned by this script is very short - only 30 samples - you will need to zoom in very close to see it.

Code: Select all

(setf data 
  (list 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0 -0.1 -0.2 -0.3 -0.4 -0.5 -0.6 -0.7 -0.8 -0.9 -1))

(setf data-array (make-array (length data)))
(dotimes (i (length data))
  (setf (aref data-array i) (nth i data)))

(snd-from-array 0 *sound-srate* data-array)
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Post Reply