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