1 /*
2 Waveform seekbar plugin for the DeaDBeeF audio player
3
4 Copyright (C) 2014 Christian Boxdörfer <christian.boxdoerfer@posteo.de>
5
6 Based on sndfile-tools waveform by Erik de Castro Lopo.
7 waveform.c - v1.04
8 Copyright (C) 2007-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
9 Copyright (C) 2012 Robin Gareus <robin@gareus.org>
10 Copyright (C) 2013 driedfruit <driedfruit@mindloop.net>
11
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 as published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 */
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <assert.h>
32 #include <math.h>
33 #include <fcntl.h>
34
35 #include <deadbeef/deadbeef.h>
36
37 #include "waveform.h"
38 #include "utils.h"
39
40 typedef struct cache_query_s
41 {
42 char *fname;
43 struct cache_query_s *next;
44 } cache_query_t;
45
46 static uintptr_t mutex = 0;
47 static cache_query_t *queue;
48 static cache_query_t *queue_tail;
49
50 int
check_dir(const char * dir,mode_t mode)51 check_dir (const char *dir, mode_t mode)
52 {
53 char *tmp = strdup (dir);
54 char *slash = tmp;
55 struct stat stat_buf;
56 do
57 {
58 slash = strstr (slash+1, "/");
59 if (slash)
60 *slash = 0;
61 if (-1 == stat (tmp, &stat_buf))
62 {
63 if (0 != mkdir (tmp, mode))
64 {
65 free (tmp);
66 return 0;
67 }
68 }
69 if (slash)
70 *slash = '/';
71 } while (slash);
72 free (tmp);
73 return 1;
74 }
75
76 int
queue_add(const char * fname)77 queue_add (const char *fname)
78 {
79 if (!mutex) {
80 mutex = deadbeef->mutex_create ();
81 }
82 deadbeef->mutex_lock (mutex);
83 for (cache_query_t *q = queue; q; q = q->next) {
84 if (!strcmp (fname, q->fname)) {
85 // already queued
86 trace ("waveform: already queued. (%s)\n",fname);
87 deadbeef->mutex_unlock (mutex);
88 return 0;
89 }
90 }
91 cache_query_t *q = malloc (sizeof (cache_query_t));
92 memset (q, 0, sizeof (cache_query_t));
93 q->fname = strdup (fname);
94 if (queue_tail) {
95 queue_tail->next = q;
96 queue_tail = q;
97 }
98 else {
99 queue = queue_tail = q;
100 }
101 trace ("waveform: queued. (%s)\n",fname);
102 deadbeef->mutex_unlock (mutex);
103 return 1;
104 }
105
106 void
queue_pop(const char * fname)107 queue_pop (const char *fname)
108 {
109 deadbeef->mutex_lock (mutex);
110 cache_query_t *next = NULL;
111 for (cache_query_t *q = queue; q; q = q->next) {
112 if (!strcmp (fname, q->fname)) {
113 next = q->next;
114 if (q->fname) {
115 trace ("waveform: removed from queue. (%s)\n",q->fname);
116 free (q->fname);
117 }
118 free (q);
119 break;
120 }
121 }
122 queue = next;
123 if (!queue) {
124 queue_tail = NULL;
125 }
126 deadbeef->mutex_unlock (mutex);
127 }
128