cannam@125
|
1 /*
|
cannam@125
|
2 ** Copyright (C) 2005-2011 Erik de Castro Lopo
|
cannam@125
|
3 **
|
cannam@125
|
4 ** This program is free software; you can redistribute it and/or modify
|
cannam@125
|
5 ** it under the terms of the GNU General Public License as published by
|
cannam@125
|
6 ** the Free Software Foundation; either version 2 of the License, or
|
cannam@125
|
7 ** (at your option) any later version.
|
cannam@125
|
8 **
|
cannam@125
|
9 ** This program is distributed in the hope that it will be useful,
|
cannam@125
|
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
cannam@125
|
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
cannam@125
|
12 ** GNU General Public License for more details.
|
cannam@125
|
13 **
|
cannam@125
|
14 ** You should have received a copy of the GNU General Public License
|
cannam@125
|
15 ** along with this program; if not, write to the Free Software
|
cannam@125
|
16 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
cannam@125
|
17 */
|
cannam@125
|
18
|
cannam@125
|
19 /*
|
cannam@125
|
20 ** A simple checksum for short, int and float data.
|
cannam@125
|
21 */
|
cannam@125
|
22
|
cannam@125
|
23 #include "sfconfig.h"
|
cannam@125
|
24
|
cannam@125
|
25 #include <stdio.h>
|
cannam@125
|
26 #include <stdlib.h>
|
cannam@125
|
27 #include <string.h>
|
cannam@125
|
28 #include <math.h>
|
cannam@125
|
29
|
cannam@125
|
30 #include <sndfile.h>
|
cannam@125
|
31
|
cannam@125
|
32 #include "regtest.h"
|
cannam@125
|
33
|
cannam@125
|
34 #define BIG_PRIME 999983
|
cannam@125
|
35
|
cannam@125
|
36 #define ARRAY_LEN(x) ((int) (sizeof (x)) / (sizeof ((x) [0])))
|
cannam@125
|
37
|
cannam@125
|
38 static int short_checksum (SNDFILE * file, int start) ;
|
cannam@125
|
39 static int int_checksum (SNDFILE * file, int start) ;
|
cannam@125
|
40 static int float_checksum (SNDFILE * file, int start) ;
|
cannam@125
|
41
|
cannam@125
|
42 int
|
cannam@125
|
43 calc_checksum (SNDFILE * file, const SF_INFO * info)
|
cannam@125
|
44 { int start ;
|
cannam@125
|
45
|
cannam@125
|
46 /* Seed the checksum with data from the SF_INFO struct. */
|
cannam@125
|
47 start = info->samplerate ;
|
cannam@125
|
48 start = start * BIG_PRIME + info->channels ;
|
cannam@125
|
49 start = start * BIG_PRIME + info->format ;
|
cannam@125
|
50
|
cannam@125
|
51 switch (info->format & SF_FORMAT_SUBMASK)
|
cannam@125
|
52 { case SF_FORMAT_FLOAT :
|
cannam@125
|
53 case SF_FORMAT_DOUBLE :
|
cannam@125
|
54 return float_checksum (file, start) ;
|
cannam@125
|
55
|
cannam@125
|
56 case SF_FORMAT_PCM_24 :
|
cannam@125
|
57 case SF_FORMAT_PCM_32 :
|
cannam@125
|
58 return int_checksum (file, start) ;
|
cannam@125
|
59
|
cannam@125
|
60 default :
|
cannam@125
|
61 return short_checksum (file, start) ;
|
cannam@125
|
62 } ;
|
cannam@125
|
63
|
cannam@125
|
64 return 0 ;
|
cannam@125
|
65 } /* calc_checksum */
|
cannam@125
|
66
|
cannam@125
|
67 /*------------------------------------------------------------------------------
|
cannam@125
|
68 */
|
cannam@125
|
69
|
cannam@125
|
70 static union
|
cannam@125
|
71 { short s [1 << 16] ;
|
cannam@125
|
72 int i [1 << 15] ;
|
cannam@125
|
73 float f [1 << 15] ;
|
cannam@125
|
74 } data ;
|
cannam@125
|
75
|
cannam@125
|
76 static int
|
cannam@125
|
77 short_checksum (SNDFILE * file, int start)
|
cannam@125
|
78 { int k, count ;
|
cannam@125
|
79
|
cannam@125
|
80 do
|
cannam@125
|
81 { count = (int) sf_read_short (file, data.s, ARRAY_LEN (data.s)) ;
|
cannam@125
|
82 for (k = 0 ; k < count ; k++)
|
cannam@125
|
83 start = start * BIG_PRIME + data.s [k] ;
|
cannam@125
|
84 }
|
cannam@125
|
85 while (count > 0) ;
|
cannam@125
|
86
|
cannam@125
|
87 return start ;
|
cannam@125
|
88 } /* short_checksum */
|
cannam@125
|
89
|
cannam@125
|
90 static int
|
cannam@125
|
91 int_checksum (SNDFILE * file, int start)
|
cannam@125
|
92 { int k, count ;
|
cannam@125
|
93
|
cannam@125
|
94 do
|
cannam@125
|
95 { count = (int) sf_read_int (file, data.i, ARRAY_LEN (data.i)) ;
|
cannam@125
|
96 for (k = 0 ; k < count ; k++)
|
cannam@125
|
97 start = start * BIG_PRIME + data.i [k] ;
|
cannam@125
|
98 }
|
cannam@125
|
99 while (count > 0) ;
|
cannam@125
|
100
|
cannam@125
|
101 return start ;
|
cannam@125
|
102 } /* int_checksum */
|
cannam@125
|
103
|
cannam@125
|
104 static int
|
cannam@125
|
105 float_checksum (SNDFILE * file, int start)
|
cannam@125
|
106 { int k, count ;
|
cannam@125
|
107
|
cannam@125
|
108 do
|
cannam@125
|
109 { count = (int) sf_read_float (file, data.f, ARRAY_LEN (data.f)) ;
|
cannam@125
|
110 for (k = 0 ; k < count ; k++)
|
cannam@125
|
111 start = start * BIG_PRIME + lrintf (0x7FFFFFFF * data.f [k]) ;
|
cannam@125
|
112 }
|
cannam@125
|
113 while (count > 0) ;
|
cannam@125
|
114
|
cannam@125
|
115 return start ;
|
cannam@125
|
116 } /* float_checksum */
|
cannam@125
|
117
|