~ubuntu-branches/ubuntu/wily/alsaplayer/wily

« back to all changes in this revision

Viewing changes to scopes/monoscope/monoscope.c

  • Committer: Bazaar Package Importer
  • Author(s): Hubert Chathi
  • Date: 2007-10-10 15:33:10 UTC
  • mto: (9.2.5 sid)
  • mto: This revision was merged to the branch mainline in revision 15.
  • Revision ID: james.westby@ubuntu.com-20071010153310-h3holq75eu2cigb0
Tags: upstream-0.99.80~rc4
ImportĀ upstreamĀ versionĀ 0.99.80~rc4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  monoscope.h
2
 
 *  Copyright (C) 1998-2002 Andy Lo A Foe <andy@alsaplayer.org>
3
 
 *  Original code by Tinic Uro
4
 
 *
5
 
 *  This program is free software; you can redistribute it and/or modify
6
 
 *  it under the terms of the GNU General Public License as published by
7
 
 *  the Free Software Foundation; either version 2 of the License, or
8
 
 *  (at your option) any later version.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 
 *
19
 
 *  $Id: monoscope.c 1017 2003-11-09 13:28:30Z adnans $
20
 
 */ 
21
 
#include <pthread.h>
22
 
#include <dirent.h>
23
 
#include <sys/stat.h>
24
 
#include <gtk/gtk.h>
25
 
#include <sys/time.h>
26
 
#include <time.h>   
27
 
#include <math.h>
28
 
#include <stdio.h>
29
 
#include <unistd.h>
30
 
#include <malloc.h>
31
 
#include <string.h>
32
 
#include <assert.h>
33
 
#include "scope_config.h"
34
 
#include "prefs.h"
35
 
#include "alsaplayer_convolve.h"
36
 
#include "alsaplayer_error.h"
37
 
 
38
 
short newEq[CONVOLVE_BIG];      /* latest block of 512 samples. */
39
 
static short copyEq[CONVOLVE_BIG];
40
 
int avgEq[CONVOLVE_SMALL];      /* a running average of the last few. */
41
 
int avgMax;                     /* running average of max sample. */
42
 
 
43
 
static GtkWidget *area = NULL;
44
 
static GtkWidget *scope_win = NULL;
45
 
static GdkRgbCmap *color_map = NULL;
46
 
static int ready_state = 0;
47
 
static pthread_t monoscope_thread;
48
 
static pthread_mutex_t monoscope_mutex;
49
 
static pthread_mutex_t update_mutex;
50
 
static int is_init = 0;
51
 
static int running = 0;
52
 
static convolve_state *state = NULL;
53
 
 
54
 
static void monoscope_hide(void);
55
 
static int monoscope_running(void);
56
 
 
57
 
static const int default_colors[] = {
58
 
        10, 20, 30,
59
 
        230, 230, 230
60
 
};
61
 
 
62
 
void monoscope_set_data(void *audio_buffer, int size)
63
 
{
64
 
        int i;  
65
 
        short *sound = (short *)audio_buffer;
66
 
 
67
 
        if (pthread_mutex_trylock(&update_mutex) != 0) {
68
 
                /* alsaplayer_error("missing an update"); */
69
 
                return;
70
 
        }       
71
 
        if (!sound) {
72
 
                memset(&newEq, 0, sizeof(newEq));
73
 
                pthread_mutex_unlock(&update_mutex);
74
 
                return;
75
 
        }       
76
 
        if (running && size >= CONVOLVE_BIG) {
77
 
                short * newset = newEq;
78
 
                int skip = (size / (CONVOLVE_BIG * 2)) * 2;
79
 
                for (i = 0; i < CONVOLVE_BIG; i++) {
80
 
                        *newset++ = (((int) sound[0]) + (int) sound[1]) >> 1;
81
 
                        sound += skip;
82
 
                }
83
 
        }
84
 
        pthread_mutex_unlock(&update_mutex);
85
 
}
86
 
 
87
 
 
88
 
void the_monoscope()
89
 
