spek

Acoustic spectrum analyser https://github.com/alexkay/spek spek.cc
git clone http://git.hanabi.in/repos/spek.git
Log | Files | Refs | README

spek-palette.cc (2529B)


      1 #include <assert.h>
      2 #include <math.h>
      3 
      4 #include "spek-palette.h"
      5 
      6 // Modified version of Dan Bruton's algorithm:
      7 // http://www.physics.sfasu.edu/astro/color/spectra.html
      8 static uint32_t spectrum(double level)
      9 {
     10     level *= 0.6625;
     11     double r = 0.0, g = 0.0, b = 0.0;
     12     if (level >= 0 && level < 0.15) {
     13         r = (0.15 - level) / (0.15 + 0.075);
     14         g = 0.0;
     15         b = 1.0;
     16     } else if (level >= 0.15 && level < 0.275) {
     17         r = 0.0;
     18         g = (level - 0.15) / (0.275 - 0.15);
     19         b = 1.0;
     20     } else if (level >= 0.275 && level < 0.325) {
     21         r = 0.0;
     22         g = 1.0;
     23         b = (0.325 - level) / (0.325 - 0.275);
     24     } else if (level >= 0.325 && level < 0.5) {
     25         r = (level - 0.325) / (0.5 - 0.325);
     26         g = 1.0;
     27         b = 0.0;
     28     } else if (level >= 0.5 && level < 0.6625) {
     29         r = 1.0;
     30         g = (0.6625 - level) / (0.6625 - 0.5f);
     31         b = 0.0;
     32     }
     33 
     34     // Intensity correction.
     35     double cf = 1.0;
     36     if (level >= 0.0 && level < 0.1) {
     37         cf = level / 0.1;
     38     }
     39     cf *= 255.0;
     40 
     41     // Pack RGB values into a 32-bit uint.
     42     uint32_t rr = (uint32_t) (r * cf + 0.5);
     43     uint32_t gg = (uint32_t) (g * cf + 0.5);
     44     uint32_t bb = (uint32_t) (b * cf + 0.5);
     45     return (rr << 16) + (gg << 8) + bb;
     46 }
     47 
     48 // The default palette used by SoX and written by Rob Sykes.
     49 static uint32_t sox(double level)
     50 {
     51     double r = 0.0;
     52     if (level >= 0.13 && level < 0.73) {
     53         r = sin((level - 0.13) / 0.60 * M_PI / 2.0);
     54     } else if (level >= 0.73) {
     55         r = 1.0;
     56     }
     57 
     58     double g = 0.0;
     59     if (level >= 0.6 && level < 0.91) {
     60         g = sin((level - 0.6) / 0.31 * M_PI / 2.0);
     61     } else if (level >= 0.91) {
     62         g = 1.0;
     63     }
     64 
     65     double b = 0.0;
     66     if (level < 0.60) {
     67         b = 0.5 * sin(level / 0.6 * M_PI);
     68     } else if (level >= 0.78) {
     69         b = (level - 0.78) / 0.22;
     70     }
     71 
     72     // Pack RGB values into a 32-bit uint.
     73     uint32_t rr = (uint32_t) (r * 255.0 + 0.5);
     74     uint32_t gg = (uint32_t) (g * 255.0 + 0.5);
     75     uint32_t bb = (uint32_t) (b * 255.0 + 0.5);
     76     return (rr << 16) + (gg << 8) + bb;
     77 }
     78 
     79 static uint32_t mono(double level)
     80 {
     81     uint32_t v = (uint32_t) (level * 255.0 + 0.5);
     82     return (v << 16) + (v << 8) + v;
     83 }
     84 
     85 uint32_t spek_palette(enum palette palette, double level) {
     86     switch (palette) {
     87     case PALETTE_SPECTRUM:
     88         return spectrum(level);
     89     case PALETTE_SOX:
     90         return sox(level);
     91     case PALETTE_MONO:
     92         return mono(level);
     93     default:
     94         assert(false);
     95         return 0;
     96     }
     97 }