1 /* 2 * Copyright (C) 2002 2003 2004 2005 2006 2009, Magnus Hjorth 3 * 4 * This file is part of mhWaveEdit. 5 * 6 * mhWaveEdit is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * mhWaveEdit is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with mhWaveEdit; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 /* Datasource object represent a source of PCM data. */ 22 23 /* This is (and should be) mainly used by chunk.c */ 24 25 #ifndef DATASOURCE_H_INCLUDED 26 #define DATASOURCE_H_INCLUDED 27 28 #include <gtk/gtk.h> 29 #include "gtkfiles.h" 30 #include "statusbar.h" 31 #include "dataformat.h" 32 33 #define DATASOURCE(obj) GTK_CHECK_CAST(obj,datasource_get_type(),Datasource) 34 #define DATASOURCE_CLASS(klass) GTK_CHECK_CLASS_CAST(klass,datasource_get_type(),DatasourceClass) 35 #define IS_DATASOURCE(obj) GTK_CHECK_TYPE(obj,datasource_get_type()) 36 37 #ifndef HAVE_LIBSNDFILE 38 #define SNDFILE void 39 #else 40 #include <sndfile.h> 41 #endif 42 43 44 45 /* Values for the type member of the Datasource struct. Determines how to 46 * actually get the data. */ 47 48 /* Data stored directly in memory */ 49 #define DATASOURCE_REAL 0 50 /* The data is stored in a (read-only) file. */ 51 #define DATASOURCE_VIRTUAL 1 52 /* Data stored in a file that will be removed when the Datasource is 53 * destroyed. */ 54 #define DATASOURCE_TEMPFILE 2 55 /* Silence (duh) */ 56 #define DATASOURCE_SILENCE 3 57 /* The data is read using libSndfile */ 58 #define DATASOURCE_SNDFILE 4 59 /* Same as DATASOURCE_SNDFILE but will be removed when the chunk is 60 * destroyed. */ 61 #define DATASOURCE_SNDFILE_TEMPORARY 5 62 /* Reference to another Datasource. Has the same format. 63 * All requests will simply be passed on to the referred datasource. */ 64 #define DATASOURCE_REF 6 65 /* Clone of another PCM Datasource. The Clone can have different 66 * format than the original. This is used for mending files with 67 * broken headers..*/ 68 #define DATASOURCE_CLONE 7 69 /* Byteswapped clone of PCM datsource.*/ 70 #define DATASOURCE_BYTESWAP 8 71 /* Autoconverting datasource. This Datasource must have the 72 * same number of channels as referred Datasource. 73 * Floating point requests will be passed on to the referred 74 * Datasource, PCM requests will be sent as FP requests and then 75 * automatically converted from the FP data. */ 76 #define DATASOURCE_CONVERT 9 77 /* Clone of other datasource with channels rearranged. 78 * Has the sample sample format and rate, but can have different number of 79 * channels */ 80 #define DATASOURCE_CHANMAP 10 81 82 struct temparea { 83 gpointer ptr; 84 int size; 85 }; 86 87 struct _Datasource; 88 89 struct _Datasource { 90 91 GtkObject object; 92 93 gint type; 94 95 Dataformat format; 96 97 off_t length; /*�Number of samples */ 98 off_t bytes; /* Number of bytes in file. */ 99 100 guint opencount; /* To keep track of nested open/close calls */ 101 102 /* Temporary areas for internal use */ 103 struct temparea read_temparea,readfp_temparea; 104 105 gint tag; /* Extra field... */ 106 107 /* Type-specific data */ 108 union { 109 110 /* --- DATASOURCE_TEMPFILE and DATASOURCE_VIRTUAL --- */ 111 struct { 112 char *filename; 113 off_t offset; /* Offset of data in file (bytes) */ 114 EFILE *handle; 115 off_t pos; /* Current position in file (bytes) */ 116 } virtual; 117 118 /* --- DATASOURCE_REAL ---*/ 119 char *real; /* Pointer into the memory buffer with the sound data. */ 120 121 122 /* --- DATASOURCE_SNDFILE and DATASOURCE_SNDFILE_TEMPORARY --- */ 123 struct { 124 char *filename; 125 gboolean raw_readable; 126 SNDFILE *handle; 127 off_t pos; /* Current position in file (samples) */ 128 } sndfile; 129 130 /* DATASOURCE_CLONE, DATASOURCE_REF, DATASOURCE_CONVERT and 131 * DATASOURCE_BYTESWAP */ 132 struct _Datasource *clone; 133 134 /* DATASOURCE_CHANMAP */ 135 struct { 136 struct _Datasource *clone; 137 int *map; 138 } chanmap; 139 140 } data; 141 }; 142 143 typedef struct _Datasource Datasource; 144 145 typedef struct { 146 GtkObjectClass klass; 147 } DatasourceClass; 148 149 150 GtkType datasource_get_type(void); 151 152 /* ------------ 153 * CONSTRUCTORS 154 * ------------ */ 155 156 157 /* Create data source from another Datasource object. The format of the data 158 * will be that of the format argument, regardless of what the other source 159 * specifies. This makes it possible to override the format when you know it is 160 * wrong. 161 * source must be a PCM datasource 162 */ 163 Datasource *datasource_clone_df(Datasource *source, Dataformat *format); 164 165 166 /* Returns a byte-swapped clone of another Datasource. 167 * source must be a PCM datasource */ 168 Datasource *datasource_byteswap(Datasource *source); 169 170 171 /* Returns a Datasource containing the same data as source, but converted to 172 * new_format. If source is floating-point, the original data will still 173 * be returned when the read_array_fp function is used. source and new must 174 * have the same number of channels and samplerate. */ 175 Datasource *datasource_convert(Datasource *source, Dataformat *new_format); 176 177 /* Returns a Datasource containing the same data as source, but with its 178 * channels remapped. 179 * n_channels is the number of channels in the new source. 180 * map should point to an array length n_channels mapping to source channels */ 181 Datasource *datasource_channel_map(Datasource *source, int n_channels, 182 int *map); 183 184 /* Create a data source from a memory buffer of data. The buffer will be 185 * g_free:d when the data source is destroyed and the data should not be 186 * modified by the caller any more after this call. 187 */ 188 Datasource *datasource_new_from_data(void *data, Dataformat *format, 189 guint32 size); 190 191 192 /* Create a new datasource containing silence with a certain format and the 193 * specified number of samples 194 */ 195 Datasource *datasource_new_silent(Dataformat *format, off_t samples); 196 197 198 199 /* --------------------- 200 * DATA ACCESS FUNCTIONS 201 * --------------------- */ 202 203 204 205 /* Open the data source. Must be called before any of the other data access 206 * functions. May be called more than one time for the same Datasource. 207 */ 208 209 gboolean datasource_open(Datasource *source); 210 211 212 213 /* Close the data source. Must be called once for each call to 214 * datasource_open. 215 */ 216 217 void datasource_close(Datasource *source); 218 219 220 221 /* Read one/many PCM/float sample from the Data source into the buffer. The 222 * sample data will always be in host endian order. 223 */ 224 gboolean datasource_read(Datasource *source, off_t sampleno, gpointer buffer, 225 int dither_mode); 226 gboolean datasource_read_fp(Datasource *source, off_t sampleno, 227 sample_t *buffer, int dither_mode); 228 /* Returns number of bytes read (0 on error). If clipping != NULL and clipping 229 * conversion was performed, sets *clipping to TRUE. 230 */ 231 guint datasource_read_array(Datasource *source, off_t sampleno, 232 guint size, gpointer buffer, int dither_mode, 233 off_t *clipcount); 234 /* Returns number of (multi-channel) samples read (0 on error). */ 235 guint datasource_read_array_fp(Datasource *source, off_t sampleno, 236 guint samples, sample_t *buffer, 237 int dither_mode, off_t *clipcount); 238 239 240 241 242 243 244 /* ------- 245 * VARIOUS 246 * ------- */ 247 248 249 /* Returns the number of active Datasource objects */ 250 guint datasource_count(void); 251 252 253 254 /* This dumps the contents of the datasource into a file. You don't need 255 * to open the datasource when using this function. The StatusBar must 256 * already be in progress mode. 257 */ 258 259 gboolean datasource_dump(Datasource *ds, off_t position, off_t length, 260 EFILE *file, int dither_mode, StatusBar *bar, 261 off_t *clipcount); 262 263 264 /* This reads all the data of the datasource into a memory buffer and converts 265 * it into a memory datasource. 266 */ 267 268 gboolean datasource_realize(Datasource *ds, int dither_mode); 269 270 /* This function will unlink a file. If any of the Datasources depend on this 271 * file, the file will be moved or copied into a temporary file before the 272 * original name is unlinked. 273 */ 274 275 gboolean datasource_backup_unlink(gchar *filename); 276 277 /* Returns zero if reading the datasource does not cause clipping conversion. 278 * and the datasource contains normalized data. 279 * Returns non-zero if reading the datasource causes clipping conversion 280 * Returns 1 if the error can be solved by normalizing the Datasource 281 * Returns 2 if the error can not be solved in that way (very special cases) 282 * Returns <0 if an error or break occurred while checking 283 * The StatusBar must already be in progress mode. 284 */ 285 gint datasource_clip_check(Datasource *ds, StatusBar *bar); 286 287 #endif 288