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 "cache.h"
28
29 static sqlite3 *db;
30
31 void
waveform_db_open(char * path,int size)32 waveform_db_open (char* path, int size)
33 {
34 int rc;
35
36 sqlite3_close(db);
37 sprintf (path + size, "wavecache.db");
38 rc = sqlite3_open(path, &db);
39 if (rc) {
40 fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
41 sqlite3_close(db);
42 return;
43 }
44 }
45
46 void
waveform_db_close()47 waveform_db_close ()
48 {
49 sqlite3_close(db);
50 }
51
52 void
waveform_db_init(char const * fname)53 waveform_db_init (char const *fname)
54 {
55 char *zErrMsg = 0;
56 int rc;
57
58 char *query = "CREATE TABLE IF NOT EXISTS wave ( path TEXT PRIMARY KEY NOT NULL, channels INTEGER NOT NULL, compression INTEGER, data BLOB)";
59 rc = sqlite3_exec(db, query, NULL, 0, &zErrMsg);
60 if (rc != SQLITE_OK) {
61 fprintf(stderr, "SQL error: %s\n", zErrMsg);
62 }
63 sqlite3_free(zErrMsg);
64 }
65
66 int
waveform_db_cached(char const * fname)67 waveform_db_cached (char const *fname)
68 {
69 int rc;
70 sqlite3_stmt* p = 0;
71
72 char* query = sqlite3_mprintf ("SELECT * FROM wave WHERE path = '%q'", fname);
73 rc = sqlite3_prepare_v2 (db, query, strlen(query), &p, NULL);
74 if (rc != SQLITE_OK) {
75 fprintf(stderr, "cached_perpare: SQL error: %d\n", rc);
76 }
77 rc = sqlite3_step (p);
78 if (rc == SQLITE_ROW) {
79 sqlite3_finalize (p);
80 return 1;
81 }
82 sqlite3_finalize (p);
83 return 0;
84 }
85
86 int
waveform_db_delete(char const * fname)87 waveform_db_delete (char const *fname)
88 {
89 int rc;
90 sqlite3_stmt* p = 0;
91
92 char* query = sqlite3_mprintf ("DELETE FROM wave WHERE path = '%q'", fname);
93 rc = sqlite3_prepare_v2 (db, query, strlen(query), &p, NULL);
94 if (rc != SQLITE_OK) {
95 fprintf(stderr, "delete_perpare: SQL error: %d\n", rc);
96 }
97 rc = sqlite3_step (p);
98 if (rc != SQLITE_DONE) {
99 fprintf(stderr, "delete_exec: SQL error: %d\n", rc);
100 }
101 sqlite3_finalize (p);
102 return 1;
103 }
104
105 int
waveform_db_read(char const * fname,short * buffer,int buffer_len,int * channels)106 waveform_db_read (char const *fname, short *buffer, int buffer_len, int *channels)
107 {
108 int rc;
109 sqlite3_stmt* p = 0;
110
111 char* query = sqlite3_mprintf("SELECT channels, data FROM wave WHERE path = '%q'", fname);
112 rc = sqlite3_prepare_v2 (db, query, strlen(query), &p, NULL);
113 if (rc != SQLITE_OK) {
114 fprintf(stderr, "read_perpare: SQL error: %d\n", rc);
115 }
116 rc = sqlite3_step (p);
117 if (rc == SQLITE_DONE) {
118 sqlite3_finalize (p);
119 return 0;
120 }
121 else if (rc != SQLITE_ROW) {
122 fprintf(stderr, "read_exec: SQL error: %d\n", rc);
123 sqlite3_finalize (p);
124 return 0;
125 }
126
127 *channels = sqlite3_column_int (p,0);
128 short *data = (short *)sqlite3_column_blob (p,1);
129
130 int bytes = sqlite3_column_bytes (p,1);
131 if (bytes > buffer_len * sizeof(short)) {
132 bytes = buffer_len;
133 }
134 memcpy (buffer,data,bytes);
135
136 sqlite3_finalize (p);
137 return bytes / sizeof(short);
138 }
139
140 void
waveform_db_write(char const * fname,short * buffer,int buffer_len,int channels,int compression)141 waveform_db_write (char const *fname, short *buffer, int buffer_len, int channels, int compression)
142 {
143 int rc;
144 sqlite3_stmt* p = 0;
145
146 char* query = "INSERT INTO wave (path, channels, compression, data) VALUES (?, ?, ?, ?);";
147 rc = sqlite3_prepare_v2 (db, query, strlen(query), &p, NULL);
148 if (rc != SQLITE_OK) {
149 fprintf(stderr, "write_perpare: SQL error: %d\n", rc);
150 }
151 rc = sqlite3_bind_text (p, 1, fname, -1, SQLITE_STATIC);
152 if (rc != SQLITE_OK) {
153 fprintf(stderr, "write_fname: SQL error: %d\n", rc);
154 }
155 rc = sqlite3_bind_int (p, 2, channels);
156 if (rc != SQLITE_OK) {
157 fprintf(stderr, "write_channels: SQL error: %d\n", rc);
158 }
159 rc = sqlite3_bind_int (p, 3, compression);
160 if (rc != SQLITE_OK) {
161 fprintf(stderr, "write_compression: SQL error: %d\n", rc);
162 }
163 rc = sqlite3_bind_blob (p, 4, buffer, buffer_len, SQLITE_STATIC);
164 if (rc != SQLITE_OK) {
165 fprintf(stderr, "write_data: SQL error: %d\n", rc);
166 }
167 rc = sqlite3_step (p);
168 if (rc != SQLITE_DONE) {
169 fprintf(stderr, "write_exec: SQL error: %d\n", rc);
170 }
171 sqlite3_finalize (p);
172 }
173