blob: 7f433a41c86c44bb3fb2861916797bd869cb6559 [file] [log] [blame]
Alexandre Lision7c6f4a62013-09-05 13:27:01 -04001/*
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
38static int short_checksum (SNDFILE * file, int start) ;
39static int int_checksum (SNDFILE * file, int start) ;
40static int float_checksum (SNDFILE * file, int start) ;
41
42int
43calc_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
70static union
71{ short s [1 << 16] ;
72 int i [1 << 15] ;
73 float f [1 << 15] ;
74} data ;
75
76static int
77short_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
90static int
91int_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
104static int
105float_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 (0x7FFFFFFF * data.f [k]) ;
112 }
113 while (count > 0) ;
114
115 return start ;
116} /* float_checksum */
117