Sine LUT VHDL wont simulate below 800 hz - midi

I made a sine LUT for VHDL, using 256 elements.
Im using MIDI input, so values range 8.17Hz (note #0) to 12543.85z (note #127).
I have another LUT that calculates how many value must be sent to my 48 kHz codec in order to play the sound (the 8.17Hz frequency will need 48000/8.17 = 5870 values).
I have another LUT that contains an index factor, which is 256/num_Values, which is used to call values from the sin table (ex: 100*256/5870 = 4 (with integer rounding)).
I send this index factor to another VHDL file, which is used to calculate which value should be sent back. (ex: index = index_factor*step_counter)
When I get this index, I divide it by 100, and call sineLUT[index] to get the value that I need to generate a sine wave at the desired frequency.
The problem is, only the last 51 notes seem to work for me, and I do not know why. It seems to get stuck on a constant note at anything below that frequency (<650 hz) , and just decrease in volume every time I try to lower the note.
If you need parts of my code, let me know.

Just guessing, I suspect your step_counter isn't going through enough cycles, so your index (into the sine lut) doesn't go through a full 360 degrees for the lower frequencies.
For anything more helpful, you'll probably have to post code.
As an aside, why aren't you using something more like a conventional DDS? Analog Devices has a nice write-up on the basics: DDS Tutorial

Related

How to calculate amplitude from Uint8List Stream?

I am using flutter_sound package to record audio from mic. It provides data in stream of Uint8List. So how can I calculate amplitude from it. I have found many answers in other language but I was having hard time interpreting it into dart.
for reference,
Reading in a WAV file and calculating RMS
Detect silence when recording
how can i translate byte[] buffer to amplitude level
if anyone can interpret this into dart so that I can calculate amplitude
I was not able to calculate amplitude from Uint8List so what I did was write my own native code to directly get amplitude from native you can check out my package here. (I am busy somewhere else so I'm not right now maintaining it but will surely do in future.)
And I don't know but flutter_sound provides maybe false values or I was calculating wrong but I was always getting nearly the same values even when the volume is high or low.
Now, if you want to calculate amplitude then it should be based on values you're getting,
If you are getting values between -32768 and 32767 then from my understanding what you do is define a timeframe and for that timeframe calculate the RMS of it.
The RMS is your amplitude.
Now, as #richard said in the comment to normalize with 32768 if you have Int16List. But I guess that is doing too much work. We get a stream of Int16List so data may be coming every 200ms or whatever it is set at the plugin level. Calculating RMS for each Int16List is a very intensive task so I don't think it's good to do it on the flutter side. Get data from native directly and just pass it flutter using platform channels.
Now, if you want to try then calculate the RMS of an Int16List then for a defined timeframe take the mean of those values.
I may well be wrong but hope this helps or guides you in the right direction. If anyone finds a better way please post it here.

Efficient way of using ssim() function in Matlab for comparing image structures (or any other alternative)

I'm given the task of reordering a number of randomly placed video frames into the right order. I've managed to do this by using each frame as a reference once, and find the the two closest frames in terms of structure for that reference frame..presumably that these two closest frames would be the ones behind and after that frame in the video. After finding the two closest frames for each video frame, I would then compute a possible path.
My problem however is when it comes to performance, particularly when scoring. It's very inefficient unfortunately,and run time alone for 72 frames (320x240) is approx 80 seconds on just the scoring. I'm not too familiar with Matlab (or any similar language) but this is what I am doing for scoring right now:
for i =1: n_images,
current_image = Images{1,i};
%obtain score pairs image similarity
for j = 1:n_images,
if i ~= j,
scores(1,j) = ssim(Images{1,j}, current_image);
end
end
[svalues, index] = sort(scores,'descend');
Closest(1,i) = index(1,1);
Closest(2,i) = index(1,2);
%Closest consists of a 2 x n_images matrix, where for each frame index, there are two
%column values, which are the indexes of the closest frames.
end
Could anyone give me some pointers for optimizations, or else suggestions for a better way of scoring?
Edit: Images are normalized and converted to grayscale
Edit #2: I've tried using threads by adding parfor in the scoring loop, which improved performance by around 50%, however the problem is that I need to create an executable, and i'm not sure I'd achieve the same performance..
Never mind, here I'm going through all image pairs, twice (switched parameters), which is not needed.So it is possible to reduce the speed by n-1/2.
If you want efficiency over accuracy (which in my case, it is), finding the score from the correlation of histograms is one possible way.
It took me 55 seconds to process 72 frames with ssim(), while only 1.2 seconds with difference of histograms.

What is AVAudioPlayer's averagePowerForChannel averaging?

The docs for AVAudioPlayer say averagePowerForChannel: "Returns the average power for a given channel, in decibels, for the sound being played." But it doesn't say what "average" means, or how/if that average is weighted. I'm particularly interested in what the range of samples is, specifically the time interval and whether it goes forward into the future at all.
AVAudioRecorder: peak and average power says that the formula used to calculate power is RMS (root mean square) over a number of samples, but also doesn't say how many samples are used.
Optional bonus question: if I want to calculate what the average power will be in, say, 100 msec -- enough time for an animation to begin now and reach an appropriate level soon -- what frameworks should I be looking into? Confusion with meters in AVAudioRecorder says I can get ahold of the raw sample data with AudioQueue or RemoteIO, and then I can use something like this: Android version of AVAudioPlayer's averagePowerForChannel -- but I haven't found sample code (pardon the pun).

How to find out carrier signal strength programmatically

Here is the code that I have used to find out carrier signal strength:
int getSignalStrength()
{
void *libHandle = dlopen("/System/Library/Frameworks/CoreTelephony.framework/CoreTelephony", RTLD_LAZY);
int (*CTGetSignalStrength)();
CTGetSignalStrength = dlsym(libHandle, "CTGetSignalStrength");
if( CTGetSignalStrength == NULL) NSLog(#"Could not find CTGetSignalStrength");
int result = CTGetSignalStrength();
dlclose(libHandle);
return result;
}
It is giving me values between 60 to 100, but when I test the signal strength in device by calling to this *3001#12345#* number it showed me as -65. Below I have attached the screenshot. Is the value coming from getSignalStrength() accurate? Then why is it returning positive values always?
getSignalStrength() is showing negated dB attenuation, e.g. -(-60) == 60. The call in is displaying it more conventionally as a measurement less than zero. Yes, these kinds of variations are typical. Even in strictly controlled conditions you can get +/- 20 decibels. One way you can fix it is to take a series of measurements over time, say every second, and keep a running list of the last 10 or so measurements. Then report the mean or median or some other statistic. In my experience this cuts down the variation a lot. You can also do standard deviation to provide a measure of reliability.
My observation on CTGetSignalStrength() in CoreTelephony is that, it returns the
RSSI(Received Signal Strength Indication) value of carrier's signal strength. My experiments with this returns values between the range 0 - 100, which I believe is the "percent signal strength" of the carrier according to this .
Also iOS does not measure signal strength in a linear manner according to this
I also noticed that, even when we have 5 bars in status bar, RSSI value may not be 100.
getSignalStrength() provides the result in negative scale. The difference can be controlled using high pass filter.
You should gather the results of last 10 observations. At the time of adding new observation, take the average of last 10 observations. Multiply it by 0.1. Take the current reading and multiply it by 0.9. Add both. If total observations are greater than 10, remove the oldest observation for next calculation.
It will make your result more reliable and you can also handle sudden changes in the signal strength effectively.
I would recommend reading up on decibel measure. The following link should help.
How to Read Signal Strength
As for many signals getSignalStrength() should be used cojointly with a high-pass filter algorithm.
Also make sure to have an average measurement over some time (10-15 successive measurements).
And it's normal that it gives negative result, dB signals for telephony are like that ;-)

Measuring Frequency of Square wave in MATLAB using USB 1024HLS

I'm trying to measure the frequency of a square wave which is read through a USB 1024 HLS Daq module through MATLAB. What I've done is create a loop which reads 100 values from the digitial input and that gives me vector of 0's and 1's. There is also a timer in this loop which measures the duration for which the loop runs.
After getting the vector, I then count the number of 1's and then use frequency = num_transitions/time to give me the frequency. However, this doesn't seem to work well :( I keep getting different frequencies for different number of iterations of the loop. Any suggestions?
I would suggest trying the following code:
vec = ...(the 100-element vector of digital values)...
dur = ...(the time required to collect the above vector)...
edges = find(diff(vec)); % Finds the indices of transitions between 0 and 1
period = 2*mean(diff(edges)); % Finds the mean period, in number of samples
frequency = 100/(dur*period);
First, the code finds the indices of the transitions from 0 to 1 or 1 to 0. Next, the differences between these indices are computed and averaged, giving the average duration (in number of samples) for the lengths of zeroes and ones. Multiplying this number by two then gives the average period (in number of samples) of the square wave. This number is then multiplied by dur/100 to get the period in whatever the time units of dur are (i.e. seconds, milliseconds, etc.). Taking the reciprocal then gives the average frequency.
One additional caveat: in order to get a good estimate of the frequency, you might have to make sure the 100 samples you collect contain at least a few repeated periods.
Functions of interest used above: DIFF, FIND, MEAN
First of all, you have to make sure that your 100 samples contain at least one full period of the signal, otherwise you'll get false results. You need a good compromise of sample rate (i.e. the more samples per period you have the better the measurement is) and and number of samples.
To be really precise, you should either have a timestamp associated with every measurement (as you usually can't be sure that you get equidistant time spacing in the for loop) or perhaps it's possible to switch your USB module in some "running" mode which doesn't only get one sample at a time but a complete waveform with fixed samplerate.
Concerning the calculation of the frequency, gnovice already pointed out the right way. If you have individual timestamps (in seconds), the following changes are necessary:
tst = ...(the timestamps associated with every sample)...
period = 2*mean(diff(tst(edges)));
frequency = 1/period;
I can't figure out the problem, but if the boolean vector were v then,
frequency = sum(v)/time_to_give_me_the_frequency
Based on your description, it doesn't sound like a problem with the software, UNLESS you are using the Windows system timer, which is notoriously inaccurate (it is only accurate to about 15 milliseconds).
There are high-resolution timers available in Windows, but I don't know how to use them in Matlab. If you have access to the .NET framework, the Stopwatch class has 1 microsecond accuracy (or better), as does the QueryPerformanceCounter API in Win32.
Other than that, you might have some jitter. There could be something in your signal chain that is causing false triggers, etc.
UPDATE: The following CodeProject article should solve the timing problem, if there is one. You should check the Matlab documentation of your version of Matlab to see if it has a native high-resolution timer. Otherwise, you can use this:
C++/Mex wrapper adds microsecond resolution timer to Matlab under WinXP
http://www.codeproject.com/KB/cpp/Matlab_Microsecond_Timer.aspx
mersenne31:
Thanks everyone for your responses. I have tried the solutions that gnovice and groovingandi mentioned and I'm sure they will work as soon as the timing issue is solved.
The code I've used is shown below:
for i=1:100 tic; value = getvalue(portCH); vector(i) = value(1); tst(i) = toc; % gets an individual time sample end
% to get the total time I put total_time = toc after the for loop
totaltime = sum(tst); edges = find(diff(vec)); % Finds the indices of transitions between 0 and 1 period = 2*mean(diff(edges)); % Finds the mean period, in number of samples frequency = 100/(totaltime*period);
The problem is that measuring the time for one sample doesn't really help because it is nearly the same for all samples. What is needed is, as groovingandi mentioned, some "running" mode which reads 100 samples for 3 seconds.
So something like for(3 seconds) and then we do the data capture. But I can't find anything like this. Is there any function in MATLAB that could do this?
This won't answer your question, but it's what I thought of after reading you question. square waves have infinite frequency. The FFT of a square wave it sin(x)/x, which goes from -inf to +inf.
Also try counting only the rising edges in matlab. You can quantize the signal to just +1 and 0, and then only increment the count when you see [0 1] slice of your vector.
OR
You can quantize, decimate, then just sum. This will only work if the each square pulse is the same length and your sampling frequency is constant. I think this one would be harder to do.