1 /*
2  * Copyright (C) 2002 2003 2004 2005 2006 2008 2010 2012, 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 
22 #ifndef DATAFORMAT_H_INCLUDED
23 #define DATAFORMAT_H_INCLUDED
24 
25 #include <gtk/gtk.h>
26 
27 /* struct describing the sample format. */
28 
29 #define DATAFORMAT_PCM   0 /* Linear PCM */
30 #define DATAFORMAT_FLOAT 1 /* Floating-point (float or double array) */
31 
32 typedef struct {
33 
34      int type;                   /* DATAFORMAT_PCM or DATAFORMAT_FLOAT */
35 
36      guint32 samplerate;         /* Samples/sec */
37      unsigned samplesize;           /* bytes (PCM: 1,2,3 or 4,
38 				  * float: sizeof(gfloat) or sizeof(gdouble))*/
39      int packing;               /* For non-packed 24-in-32 samples,
40 				 * set samplesize to 4 and packing to 1 (data in
41 				 * MSB) or 2 (data in LSB)
42 				 * For other types, this should be 0 */
43      int channels;              /* Number of channels (1-8) */
44      int samplebytes;           /* should always be samplesize*channels */
45 
46      /* For DATAFORMAT_PCM only: */
47      gboolean sign;              /* TRUE=signed, FALSE=unsigned */
48      gboolean bigendian;         /* TRUE=big endian, FALSE=little endian */
49 
50 } Dataformat;
51 
52 extern Dataformat dataformat_sample_t;
53 extern Dataformat dataformat_single;
54 
55 #define CONVERT_MODE_BIASED    0
56 #define CONVERT_MODE_NOOFFS    1
57 #define CONVERT_MODE_MAX       1
58 
59 extern gint sample_convert_mode;
60 
61 extern gboolean ieee_le_compatible,ieee_be_compatible;
62 
63 #define FORMAT_IS_SAMPLET(fmtp) ((fmtp)->type == DATAFORMAT_FLOAT && (fmtp)->samplesize == sizeof(sample_t))
64 
65 void floating_point_check(void);
66 
67 /* Returns TRUE if the two formats are equal */
68 
69 gboolean dataformat_equal(Dataformat *f1, Dataformat *f2);
70 
71 /* Returns TRUE if the two formats are equal but doesn't care for sample rate
72  * or channels */
73 gboolean dataformat_samples_equal(Dataformat *f1, Dataformat *f2);
74 
75 /* Returns TRUE if there was a format stored. */
76 gboolean dataformat_get_from_inifile(gchar *ini_prefix, gboolean full,
77 				     Dataformat *result);
78 void dataformat_save_to_inifile(gchar *ini_prefix, Dataformat *format,
79 				gboolean full);
80 
81 
82 const gchar *sampletype_name(Dataformat *fmt);
83 
84 
85 /* -------------------
86  * CONVERSION ROUTINES
87  * ------------------- */
88 
89 #ifdef USE_DOUBLE_SAMPLES
90 
91 typedef gdouble sample_t;
92 #define sf_readf_sample_t sf_readf_double
93 #define sf_writef_sample_t sf_writef_double
94 
95 #else
96 
97 typedef gfloat sample_t;
98 #define sf_readf_sample_t sf_readf_float
99 #define sf_writef_sample_t sf_writef_float
100 
101 #endif
102 
103 #define DITHER_NONE       0
104 #define DITHER_MINIMAL    1
105 #define DITHER_MAX        1
106 /* This constant can be used to indicate that dithering should not
107  * be necessary. If this is given when an FP->PCM conversion is done,
108  * the program will halt. */
109 #define DITHER_UNSPEC    -1
110 
111 /* These convert one or many samples between pcm formats and sample_t
112  * NOTE: These convert SINGLE-CHANNEL samples so you have to multiply the
113  * count with the number of channels if you want to read full samples.
114  * NOTE 2: These routines assumes the data to be in host endian order.
115  */
116 
117 #define maximum_float_value(x) (1.0)
118 sample_t minimum_float_value(Dataformat *x);
119 
120 void convert_array(void *indata, Dataformat *indata_format,
121 		   void *outdata, Dataformat *outdata_format,
122 		   guint count, int dither_mode, off_t *clipcount);
123 
124 void apply_convert_factor(Dataformat *infmt, Dataformat *outfmt,
125 			  sample_t *buffer, guint count);
126 
127 gint unnormalized_count(sample_t *buf, gint buflen, Dataformat *target);
128 
129 void conversion_selftest(void);
130 void conversion_performance_test(void);
131 
132 
133 #endif
134