libxputty  0.1
A damn tiny abstraction Layer to create X11 window/widgets with cairo surfaces
xtuner_private.c
Go to the documentation of this file.
1 /*
2  * 0BSD
3  *
4  * BSD Zero Clause License
5  *
6  * Copyright (c) 2019 Hermann Meyer
7  *
8  * Permission to use, copy, modify, and/or distribute this software for any
9  * purpose with or without fee is hereby granted.
10 
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  *
19  */
20 
21 
22 #include "xtuner_private.h"
23 
24 
25 static const char *note_sharp[] = {"A","A#","B","C","C#","D","D#","E","F","F#","G","G#"};
26 static const char *note_flat[] = {"A","Bb","B","C","Db","D","Eb","E","F","Gb","G","Ab"};
27 static const char* note_19[19] = {"A","A♯","B♭","B","B♯","C","C♯","D♭","D","D♯","E♭","E","E♯","F","F♯","G♭","G","G♯","A♭"};
28 static const char* note_24[24] = {"A","A¼♯","A♯","A¾♯","B","B¼♯","C","C¼♯","C♯","C¾♯","D","D¼♯","D♯","D¾♯","E","E¼♯","F","F¼♯","F♯","F¾♯","G","G¼♯","G♯","G¾♯"};
29 static const char* note_31[31] = {"A","B♭♭","A♯","B♭","A♯♯","B","C♭","B♯","C ","D♭♭","C♯","D♭","C♯♯","D","E♭♭","D♯","E♭","D♯♯","E","F♭","E♯","F","G♭♭","F♯","G♭","F♯♯","G","A♭♭","G♯","A♭","G♯♯"};
30 static const char* note_53[53] = {"la","laa","lo","law","ta","teh","te","tu","tuh","ti","tih","to","taw","da","do","di","daw","ro","rih","ra","ru","ruh","reh","re ","ri","raw","ma","meh","me","mu","muh","mi","maa","mo","maw","fe","fa","fih","fu","fuh","fi","se","suh","su","sih","sol","si","saw","lo","leh","le","lu","luh"};
31 static const char *octave[] = {"0","1","2","3","4","5"," "};
32 
33 static void _tuner_triangle(Widget_t *w, float posx, float posy, float width, float height)
34 {
35  float h2 = height/2.0;
36  cairo_move_to(w->crb, posx, posy-h2);
37  if (width > 0) {
38  cairo_curve_to(w->crb,posx, posy-h2, posx+10, posy, posx, posy+h2);
39  } else {
40  cairo_curve_to(w->crb,posx, posy-h2, posx-10, posy, posx, posy+h2);
41  }
42  cairo_curve_to(w->crb,posx, posy+h2, posx+width/2, posy+h2, posx+width, posy);
43  cairo_curve_to(w->crb, posx+width, posy, posx+width/2, posy-h2, posx, posy-h2);
44  cairo_fill(w->crb);
45  cairo_new_path (w->crb);
46 }
47 
48 static int _get_tuner_temperament(Widget_t *w) {
49  XTuner *xt = (XTuner *)w->parent_struct;
50  if((int)xt->temperament == 0) return 12;
51  else if((int)xt->temperament == 1) return 19;
52  else if((int)xt->temperament == 2) return 24;
53  else if((int)xt->temperament == 3) return 31;
54  else if((int)xt->temperament == 4) return 53;
55  else return 12;
56 }
57 
58 static const char **_get_note_set(Widget_t *w) {
59  XTuner *xt = (XTuner *)w->parent_struct;
60  if((int)xt->temperament == 0) return note_sharp;
61  else if((int)xt->temperament == 1) return note_19;
62  else if((int)xt->temperament == 2) return note_24;
63  else if((int)xt->temperament == 3) return note_31;
64  else if((int)xt->temperament == 4) return note_53;
65  else return note_flat;
66 
67 }
68 
69 void _draw_tuner(void *w_, void* user_data) {
70  Widget_t *w = (Widget_t*)w_;
71  if (!w) return;
72  XTuner *xt = (XTuner *)w->parent_struct;
73  XWindowAttributes attrs;
74  XGetWindowAttributes(w->app->dpy, (Window)w->widget, &attrs);
75  if (attrs.map_state != IsViewable) return;
76  int width = attrs.width;
77  int height = attrs.height;
78  float x0 = width/2;
79  float y0 = height/2;
80 
82  cairo_paint (w->crb);
83 
84  cairo_set_source_rgb(w->crb,0.2,0.2,0.2);
85  _tuner_triangle(w, width/5.8,y0 , 25/w->scale.ascale, 20/w->scale.ascale);
86  _tuner_triangle(w, width/1.2, y0, -25/w->scale.ascale, 20/w->scale.ascale);
87 
88  float value = adj_get_value(w->adj);
89  float scale = -0.5;
90 
91  float fvis = _get_tuner_temperament(w) * (log2f(value/xt->ref_freq) + 4);
92  float fvisr = round(fvis);
93  int vis = fvisr;
94  int indicate_oc = round((fvisr+xt->temp_adjust)/_get_tuner_temperament(w));
95  const int octsz = sizeof(octave) / sizeof(octave[0]);
96  if (indicate_oc < 0 || indicate_oc >= octsz) {
97  // just safety, should not happen with current parameters
98  // (pitch tracker output 23 .. 999 Hz)
99  indicate_oc = octsz - 1;
100  }
101 
102  scale = (fvis-vis) / 2;
103  vis = vis % _get_tuner_temperament(w);
104  if (vis < 0) {
105  vis += _get_tuner_temperament(w);
106  }
107 
108  if (value > 24.0 && value < 999.0) {
109  if (scale < 0.003) {
110  cairo_set_source_rgb(w->crb,0.80,0.79,0.01);
111  _tuner_triangle(w, (width/5.8),y0 , 25/w->scale.ascale, 20/w->scale.ascale);
112  _tuner_triangle(w, (width/5.8)-(140*scale)/w->scale.ascale,y0 , 25/w->scale.ascale, 20/w->scale.ascale);
113  _tuner_triangle(w, (width/5.8)-(280*scale)/w->scale.ascale,y0 , 25/w->scale.ascale, 20/w->scale.ascale);
114  }
115  if (scale > -0.003) {
116  cairo_set_source_rgb(w->crb,0.80,0.79,0.01);
117  _tuner_triangle(w, (width/1.2), y0, -25/w->scale.ascale, 20/w->scale.ascale);
118  _tuner_triangle(w, (width/1.2)-(140*scale)/w->scale.ascale, y0, -25/w->scale.ascale, 20/w->scale.ascale);
119  _tuner_triangle(w, (width/1.2)-(280*scale)/w->scale.ascale, y0, -25/w->scale.ascale, 20/w->scale.ascale);
120  }
121  }
122  // display note
123  cairo_set_source_rgba(w->crb, fabsf(scale)*2, 1-(scale*scale*4), 0.2,1-(fabsf(scale)*2));
124  cairo_set_font_size(w->crb, (w->app->big_font*2)/w->scale.ascale);
125  cairo_text_extents_t extents;
126  cairo_text_extents(w->crb,_get_note_set(w)[vis] , &extents);
127 
128  if (value > 24.0 && value < 999.0) {
129  float c = (extents.width/2)+10.0;
130  cairo_move_to(w->crb,x0-c , y0 );
131  cairo_show_text(w->crb, _get_note_set(w)[vis]);
132  cairo_set_font_size(w->crb, (w->app->small_font*2)/w->scale.ascale);
133  cairo_move_to(w->crb,x0+c-10.0, y0+ extents.height/2 );
134  cairo_show_text(w->crb, octave[indicate_oc]);
135 
136  char s[64];
137  const char* format[] = {"%.1f Hz", "%.2f Hz", "%.3f Hz"};
138  snprintf(s, 63, format[2-1], value);
140  cairo_set_font_size (w->crb, w->app->normal_font/w->scale.ascale);
141  cairo_text_extents(w->crb,s , &extents);
142  cairo_move_to (w->crb, width/1.2-extents.width/2, height-extents.height );
143  cairo_show_text(w->crb, s);
144  }
145 }
XTuner
Definition: xtuner.h:33
use_text_color_scheme
void use_text_color_scheme(Widget_t *w, Color_state st)
use_text_color_scheme - use text Colors to paint on Widget_t
Definition: xcolor.c:199
Xputty::big_font
int big_font
Definition: xputty.h:193
Widget_t::parent_struct
void * parent_struct
Definition: xwidget.h:306
Xputty::normal_font
int normal_font
Definition: xputty.h:191
adj_get_value
float adj_get_value(Adjustment_t *adj)
adj_get_value - get the current value of the Adjustment_t
Definition: xadjustment.c:154
Widget_t::crb
cairo_t * crb
Definition: xwidget.h:318
Widget_t::adj
Adjustment_t * adj
Definition: xwidget.h:334
xtuner_private.h
XTuner::temperament
float temperament
Definition: xtuner.h:35
Widget_t::scale
Resize_t scale
Definition: xwidget.h:356
use_bg_color_scheme
void use_bg_color_scheme(Widget_t *w, Color_state st)
use_bg_color_scheme - use background Colors to paint on Widget_t
Definition: xcolor.c:185
Widget_t::app
Xputty * app
Definition: xwidget.h:300
Xputty::dpy
Display * dpy
Definition: xputty.h:181
Resize_t::ascale
float ascale
Definition: xwidget.h:214
Widget_t::widget
Window widget
Definition: xwidget.h:302
Widget_t
Widget_t - struct to hold the basic Widget_t info.
Definition: xwidget.h:298
XTuner::temp_adjust
int temp_adjust
Definition: xtuner.h:36
NORMAL_
@ NORMAL_
Definition: xcolor.h:39
Xputty::small_font
int small_font
Definition: xputty.h:189
XTuner::ref_freq
float ref_freq
Definition: xtuner.h:34
_draw_tuner
void _draw_tuner(void *w_, void *user_data)
_draw_tuner - draw the tuner on expose call
Definition: xtuner_private.c:69