0 Replies Latest reply on Dec 8, 2009 12:12 PM by RonNovy

    Running histogram.

    RonNovy Level 2

      Anyone that has used iZotope Ozone has probably seen the histogram in the Loudness maximizer section.  I was just wondering what people would think about Audition having its own running histogram for real-time analysis?  Would it be it's own seperate window or could it possibly replace or overlay the VU meters that are already there or both???

       

      It's just another crazy idea that I think might be helpful.  It would give more information then the usual VU meters... And it would be a bit of eye candy as well

       

      Just so everyone knows what I mean when I say 'running histogram' I'll post code... Ok I'm just bored...

       

      All in regular C and no guarantees that it works.. Never tested...

       

       

      /* Structure to hold data for a running histogram. */
      typedef struct DSP_RUNNING_HISTOGRAM {
          int  w_size;     /* size of sample window */
          int  w_cur;      /* current offset into window */
          int *window;     /* the window buffer */

       

          int  h_size;     /* size of histogram */
          int *histogram;  /* the histogram */
          int  underflow;  /* Underflow count */
          int  overflow;   /* Overflow count */
      } DSP_RUNNING_HISTOGRAM;

       

      #define MAX_HISTOGRAM_SIZE  (65536)
      #define MAX_HWINDOW_SIZE    (65536)


      #ifndef NULL
          #define NULL ((void*)0)
      #endif

       


      /* dsp_new_running_histogram:
      *  Creates a new structure for histogram data. If WINDOW_SIZE is 0 then
      * the structure is treated like a regular histogram and not a running
      * histogram so be sure not to continuously add data... ;P
      */
      DSP_RUNNING_HISTOGRAM *dsp_new_running_histogram(
          int window_size, int histogram_size)
      {
          DSP_RUNNING_HISTOGRAM *r = malloc(sizeof(DSP_RUNNING_HISTOGRAM));

       

          /* Limit the size of the histogram data */
          if (histogram_size > MAX_HISTOGRAM_SIZE)
              histogram_size = MAX_HISTOGRAM_SIZE;

       

          if (window_size > MAX_HWINDOW_SIZE)
              window_size = MAX_HWINDOW_SIZE;

       

          /* Check to see that we have the memory and then fill it */
          if (r) {
              r->w_size = window_size;
              r->w_cur  = 0;
              if (window_size > 0)
                  r->window = malloc(sizeof(int) * window_size);
              else
                  r->window = NULL;

       

              /* To get the entire range of data we add 1. */
              r->h_size    = histogram_size;
              r->histogram = malloc(sizeof(int) * histogram_size + 1);
              r->underflow = window_size;
              r->overflow = 0;

       

              /* Check for memory */
              if (!r->window || !r->histogram) {
                  free(r->window);
                  free(r->histogram);
                  free(r);
                  return NULL;
              }

       

              memset(r->window, 0xffffffff, r->w_size);
              memset(r->histogram, 0, r->h_size + 1);
          }

       

          return r;
      }

       

       

       

      /* dsp_free_histogram:
      *  Frees all memory used by the running histogram structure.
      */
      void *dsp_free_histogram(DSP_RUNNING_HISTOGRAM *x)
      {
          if (x) {
              free(x->histogram);
              free(x->window);
              free(x);
          }
          return NULL;
      }

       

       


      /* dsp_do_magnitude_histogram:
      *  Adds data to a histogram. Sample data should be between 0 and +1 and
      * data that is out of range will be recorded in the UNDERFLOW and OVERFLOW
      * variables in the DSP_RUNNING_HISTOGRAM structure. If the window is setup
      * then old data will be subtracted before the new data is added.
      */
      void dsp_do_magnitude_histogram(DSP_RUNNING_HISTOGRAM *x, int num_samples,  double *sample)
      {
          int i, v;

          for (i = 0; i < num_samples; i++) {

              /* Subtract old value in current window */
              v = x->window[x->w_cur];
              if (v < 0)
                  x->underflow--;
              else if (v <= x->h_size)
                  x->histogram[v]--;
              else
                  x->overflow--;

              /* scale new sample to fit in graph */
              x->window[x->w_cur] = v = (int)floor(sample[i] * x->h_size + 0.5);
              if (v < 0)
                  x->underflow++;
              else if (v <= x->h_size)
                  x->histogram[v]++;
              else
                  x->overflow++;

              /* increment and bind window cursor */
              x->w_cur++;
              x->w_cur %= x->w_size;
          }
      }