No announcement yet.

Savitzky-Golay smoothing

  • Filter
  • Time
  • Show
Clear All
new posts

  • Savitzky-Golay smoothing

    I put a demo in Source and had some posts in Programming, but have a question that maybe will get better exposure here. My filter is a weighted moving average filter implemented with a loop through an array. The intent is to use it with wav files. Two questions-

    1) Did it make sense to do this with indexed pointers like I did?

    2) Can anybody show this mathphobe how it can be done using MAT, assuming that's a reasonable way to go about it?

    example filter-
    SUB SG_Smooth15(nSamples AS LONG, dLen1 AS LONG)                'Savitzky-Golay filter, # of points = 15
        LOCAL i AS LONG
        FOR i = 7 TO nSamples - 7
            @sData[i] = (-78 * @pData[i - 7] -13 * @pData[i - 6] + 42 * @pData[i - 5] + 87 * @pData[i - 4] _
                        + 122 * @pData[i - 3] + 147 * @pData[i - 2] + 162 * @pData[i - 1] + 167 * @pData[i] _
                        + 162 * @pData[i + 1] + 147 * @pData[i + 2] + 122 * @pData[i + 3] + 87 * @pData[i + 4] _
                        + 42 * @pData[i + 5] - 13 * @pData[i + 6] -78 * @pData[i + 7]) / 1105
        MEMORY COPY sData, pData, dLen1                             'copy filtered data to reference array for next run

  • #2

    I couldn't see your source because of work restrictions on downloading zip files.

    The snippet you've posted here looks ok to me in terms of the implementation f the filter. I'm assuming that sData and pData are globals that you've declared and assigned elsewhere.

    Indexed pointers are an efficient way of going about things, but I don't know if they're that much better than ordinary array indexes. You do have to be careful about your pointers pointing at the correct type of variable - if the size is wrong, Bad Things will happen.

    If I remember rightly, WAV files store data as 16-bit integers? If so, and if your pData points directly at the WAV data, you may get overflow errors.

    I can't really see any way that MAT would help. Unless you're looking to calculate the S-G weights within your programme, in which case it's probably the best way forward.


    • #3
      Thanks- I've been told "don't deal with individual samples" but didn't see how to do it with a matrix function. The file data is signed 16 bit, and has been separated out for my calcs, so no problem with the indexed pointer- you described exactly what I'm doing. I thought about overflow and am not sure if it's a problem on internal calcs or not, so long as I don't assign a large intermediate result to a low-bit variable. The filter output is scaled so it's the same or smaller than the original signal. Is that right, or do I need to worry?
      Last edited by Conrad Hoffman; 21 Apr 2017, 01:51 PM.


      • #4
        The ultimate goal of doing this was to understand it well enough to translate it into Nyquist, the LISP extension used by the Audacity sound editor. After wasting several days trying to grasp LISP, I'm giving up. It has a convolve function and conceptually I know exactly what I want to do, but between the syntax mysteries, various versions and incomplete documentation, there are better things to spend my time on. Makes me really appreciate PB!

        (actually, stubbornness will force me to keep after this in my spare time)
        Last edited by Conrad Hoffman; 24 Apr 2017, 07:59 AM.


        • #5
          Originally posted by Conrad Hoffman View Post

          (actually, stubbornness will force me to keep after this in my spare time)
          What, you get "spare time"??? LOL!!! Send me a some!

          Actually, your statement is in the true PB tradition! (Or was that Galaxy Quest? -- "Never give up! Never surrender!")



          • #6
            I think it would look like this, not nearly as efficient as what you've done though!

            Define MAT a (nSamples x nSamples) as:
            first 7 rows 0
            -78 -13 ........167 ..... -13. -78 ...................8th row
            ......-78 -13 .......167.........-13 -78............ 9th row
            etc with staggered rows
            last 7 rows 0

            MAT s (nSamples x 1)

            s = a*s
            Last edited by Charles Dietz; 24 Apr 2017, 02:46 PM. Reason: couldn't show staggered rows using spaces


            • #7
              following your code s = a*s, but I wonder if it shouldn't be s = s + a*s


              • #8
                I think for the same reason I use two arrays- you don't want to calculate the smoothing using partially smoothed data.