Desktop Recorder

Discussion in 'Additional Libraries' started by Pachuquin, May 17, 2009.

  1. klaus

    klaus Expert Licensed User

    Perhaps:
    ToAmplitudePhase
    ToAmplitude
    ToPhase

    Best regads.
     
  2. agraham

    agraham Expert Licensed User

    That would waste some time. After you DIM an array .NET fills it with zeros so on a new array it is only necessary to fill in the Real values.
    I've already suggested that in the post above but I need a better name or to rename some existing methods, any suggestions?
    I'll leave that to someone who is more confident with the maths than I am.
    I'll wait till you have done that
     
  3. agraham

    agraham Expert Licensed User

    I've already got ToAmplitude and ToPhase. How about GetAmplitute and GetPhase or shall I do a complete rename of the existing methods? What did you intend ToAmplitudePhase to do?
     
  4. redbird

    redbird Member Licensed User

    Allow me to summarize what I understood from these detailled posts, related to my example:

    Filling the array only with 4096 real bytes from my sound sample will work mathematically, giving 100% correct results, but could take more time. Is that correct to assume ?

    I understand the .NET mechanism that fills an array at declaration time with zeros, and see the benefits. I also understand now how the fft library is able to handle an input with only real values anyway, as it seems to generate the zero (imag) values itself internally.

    BTW, I tried both methods, and besides the probable speed difference, the results looked good every time.

    In my real life app, I only look for frequencies between 33 and 166 Hertz, being 1000 to 5000 RPM "headspeed" for a 2 bladed R/C helicopter. Simply 33*60/2 and 166*60/2. And until now, in this small, lower part of the spektrum, i only encountered this 1 frequency, together with 1 harmonic with exactly half the frequency, but less than half in amplitude. So my code can easily make the difference between those two, leaving no room for error.
    I visualised this by means of a graph indeed, to be able to control this.
    The user is of course responsible of making a recording with no other sound sources present. All the other frequencies generated by a R/C heli are much higher, being the 2-3 times faster turning tail blades, or the even higher RPMs of the electric motor, and all harmonics I found until now.
     
    Last edited: Mar 16, 2010
  5. klaus

    klaus Expert Licensed User

    Hi Andrew,

    I'm coming back on my suggestion 1) transfering in the Fft.Transform function only the real data.

    I had a look at your library with SharpDevelop and saw that the real and imag samples could relatively easy be treated separately.
    - real data in the input, half the length than before
    - so, n = data.length and no more n = data.length/2
    - generate an internal array for the imag data samples
    - everywhere you have data(i) or data(j) is the real input data array realdata(i)
    - everywhere you have data(i+1) or data(j+1) is the internal imag data array imagdata(i)
    - for the return copy the first half of the imag samples into the second half of the data array.

    Just to illustrate
    Code:
    [SIZE=2]data[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]j[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] = [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]data[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] - [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]data[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]j [/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]+ [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#00008b][SIZE=2][COLOR=#00008b]1[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] = [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]data[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i [/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]+ [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#00008b][SIZE=2][COLOR=#00008b]1[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] - [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]data[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] += [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]data[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i [/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]+ [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#00008b][SIZE=2][COLOR=#00008b]1[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] += [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE][/COLOR][/SIZE]
    would become
    Code:
    real[SIZE=2]data[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]j[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] = [/COLOR][COLOR=black]real[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=black]da[/COLOR]ta[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] - [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]imagdata[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]j[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] = [/COLOR][COLOR=black]imag[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=black]d[/COLOR]ata[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] - [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]realdata[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] += [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]imagdata[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] += [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE][/COLOR][/SIZE]
    Could you please have a look at this.

    If this is could be done, then we do no more need two methods for Amplitude and Phase.

    With ToAmplitudePhase I was thinking of a single method for getting both arrays, but two seperate functions are OK for me.

    Best regards.
     
  6. agraham

    agraham Expert Licensed User

    It's not quite that simple as the loop arithmetic needs altering together with some other indexing stuff but I'll have a think about restructuring the library as it has grown a bit like Topsy.
     
  7. agraham

    agraham Expert Licensed User

    Try this, it's probably buggy as I haven't played with it. To keep things simple and retain the full inverse transform capability I didn't generate imaginary internal values. Dimming a new array initialised to zeroes is just as cheap in Basic4pc code as in C#.

    void Transform(double[] real, double[]imag)

    void Inverse(double[] real, double[] imag)

    double[] CopyArray(double[] array)

    double[] ToAmplitude(double[] real, double[] imag, double scale)

    double[] ToPhase(double[] real, double[] imag)

    ToAmpAndPhase(double[] real, double[] imag, double scale) ' half and half

    double[] ToReal(double[] amplitude, double[] phase, double scale)

    double[] ToImaginary(double[] amplitude, double[] phase, double scale)


    EDIT :- It doesn't work. I don't understand the indexing (k) in the bitreverse method so can't get it right for separate Real and Image arrays and theres a similar problem (b) in the actual transform. I'm going back to the original algorithm but will make it accept and return separate arrays.
     

    Attached Files:

    Last edited: Mar 16, 2010
  8. agraham

    agraham Expert Licensed User

    I'm beginning to wish I hadn't started this separate array stuff :( Try this version with the same methods listed above.
     

    Attached Files:

  9. klaus

    klaus Expert Licensed User

    Hi Andrew,

    I just cam back home, and looked at the library.
    What version is FFTV1.2 ?
    The one before your edit ?

    I had a look at the FFT.cs file and found that in lines 65-68
    Code:
    [SIZE=2]real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]j[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] = [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] - [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]j[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] = [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] - [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] += [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] += [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE][/COLOR][/SIZE]
    should be
    Code:
    [SIZE=2]real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]j[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] = [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] - [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]j[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] = [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] - [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2][COLOR=red]real[/COLOR][/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] += [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_real[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE]
    [/COLOR][/SIZE][SIZE=
    2]imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400][[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]i[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400]] += [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]wd_imag[/SIZE][SIZE=2][COLOR=#006400][SIZE=2][COLOR=#006400];[/COLOR][/SIZE][/COLOR][/SIZE]
    This evening I won't be at home.

    Best regards.
     
  10. agraham

    agraham Expert Licensed User

    V1.1 takes a single data() array
    V1.2 attempted modified algorithm to take real() and imag() arrays - FAILURE for at least two reasons.
    V1.3 original alogorithm wrapped to look like V1.2
     
  11. redbird

    redbird Member Licensed User

    Don't want to interrupt any subject here, but I thought I could mention a strange thing with those desktop and device recorder.dlls.

    When analyzing a recorded (stereo) wave-file, made on my HTC Touch HD, I noticed that after the header (44 bytes long) all the bytes are filled with the same value (128 decimal), until position 7759 in the file, counting from position zero.

    This does not happen with the (mono) desktop recording dll. After the header, there are "normal" amplitude bytes right away, that's from position 44.

    I don't know if this might be related to my device, or a problem with a library or so, but I thought I just mention this.

    In my app, I simply ignore the first 7760 bytes before extracting samples, just to be sure.
     
  12. agraham

    agraham Expert Licensed User

    I think that stretch of silence can only be down to the device.

    I think I got the algorithm working with separate arrays so here it is. The source code is messy as there is a lot of commented out stuff I don't want to lose until Klaus is happy with the library. Methods are as below. Now I'll start the help and wait for Klaus to check the library and come up with a demo.

    void Transform(double[] real, double[]imag)

    void Inverse(double[] real, double[] imag)

    double[] CopyArray(double[] array)

    double[] ToAmplitude(double[] real, double[] imag, double scale)

    double[] ToPhase(double[] real, double[] imag)

    ToAmpAndPhase(double[] real, double[] imag, double scale) ' half and half

    double[] ToReal(double[] amplitude, double[] phase, double scale)

    double[] ToImaginary(double[] amplitude, double[] phase, double scale)
     

    Attached Files:

  13. klaus

    klaus Expert Licensed User

    Hi Andrew,

    The library works fine !!!
    I am still improving the test program. Will be ready in a few days.
    Adding sine number and parameters user defined and sine modulation showing the sideband phenomenon.

    If I could abuse, I still would be pleased having a function like this:
    Fft.Transform1(DataReal(),FFTReal(),FFTImag())
    Fft.Inverse1(FFTReal(),FFTImag(),DataReal())

    Where DataReal remains the same, DataImag generated internaly in the dll and FFTReal and FFTImag having half the length than the DataReal array.
    In the Inverse1 function FFTReal and FFTImag must be converted in arrays having the conjugated values added.

    Reason: the library user has in his program only arrays with useful values.
    Fft.Transform and Fft.Inverse should remain.

    Best regards.
     
  14. klaus

    klaus Expert Licensed User

    Hi redbird,​

    A few questions about your project:
    - the sampling frequency is 11025 samples /s
    - does this mean that you take one sample out of 4 in the wave file ?
    - what accuracy of the blade speed do you expect ?
    - what update frequecy would you accept ?​

    With:
    - a frequency of 11025 samples /s
    - 4096 samples
    you get:
    - an accuracy of the speed of +/- 80 rpm
    - wave file length need 0.37 s​

    You could with:
    - a sampling frequency of 5512.5 samples /s
    - 4096 samples
    get:
    - an accuracy of the speed of +/- 40 rpm
    - wave file length need 0.74 s​

    Attached an Excel file with different configurations.​

    Best regards.​
     

    Attached Files:

  15. redbird

    redbird Member Licensed User

    Hi Klaus,

    - Because of the way the B4PPC recorder dlls are made now, I seem to be stuck to 11025 samples/second only.
    - I take 4096 subsequent bytes out of a (mono) WAVE file, double for stereo of course, and reject 1 byte every 2 bytes to get a mono file.
    - Your accuracy figures are correct, I came to the same conclusion, studying the FFTs I made with Excel. In fact, there is about 80 rpm between 2 frequencies, meaning any final result that is theoretically somewhere in between this 80 RPM interval, would have "jumped" to the most close-by value, so I was thinking the deviation would be +/- 40 RPM at most ? And this is close enough for my application. Barely, but still OK.
    - The update frequency is of no real importance, as it is no real-time tachometer. This is not of much use with RC helis. And it makes things easier for me. The user has to make the short recording in the app, and only after that, the file is analyzed by my app. But the total time of this should stay within a few seconds, to keep it user-friendly. A new reading needs a new recording, initiated by the user.
    - the wave file length I need now is indeed 0.372 seconds, but I use a longer sample, to avoid the "dead and silent" period (7760 bytes) that I see in
    the beginning of the file when recording on my PDA.

    I will try soon with a sample of 16384 bytes (2^14), being a 4 times longer sample of course. I estimated the accuracy to improve equally by a factor 4,
    resulting in a 20 RPM interval, or +/- 10 RPM if my above way of thinking would be true.

    I fail to understand your words about taking one sample out of 4, there might be something I don't get there ?


    Best regards,

    Raf

    This draft of a simple user interface gives you the idea:

    [​IMG]
     

    Attached Files:

  16. agraham

    agraham Expert Licensed User

    @Klaus - I've added the two transform methods you asked for and a third method, CopyData, that might be useful. There is now a more or less final help file in the archive.

    I am not sure I have done the correct thing when reconstructing the complex conjugate parts. I notice, assuming a 512 sample FFT, that index 0 is the DC component and is not reflected in the complex part, so index 1 is reflected into index 511, 2 into 510, and so on. This leaves no value to be relected into index 256 so I have left it as zero.

    I also note that when I add a DC component of value 1 to one of the Sine series, after Transform I get a DC amplitude of 2 whereas I expected 1. It seems to inverse transform back OK. Is there a simple explanation why it is twice what I thought it would be. :confused:
     

    Attached Files:

  17. agraham

    agraham Expert Licensed User

    On the device go to Start -> Settings -> Input -> Options (Tab NOT button). The voice recording format selected there may alter what the library records.

    EDIR:- Probably not. It looks like the format is burnt into the library code. :(
     
    Last edited: Mar 18, 2010
  18. redbird

    redbird Member Licensed User

    Good tip Andrew, never even tried. But I was also afraid that this samplerate is imposed by the dll. Not such a big deal right now, I got it working with 16384 bytes, as stated above. Only thing is it takes me about 10-12 seconds to read all that data from the wave file into an array on a PDA. Still acceptable though. On the desktop, you even can't notice there is a delay.
     
  19. klaus

    klaus Expert Licensed User

    Hi Raf,
    Code:
    I fail to understand your words about taking one sample out of 4,
    there might be something I don
    't get there
    I had in mind with the digital audio sampling rating of 44100 Hz and your 11025 Hz sampling rate you would need to take 1 sample out of 4.
    But it seems that I'm wrong, is the sampling rate on the PPC's only 11025 Hz ?

    Code:
    In fact, there is about 80 rpm between 2 frequencies
    I don't agree with that:
    - with a sampling rate of 11025 Hz you get 9.07E-5 s sampling time interval
    - with 4096 samples this gives .3715 s time window duration
    - this gives 1/.3715 = 2.69 Hz frequency interval which is 161 rpm so +/- 80 rpm

    Best regards.
     
  20. redbird

    redbird Member Licensed User

    Klaus, completely correct until the 2.69 Hertz, but then I guess there is something I did not mention clearly enough, my bad:

    My app records the sound of a RC heli which typically has TWO blades, meaning that every sinlge rotation of the head produces two consecutive sounds. So, I am not recording shaft RPM, but blade sound, which is exactly 2 times faster. This made me state the number of 80 RPM accuracy (+/-40 RPM), it is as if the 2 blades double my sample rate for free :). I hope this is correct, but if I would make any error in thinking, I would gladly accept your opinion. My apologies for not mentioning this clear enough, it is a bit too obvious for me as a R/C hobbyist, I guess.
    Of course, I need to take the 2 blades also into account when going from frequency to RPM.
    In my case: RPM = 11025/4096*60/2*index_of_array().
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice