1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 9 июл. 2019 г.
7  *
8  * lsp-plugins is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * lsp-plugins is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef UI_TK_WIDGETS_LSPAUDIOSAMPLE_H_
23 #define UI_TK_WIDGETS_LSPAUDIOSAMPLE_H_
24 
25 namespace lsp
26 {
27     namespace tk
28     {
29 
30         class LSPAudioSample: public LSPWidget
31         {
32             public:
33                 static const w_class_t    metadata;
34 
35             protected:
36                 typedef struct channel_t
37                 {
38                     size_t          nSamples;       // Number of samples
39                     size_t          nCapacity;      // Capacity
40                     float          *vSamples;       // Sample values
41 
42                     float           nFadeIn;
43                     float           nFadeOut;
44                     LSPColor        sColor;
45                     LSPColor        sFadeColor;
46                     LSPColor        sLineColor;
47 
48                     explicit channel_t(LSPWidget *parent);
49                 } channel_t;
50 
51                 enum flags_t
52                 {
53                     AF_SHOW_DATA        = 1 << 0,
54                     AF_SHOW_HINT        = 1 << 1,
55                     AF_SHOW_CURR_LEN    = 1 << 2,
56                     AF_SHOW_MAX_LEN     = 1 << 3
57                 };
58 
59             protected:
60                 LSPColor            sColor;
61                 LSPColor            sAxisColor;
62 
63                 LSPString           sHint;
64 
65                 LSPFont             sFont;
66                 LSPFont             sHintFont;
67                 LSPSizeConstraints  sConstraints;
68 
69                 ISurface           *pGlass;
70                 ISurface           *pGraph;
71                 cvector<channel_t>  vChannels;
72 
73                 size_t              nDecimSize;     // Decimation buffer size
74                 float              *vDecimX;        // Decimation buffer data for x
75                 float              *vDecimY;        // Decimation buffer data for y
76                 size_t              nBorder;
77                 size_t              nRadius;
78                 size_t              nStatus;
79                 float               fCurrLen;
80                 float               fMaxLen;
81 
82             protected:
83                 channel_t          *create_channel(color_t color);
84                 void                destroy_channel(channel_t *channel);
85                 void                destroy_data();
86                 ISurface           *render_graph(ISurface *s, ssize_t w, ssize_t h);
87                 void                drop_glass();
88                 void                render_channel(ISurface *s, channel_t *c, ssize_t y, ssize_t w, ssize_t h);
89 
90             public:
91                 explicit LSPAudioSample(LSPDisplay *dpy);
92                 virtual ~LSPAudioSample();
93 
94                 virtual status_t init();
95                 virtual void destroy();
96 
97             public:
hint()98                 inline const char      *hint() const { return sHint.get_utf8(); }
get_hint(LSPString * dst)99                 inline status_t         get_hint(LSPString *dst) const { return (dst->set(&sHint)) ? STATUS_OK : STATUS_NO_MEM; };
100 
constraints()101                 inline LSPSizeConstraints  *constraints()   { return &sConstraints; }
102 
font()103                 inline LSPFont         *font() { return &sFont; }
hint_font()104                 inline LSPFont         *hint_font() { return &sHintFont; }
105 
color()106                 inline LSPColor        *color() { return &sColor; }
bg_color()107                 inline LSPColor        *bg_color() { return &sBgColor; }
axis_color()108                 inline LSPColor        *axis_color() { return &sAxisColor; }
109 
channels()110                 inline size_t           channels() const { return vChannels.size(); }
channel_samples(size_t i)111                 inline ssize_t          channel_samples(size_t i) const { const channel_t *c = (const_cast<LSPAudioSample *>(this))->vChannels.get(i); return (c != NULL) ? c->nSamples : -1; }
channel_fade_in(size_t i)112                 inline float            channel_fade_in(size_t i) const { const channel_t *c = (const_cast<LSPAudioSample *>(this))->vChannels.get(i); return (c != NULL) ? c->nFadeIn : -1.0f; }
channel_fade_out(size_t i)113                 inline float            channel_fade_out(size_t i) const { const channel_t *c = (const_cast<LSPAudioSample *>(this))->vChannels.get(i); return (c != NULL) ? c->nFadeOut : -1.0f; }
channel_data(size_t i)114                 inline const float     *channel_data(size_t i) const { const channel_t *c = (const_cast<LSPAudioSample *>(this))->vChannels.get(i); return ((c != NULL) && (c->vSamples != NULL)) ? c->vSamples : NULL; }
channel_color(size_t i)115                 inline LSPColor        *channel_color(size_t i) { channel_t *c = vChannels.get(i); return (c != NULL) ? &c->sColor : NULL; }
channel_fade_color(size_t i)116                 inline LSPColor        *channel_fade_color(size_t i) { channel_t *c = vChannels.get(i); return (c != NULL) ? &c->sFadeColor : NULL; }
channel_line_color(size_t i)117                 inline LSPColor        *channel_line_color(size_t i) { channel_t *c = vChannels.get(i); return (c != NULL) ? &c->sLineColor : NULL; }
118 
show_data()119                 inline bool             show_data() const           { return nStatus & AF_SHOW_DATA; }
show_hint()120                 inline bool             show_hint() const           { return nStatus & AF_SHOW_HINT; }
show_curr_length()121                 inline bool             show_curr_length() const    { return nStatus & AF_SHOW_CURR_LEN; }
show_max_length()122                 inline bool             show_max_length() const     { return nStatus & AF_SHOW_CURR_LEN; }
123 
radius()124                 inline size_t           radius() const { return nRadius; }
border()125                 inline size_t           border() const { return nBorder; }
curr_length()126                 inline float            curr_length() const         { return fCurrLen; }
max_length()127                 inline float            max_length() const          { return fMaxLen; }
128 
129             public:
130                 status_t        set_hint(const char *text);
131                 status_t        set_hint(const LSPString *text);
132 
133                 status_t        set_channels(size_t n);
134                 status_t        add_channel();
135                 status_t        add_channels(size_t n);
136                 status_t        remove_channel(size_t i);
137                 status_t        swap_channels(size_t a, size_t b);
138 
139                 status_t        set_channel_fade_in(size_t i, float value);
140                 status_t        set_channel_fade_out(size_t i, float value);
141                 status_t        set_channel_data(size_t i, size_t samples, const float *data);
142                 status_t        clear_channel_data(size_t i);
143                 status_t        clear_all_channel_data();
144 
145                 status_t        set_radius(size_t radius);
146                 status_t        set_border(size_t border);
147 
148                 void            set_show_data(bool value = true);
149                 void            set_show_hint(bool value = true);
150                 void            set_show_curr_length(bool value = true);
151                 void            set_show_max_length(bool value = true);
152                 void            set_curr_length(float value);
153                 void            set_max_length(float value);
154 
155             public:
156                 virtual void draw(ISurface *s);
157 
158                 virtual void size_request(size_request_t *r);
159         };
160 
161     } /* namespace tk */
162 } /* namespace lsp */
163 
164 #endif /* UI_TK_WIDGETS_LSPAUDIOSAMPLE_H_ */
165