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