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