Understanding an wav file exported from a daw - fft

I have generated a tone from Audacity at 440Hz with Amplitude as 1 for 1 sec like this:
I understand that this is going to create 440 peaks in 1 sec with Amplitude as 1.
Here i see that its a 32 bit file with 44100Hz is the sample rate which means there are 44100 samples per sec. The Amplitude is 1 which is as expected because that is what i chose.
What i dont understand is, what is the unit of this Amplitude? When right-clicked it shows linear(-1 to +1)
There is an option to select dB it shows (0 to -60 to 0) which i dont understand how is this converted!
now when i use this wav file in the python scipy to read the wav and get values of time and amplitude
How to match or get the relation between what i generated vs what i see when i read a wav file?
The peak is amplitude is 32767.987724003342 Frequency 439.99002267573695
The code i have used in python is
wavFileName ="440Hz.wav"
sample_rate, sample_data = wavfile.read(wavFileName)
print ("Sample Rate or Sampling Frequency is", sample_rate," Hz")
l_audio = len(sample_data.shape)
print ("Channels", l_audio,"Audio data shape",sample_data.shape,"l_audio",l_audio)
if l_audio == 2:
sample_data = sample_data.sum(axis=1) / 2
N = sample_data.shape[0]
length = N / sample_rate
print ("Duration of audio wav file in secs", length,"Number of Samples chosen",sample_data.shape[0])
time =np.linspace(0, length, sample_data.shape[0])
sampling_interval=time[1]-time[0]

notice in audacity when you created the one second of audio with aplitude choice of 1.0 right before saving file it says signed 16 bit integer so amplitude from -1 to +1 means the WAV file in PCM format stores your raw audio by varying signed integers from its max negative to its max positive which since 2^16 is 65536 then signed 16 bit int range is -32768 to 32767 in other words from -2^15 to ( +2^15 - 1 ) ... to better plot I suggest you choose a shorter time period much smaller than one second lets say 0.1 seconds ... once your OK with that then boost it back to using a full one second which is hard to visualize on a plot due to 44100 samples
import os
import scipy.io
import scipy.io.wavfile
import numpy as np
import matplotlib.pyplot as plt
myAudioFilename = '/home/olof/sine_wave_440_Hz.wav'
samplerate, audio_buffer = scipy.io.wavfile.read(myAudioFilename)
duration = len(audio_buffer)/samplerate
time = np.arange(0,duration,1/samplerate) #time vector
plt.plot(time,audio_buffer)
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title(myAudioFilename)
plt.show()
here is 0.1 seconds of 440 Hz using signed 16 bit notice the Y axis of Amplitude range matches above mentioned min to max signed integer value range

Related

Python 1Hz measurement temperature

I want to create csv file in python ,storing data from the sensor plus time stamp of the reading .But sensor measures fast and I need exactly 1 measurment from the sensor exactly after 1 sec.For example sensor value is 20 at time 12:34:15.and i need value exactly at 12:34:16 .I do not have to use time.sleep because it creates delay more than second and will affect the log file if i have to take readings more than hundred.
Consumer PCs do not have real-time operating systems and there is no guarantee that a particular process will execute at least once per second and certainly no guarantee that it will be executing at each 1 second interval. If you want precision timed measurements with Python, you should look as Micropython executing on a microcontroller board. It may be able to do what you want. Python on a Raspberry Pi board might also work better than a PC.
On a regular PC, I would start with something using perf_counter.
from time import perf_counter as timer
from somewhere import sensor, save # read temperature, save value
t0 = t1 = timer()
delta = .99999 # adjust by experiment to average 1 sec reading intervals
while True:
while t1 - t0 < delta:
t1 = timer()
value = sensor())
save(value)
t0 = t1

Plotting data using Gnuplot

I have a csv file includes two column
no. of packet size
1 60
2 70
3 400
4 700
.
.
.
1000000 60
where the first column is
the number of packet
, and the second column is
the size of packet in bytes.
the total number of packets in the csv file is one million. I need to plot histogram for this data file by:
xrange = [0, 5 , 10 , 15 ]
which denotes the packet size in bytes. The range [0] denotes the packet size less than 100 bytes, and [5] denotes the packet bytes less than 500 bytes and so on.
yrange = [ 10, 100, 10000, 100000000],
which denots the number of packets
Any help will be highly appreciated.
Don't quite remember exactly how this works, but the commands given in my Gnuplot in Action book for creating a histogram are
bin(x,s) = s*int(x/s)
plot "data-file" using (bin(1,0.1)):(1./(0.1*300)) smooth frequency with boxes
I believe smooth frequency is the command that's important to you, and you need to figure out what the using argument should be (possibly with a different function used).
This should do the job:
# binning function for arbitrary ranges, change as needed
bin(x) = x<100 ? 0 : x<500 ? 5 : x<2500 ? 10 : 15
# every occurence is counted as (1)
plot datafile using (bin($2)):(1) smooth freq with boxes
Im not really sure what you mean by "yrange [10 100 1000 ...]", do you want a logscaled ordinate?
Then just
set xrange [1:1e6]
set logscale y
before plotting.

PSNR calculation in H.264 packet loss

