I have raw hex data from MEMS accelerometer with sampling rate of 1 sample per millisecond for a measurement duration of 2.5 seconds for each trace.The data contains first 12 bits for timestamp and then continued with 2 for each axis of acceleration X,Y and Z. I want to reduce this hex data with size around 31kb to 120 bytes for wireless data transfer. I want to achieve this through python
Related
I want to read wav files and get amplitude data in relation to time in dart to use it in dart and plot it in chart using flutter
At first i converted .mp3 and .m4a files to wav files using flutter_ffmpeg but i want to read those files and get sample rate and amplitude
And try to plot already existing file to chart with amplitude on y axis and time on x axis
My question about extracting amplitude and other wav info from .wav or .pcm files as there is no documentation i found on web.
natural audio in the wild is a continuous wobble of a curve .. think here of your ear drum or the membrane of a microphone or a drum head ... digital audio is that same curve recorded as a progression of audio samples ... typically 44100 samples are recorded per second and each sample records 16 bits of resolution of the height of this curve meaning 2^16 == 65,536 possible distinct height values for a given point on the raw audio curve ( more detail research PCM audio ) ... so a single audio sample amplitude represents the curve height at a specific point in time lets call it s1 ... this height as plotted on the raw audio curve is its amplitude for that sample
when reading a WAV format file the first 44 bytes is a header followed by the payload which contains the raw audio curve of each channel of the audio ( mono one channel, stereo 2 channels, etc ) ... typically audio is recorded using many microphones however to create an audio CD the music studio mixes down multi track audio ( possibly dozens of channels originally ) into two channels of audio ( one for left speaker one for right speaker meaning stereo that is two channels ) ... this header will tell you these critical details of what appears in the payload: sample_rate ( number of audio samples captured per second per channel ), bit_depth of each sample ( number of bits of data used to store each audio sample for a given channel ) , payload size in bytes, and number of channels ... you can write a WAV parser yourself ( takes about two pages of code ) or use a library to retrieve these data structures ... once parsed the raw audio found in the WAV file payload will give you the raw audio curve s1, s2, s3, etc for each channel ...
typically when folks need to identify the amplitude they refer to an aggregate of this curve height of many audio samples ... s1, s2, s3, ... one way to skin this cat is to calculate the Root Mean Square of a set of audio samples to generate one value of currAmplitude aggregate amplitude then slide forward in time to repeat for another set of audio sample points ... the number of samples in a given RMS calculation is up to you perhaps 1k or 2k more or less depending on your appetite for CPU consumption and resolution of this aggregated amplitude measurement
currAmplitude = square_root_of( ( s1*s1 + s2*s2 + s3*s3 + ... sn*sn ) / n ) // this is the RMS forumula
keep in mind each audio sample has its own amplitude and perhaps you can simply plot these ( s1, s2, s3, ... ) or instead repeatedly do above RMS to get a set of aggregate amplitudes which is more helpful if a general ballpark amplitude is desired instead of the instantaneous amplitude of each sample
SR04 ultrasonic distance sensor with stm32.
When I use it with STM32 I use it as bothedge with input capture. I measure the HIGH time of the Echo pin.
I thought it was a mistake
When I used Ardiuno with pulsein, I was dividing the time by 29.1 .My measurement was accurate enough, but when I divide it by 29.1 when using STM32, the measurement is very wrong. I did it by dividing by 58.2. This time I got more accurate values. What is the difference?
Thanks a lot.
It's right to divide the duration of the echo pulse by 58, as described in the datasheet as follows.
You can calculate the range through the time interval between sending trigger signal and
receiving echo signal. Formula: uS / 58 = centimeters or uS / 148 =inch; or: the
range = high level time * velocity (340M/S) / 2;
I tried to find an Arduino code which divides pulse duration with 29.1 or 29, I couldn't find it. Some posts computes the range by range=(duration/2)/29.1. I guess you've missed dividing duration by two. Double check your Arduino code, or post it if you want to be assured.
I found out that when using high sample rates, movesense sends multiple values in one package.
Movesense - Accelerometer Sampling Rate change fails
Is it possible to get accurate timestamps for all received values when using high sample rate (e.g. 104Hz)?
The reason movesense sensor sends more than one sample per timestamp is to save bandwidth when communicating over BLE and to save memory when same packets are stored in the internal data memory (EEPROM). Since the packets come at frequent intervals and the sample amount does not change, you can easily calculate the intermediate timestamps for individual samples.
The /Meas/Acc spec (acc.yaml) states:
Timestamp:
description: Local timestamp of first measurement.
so the 1st sample (i==0) timestamp is given. If the sample rate is 104 Hz the difference in time between samples is 1000/104 ms => ~ 9.6ms. Therefore the timestamp of the later samples [i=1..n] in the array can be calculated by:
timestamp_i = timestamp_0 + i * 9.6ms
I'm trying to do target recognition using the target acoustic signal. I tested my code in matlab, however, i'm trying to simulate that in C to test it in tinyOS using sensor simulator.
In matlab, i used wav records (16 bits per sample, 44.1 sample rate), so for example, i have a record for a certain object, lets say cat sound which of 0:01 duration, in matlab that will give me a total of 36864 samples of type int16 ,and size 73728 bytes.
In sensor, if i have [Mica2 sensor: 10 bits ADC (but i'll use 8 bits ADC), 8 MHz microprocessor, and 4 Kb RAM. This means that when i detect an object, i'll fill the buffer with 4000 samples of type uint8_t (if i used 8 KHz sample rate and 8 bits ADC).
So, my question is that:
In matlab i used a large number of samples to represent the target audio signal(36864 samples), but in the sensor i'm limited to only 4000 samples, would that be enough to record the whole target sound?
Thank you very much, highly appreciate your advice
I have been controlling Arduino from Matlab using ArduinoIO-Matlab interface. My current setup is I have 3 EMG Muscle Sensors (from Advancer Technologies) are connected to the Arduino at analog pin 1,2, and 3. Arduino is connected to Matlab. I am trying to collect data from these three pins simultaneously and store them in an matrix size 1000x3. My issue is the rate at which Matlab is sampling from the analog pin. It takes about 25 seconds to collect 1000 readings from the 3 pins simultaneously. I know arduino itself samples at a higher rate. Below is my code. How do I alter this to get a sampling rate of about like 1000 samples in 10 seconds ?
ar = arduino('COM3');
ax = zeros(1000,3);
for ai = 1:1000
ax(ai,:) = [ar.analogRead(1) ar.analogRead(2) ar.analogRead(3)];
end
delete(ar);
This is the time taken by the above code (profile viewer):
time calls line
< 0.01 1 3 ax = zeros(1000,3);
4
< 0.01 1 5 for ai = 1:1000
25.07 1000 6 ax(ai,:) = [ar.analogRead(1) ar.analogRead(2) ar.analogRead(3)];
1000 7 end
8
1.24 1 9 delete(ar);
Please let me know if there is something else that I need to clarify.
Thanks :Denter code here
You need to modify the arduino c++ code (.pde file).
In this code you should sample the signal as you prefer (1000 for example) and then transfer the sampled data to matlab using serial.writeln() method.
This will give you a sampling rate of ~3KHz (depending on alot of factors)...
The following very probably explains the result that you are seeing and why you need to do something like what Muhammad's answer suggests. While this reason was implied by his answer it was not spelt out so that others can avoid the 'trap'.
I do not have access to the underlying code and systems needed to check this answer with certainty. This answer is based on "typical methods" and has a modest chance of being sheer poppycock [tm], but the exact fit between observation and standard methods suggests this is what is happening. A very little delving by someone with the requisite system to hand will demonstrate if this is correct.
When data is sent one data sample at a time you incur a per-sample overhead significantly in excess of the time taken to just transfer the raw data.
You say it takes 25 seconds to transfer 3000 samples.
The time per sample = 25/3000 = 8.333 ms per sample.
Assume a 9600 baud data transfer rate.
The default communications speed is liable to but 9600 baud. This can be checked but the result suggests that this may be correct and making slightly different assumptions provides an equally good explanation.
Serial coms usually uses N81 format = 1 start bit, 8 data bits, 1 stop bit per 8 bit byte.
So 1 bit takes 1/9600 s
and 10 bits take 10/9600 = 1.042 mS
And sample time / byte time
= 8.333 / 1.042 = 7.997 word times.
In fact if you do the calculations without rounding or truncation, ie
25 / 3000 x 9600/10 = 8.000.... .
ie your transfer is taking EXACTLY 8 x 9600 baud word times per sample.
Equally, this is exactly 4 x 4800 baud or 2 x 2400 baud transfer times.
I have not examined the format used but imagine that to work with the PC monitor program the basic serial routine may use
2 x data bytes + CR + LF = 4 bytes.
That assumes a 16 bit variable sent as 2 x 8 bit binary words.
More likely = either
- 16 bits sent as 4 x ASCII characters or
- 24 bits sent as 6 x ASCII characters.
In the absence of suitably deep delving, the use of 6 ASCII words and a CR + LF at 9600 baud provides such a good fit using typical parameters that Occam probably opines that this is the best starting point. Regardless of whether the total requirement is 8 or 4 or 2 bytes, the somewhat serendipitous exact match between your observed data rate and standard baud rates suggests that this provides the basic reason for what you see.
Looking at the code will rapidly show what baud rate, data length and packing is used.