{
90
 
        int foo;
91
 
        int bar;  
92
 
        int i, h;
93
 
        guchar bits[ 257 * 129];
94
 
        guchar *loc;
95
 
 
96
 
        running = 1;
97
 
 
98
 
        while (running) {
99
 
                int factor;
100
 
                int val;
101
 
                int max = 1;
102
 
                short * thisEq;
103
 
                pthread_mutex_lock(&update_mutex);
104
 
                memcpy (copyEq, newEq, sizeof (short) * CONVOLVE_BIG);
105
 
                thisEq = copyEq;
106
 
#if 1                                   
107
 
                val = convolve_match (avgEq, copyEq, state);
108
 
                thisEq += val;
109
 
#endif  
110
 
                pthread_mutex_unlock(&update_mutex);
111
 
                memset(bits, 0, 256 * 128);
112
 
                for (i=0; i < 256; i++) {
113
 
                        foo = thisEq[i] + (avgEq[i] >> 1);
114
 
                        avgEq[i] = foo;
115
 
                        if (foo < 0)
116
 
                                foo = -foo;
117
 
                        if (foo > max)
118
 
                                max = foo;
119
 
                }
120
 
                avgMax += max - (avgMax >> 8);
121
 
                if (avgMax < max)
122
 
                        avgMax = max; /* Avoid overflow */
123
 
                factor = 0x7fffffff / avgMax;
124
 
                /* Keep the scaling sensible. */
125
 
                if (factor > (1 << 18))
126
 
                        factor = 1 << 18;
127
 
                if (factor < (1 << 8))
128
 
                        factor = 1 << 8;
129
 
                for (i=0; i < 256; i++) {
130
 
                        foo = avgEq[i] * factor;
131
 
                        foo >>= 18;
132
 
                        if (foo > 63)
133
 
                                foo = 63;
134
 
                        if (foo < -64)
135
 
                                foo = -64;
136
 
                        val = (i + ((foo+64) << 8));
137
 
                        bar = val;
138
 
                        if ((bar > 0) && (bar < (256 * 128))) {
139
 
                                loc = bits + bar;
140
 
                                if (foo < 0) {
141
 
                                        for (h = 0; h <= (-foo); h++) {
142
 
                                                *loc = h;
143
 
                                                loc+=256; 
144
 
                                        }
145
 
                                } else {
146
 
                                        for (h = 0; h <= foo; h++) {
147
 
                                                *loc = h;
148
 
                                                loc-=256;
149
 
                                        }
150
 
                                }
151
 
                        }
152
 
                }
153
 
                for (i=16;i < 128; i+=16) {
154
 
                        for (h = 0; h < 256; h+=2) {
155
 
                                bits[(i << 8) + h] = 63;
156
 
                                if (i == 64)
157
 
                                        bits[(i << 8) + h + 1] = 63;
158
 
                        }
159
 
                }
160
 
                for (i = 16; i < 256; i+=16) {
161
 
                        for (h = 0; h < 128; h+=2) {
162
 
                                bits[i + (h << 8)] = 63;
163
 
                        }
164
 
                }
165
 
                GDK_THREADS_ENTER();
166
 
                gdk_draw_indexed_image(area->window,area->style->white_gc,
167
 
                                0, 0, 256, 128, GDK_RGB_DITHER_NONE, bits, 256, color_map);
168
 
                gdk_flush();
169
 
                GDK_THREADS_LEAVE();
170
 
                dosleep(SCOPE_SLEEP);
171
 
        }
172
 
 
173
 
        GDK_THREADS_ENTER();
174
 
        monoscope_hide();
175
 
        gdk_flush();
176
 
        GDK_THREADS_LEAVE();
177
 
}
178
 
 
179
 
 
180
 
static void test_cb(GtkWidget *widget, gpointer data)
181
 
{
182
 
        printf("Woah!\n");
183
 
}
184
 
 
185
 
 
186
 
void stop_monoscope(void);
187
 
 
188
 
static gboolean close_monoscope_window(GtkWidget *widget, GdkEvent *event, gpointer data)
189
 
{
190
 
        GDK_THREADS_LEAVE();            
191
 
        stop_monoscope();
192
 
        GDK_THREADS_ENTER();
193
 
 
194
 
        return TRUE;
195
 
}
196
 
 
197
 
 
198
 
GtkWidget *init_monoscope_window(void)
199
 