I'm streaming H.264(libx264) videos using RTP. I would like to compare the different error resiliency methods in h.264. In some research papers, psnr was used to compare them. So I would like to know how to calculate the psnr of the h.264 video during streaming.
To calculate PSNR, you must compare two frames, so first step is to make sure you have a copy of the source video. Next, you must be able to match the frames 1:1. so if a frame is droped, you need to compare the source frame to the previous streamed frame. This may be difficult if the timestamps do not match (They may be modified by the RTP server). Next decode each frame into its YUV channels. the PSNR of the channels needs to be calculated independently. You can average the three PSNR values at the end, but this puts too much weight on the U,V channels. I recommend just using the Y channel, as it is most important. And since you are measuring packet loss, the values will be strongly correlated anyway.
Next calculate your mean squared error like so:
int64_t mse = 0;
for(int x = 0 ; x < frame.width ; ++x ) {
for(int y = 0 ; y < frame.height ; ++y ) {
mse += pow( source_frame[x][y] - streamed_frame[x][y], 2 );
}}
mse *= 1.0/(frame.width*frame.height);
And finally:
/* use 219 instead of 255 if you know your colorspace is BT.709 */
double psnr = 20 * log10( 255 ) - 10 * log10( mse );
You can average the per frame PSNRs together to get a full stream PSNR.

Multiple regression with lagged time series using libsvm

I'm trying to develop a forecaster for electric consumption. So I want to perform a regression using daily data for an entire year. My dataset has several features. Googling I've found that my problem is a Multiple regression problem (Correct me please if I am mistaken).
What I want to do is train a svm for regression with several independent variables and one dependent variable with n lagged days. Here's a sample of my independent variables, I actually have around 10. (We used PCA to determine which variables had some correlation to our problem)
Day Indep1 Indep2 Indep3
1 1.53 2.33 3.81
2 1.71 2.36 3.76
3 1.83 2.81 3.64
... ... ... ...
363 1.5 2.65 3.25
364 1.46 2.46 3.27
365 1.61 2.72 3.13
And the independendant variable 1 is actually my dependant variable in the future. So for example, with a p=2 (lagged days) I would expect my svm to train with the first 2 time series of all three independant variables.
Indep1 Indep2 Indep3
1.53 2.33 3.81
1.71 2.36 3.76
And the output value of the dependent variable would be "1.83" (Indep variable 1 on time 3).
My main problem is that I don't know how to train properly. What I was doing is just putting all features-p in an array for my "x" variables and for my "y" variables I'm just putting my independent variable on p+1 in case I want to predict next day's power consumption.
Example of training.
x with p = 2 and 3 independent variables y for next day
[1.53, 2.33, 3.81, 1.71, 2.36, 3.76] [1.83]
I tried with x being a two dimensional array but when you combine it for several days it becomes a 3d array and libsvm says it can't be.
Perhaps I should change from libsvm to another tool or maybe it's just that I'm training incorrectly.
Thanks for your help,
Aldo.
Let me answer with the python / numpy notation.
Assume the original time series data matrix with columns (Indep1, Indep2, Indep3, ...) is a numpy array data with shape (n_samples, n_variables). Let's generate it randomly for this example:
>>> import numpy as np
>>> n_samples = 100, n_variables = 5
>>> data = np.random.randn(n_samples, n_variables)
>>> data.shape
(100, 5)
If you want to use a window size of 2 time-steps, then the training set can be built as follows:
>>> targets = data[2:, 0] # shape is (n_samples - 2,)
>>> targets.shape
(98,)
>>> features = np.hstack([data[0:-2, :], data[1:-1, :]]) # shape is (n_samples - 2, n_variables * 2)
>>> features.shape
(98, 10)
Now you have your 2D input array + 1D targes that you can feed to libsvm or scikit-learn.
Edit: it might very well be the case that extracting more time-series oriented features such as moving average, moving min, moving max, moving differences (time based derivatives of the signal) or STFT might help your SVM mode make better predictions.

Unit Conversions! Ghz - ns - MHz - cycles

I am preparing for a units quiz and there are two kinds of conversions that have me stumped.
Type one:
What is length (in ns) of one cycle on a XXX computer?
- In this case, XXX can be some MHz or Ghz, randomly. I am having trouble converting the cyles times. Example:
What is length (in ns) of one cycle on a 50 MegaHertz (MHz) computer?
The second type of conversion I have trouble with:
If the average instruction on a XXX computer requires ZZ cycles, how long (in ns) does the average instruction take to execute?
- Like the previous case, the XXX will either be some MHz or Ghz. For example:
If the average instruction on a 2.0 GigaHertz (GHz) computer requires 2.0 cycles, how long (in ns) does the average instruction take to execute?
I don't understand what I am doing wrong in these conversions but I keep getting them wrong. Any help would be great!
I hope to have my math correct, I'll give it a try.
One Hertz is defined as one cycle per second, so a 1 Hz computer has a 10^9 ns cycle length (because nano is 10^-9).
50 Mega = 50 * 10^6, so 50MHz yields a (10^9 ns / (50 * 10^6)) = 20 ns cycle length.
2 Giga = 2 * 10^9, so 2GHz yields a (10^9 ns / (2 * 10^9)) = 0.5 ns cycle length. Two cycles here take 1 ns.
The unit for frequency is Hz which is the same as 1/s or s^-1. To convert from frequency to length (really time) you have to compute the reciprocal value: length = 1/frequency.
What is length (in ns) of one cycle on a 50 MegaHertz (MHz) computer?
1/(50*10^6 Hz) = 2*10^-8 s = 20*10^-9 s = 20 ns
If the average instruction on a 2.0 GigaHertz (GHz) computer requires 2.0 cycles, how long (in ns) does the average instruction take to execute?
One cycle: 1/(2*10^9 Hz) = 0.5*10^-9 s = 0.5 ns
Two cycles: 1 ns