{
200
 
        GtkWidget *monoscope_win;
201
 
        GdkColor color;
202
 
        guint32 colors[65];
203
 
        int i;
204
 
 
205
 
        pthread_mutex_init(&monoscope_mutex, NULL);
206
 
        pthread_mutex_init(&update_mutex, NULL);
207
 
 
208
 
        monoscope_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
209
 
        gtk_window_set_title(GTK_WINDOW(monoscope_win), "Monoscope");
210
 
        gtk_widget_set_usize(monoscope_win, 256,128);
211
 
        gtk_window_set_wmclass (GTK_WINDOW(monoscope_win), "Monoscope", "AlsaPlayer");
212
 
        gtk_window_set_policy (GTK_WINDOW (monoscope_win), FALSE, FALSE, FALSE);
213
 
 
214
 
        gtk_widget_realize(monoscope_win);
215
 
 
216
 
        color.red = SCOPE_BG_RED << 8;
217
 
        color.blue = SCOPE_BG_BLUE << 8;
218
 
        color.green = SCOPE_BG_GREEN << 8;
219
 
        gdk_color_alloc(gdk_colormap_get_system(), &color);
220
 
 
221
 
        colors[0] = 0;
222
 
        for (i = 1; i < 32; i++) {
223
 
                colors[i] = (i*8 << 16) +(255 << 8);
224
 
                colors[i+31] = (255 << 16) + (((31 - i) * 8) << 8);
225
 
        }
226
 
        colors[63] = (40 << 16) + (75 << 8);
227
 
        color_map = gdk_rgb_cmap_new(colors, 64);
228
 
        area = gtk_drawing_area_new();
229
 
        gtk_container_add(GTK_CONTAINER(monoscope_win), area);
230
 
        gtk_widget_realize(area);
231
 
        gdk_window_set_background(area->window, &color);
232
 
 
233
 
        gtk_widget_show(area);
234
 
        gtk_widget_show(monoscope_win);
235
 
 
236
 
        /* Signals */
237
 
 
238
 
        gtk_signal_connect(GTK_OBJECT(monoscope_win), "delete_event",
239
 
                        GTK_SIGNAL_FUNC(close_monoscope_window), monoscope_win);
240
 
 
241
 
 
242
 
        ready_state = 1;
243
 
 
244
 
        return monoscope_win;
245
 
}
246
 
 
247
 
 
248
 
void monoscope_hide(void)
249
 
{
250
 
        gint x, y;
251
 
 
252
 
        if (scope_win) {
253
 
                gdk_window_get_root_origin(scope_win->window, &x, &y);
254
 
                gtk_widget_hide(scope_win);
255
 
                gtk_widget_set_uposition(scope_win, x, y);
256
 
        } else {
257
 
                printf("Tried to hide destroyed widget!\n");
258
 
        }       
259
 
}
260
 
 
261
 
 
262
 
void stop_monoscope(void)
263
 
{
264
 
        if (running) {
265
 
                running = 0;
266
 
                pthread_join(monoscope_thread, NULL);
267
 
        }       
268
 
}
269
 
 
270
 
 
271
 
void run_monoscope(void *data)
272
 
{
273
 
        nice(SCOPE_NICE); /* Be nice to most processes */
274
 
 
275
 
        the_monoscope();
276
 
 
277
 
        pthread_mutex_unlock(&monoscope_mutex);
278
 
        pthread_exit(NULL);
279
 
}
280
 
 
281
 
 
282
 
void start_monoscope(void)
283
 
{
284
 
        if (!is_init) {
285
 
                is_init = 1;
286
 
                scope_win = init_monoscope_window();
287
 
        }
288
 
        if (pthread_mutex_trylock(&monoscope_mutex) != 0) {
289
 
                printf("monoscope already running\n");
290
 
                return;
291
 
        }
292
 
        gtk_widget_show(scope_win);
293
 
        pthread_create(&monoscope_thread, NULL, (void * (*)(void *))run_monoscope, NULL);
294
 
}
295
 
 
296
 
 
297
 
static int init_monoscope(void *arg)
298
 
{
299
 
        state = convolve_init();
300
 
        if(!state) return 0;
301
 
 
302
 
        /* FIXME - Need to call convolve_close(state); at some point
303
 
         * if this is going to become a proper plugin. */
304
 
 
305
 
        if (prefs_get_bool(ap_prefs, "monoscope", "active", 0))
306
 
                start_monoscope();
307
 
 
308
 
        return 1;
309
 
}
310
 
 
311
 
static void shutdown_monoscope(void)
312
 
{
313
 
        prefs_set_bool(ap_prefs, "monoscope", "active", monoscope_running());
314
 
 
315
 
        if (monoscope_running())
316
 
                stop_monoscope();
317
 
        /*      
318
 
                if (state)
319
 
                */                                              
320
 
}
321
 
 
322
 
static int monoscope_running(void)
323
 
{
324
 
        return running;
325
 
}
326
 
 
327
 
scope_plugin monoscope_plugin = {
328
 
        SCOPE_PLUGIN_VERSION,
329
 
        "Monoscope",
330
 
        "Andy Lo A Foe",
331
 
        NULL,
332
 
        init_monoscope,
333
 
        start_monoscope,
334
 
        monoscope_running,
335
 
        stop_monoscope,
336
 
        shutdown_monoscope,
337
 
        monoscope_set_data,
338
 
        NULL
339
 
};
340
 
 
341
 
 
342
 
scope_plugin *scope_plugin_info(void)
343
 
{
344
 
        return &monoscope_plugin;
345
 
}