1/* 2** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com> 3** 4** This program is free software; you can redistribute it and/or modify 5** it under the terms of the GNU Lesser General Public License as published by 6** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. 13** 14** You should have received a copy of the GNU Lesser General Public License 15** along with this program; if not, write to the Free Software 16** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17*/ 18 19 20#include "sfconfig.h" 21 22#include <stdio.h> 23#include <stdlib.h> 24 25#if HAVE_UNISTD_H 26#include <unistd.h> 27#else 28#include "sf_unistd.h" 29#endif 30 31#include <string.h> 32#include <errno.h> 33 34#include "common.h" 35 36typedef struct 37{ int le_float ; 38 int be_float ; 39 int le_int_24_32 ; 40 int be_int_24_32 ; 41} VOTE ; 42 43 44static void vote_for_format (VOTE * vote, const unsigned char * data, int datalen) ; 45 46int 47audio_detect (SF_PRIVATE * psf, AUDIO_DETECT *ad, const unsigned char * data, int datalen) 48{ VOTE vote ; 49 50 if (psf == NULL) 51 return 0 ; 52 53 if (ad == NULL || datalen < 256) 54 return 0 ; 55 56 vote_for_format (&vote, data, datalen) ; 57 58 psf_log_printf (psf, "audio_detect :\n" 59 " le_float : %d\n" 60 " be_float : %d\n" 61 " le_int_24_32 : %d\n" 62 " be_int_24_32 : %d\n", 63 vote.le_float, vote.be_float, vote.le_int_24_32, vote.be_int_24_32) ; 64 65 if (0) puts (psf->parselog.buf) ; 66 67 if (ad->endianness == SF_ENDIAN_LITTLE && vote.le_float > (3 * datalen) / 4) 68 { /* Almost certainly 32 bit floats. */ 69 return SF_FORMAT_FLOAT ; 70 } ; 71 72 if (ad->endianness == SF_ENDIAN_LITTLE && vote.le_int_24_32 > (3 * datalen) / 4) 73 { /* Almost certainly 24 bit data stored in 32 bit ints. */ 74 return SF_FORMAT_PCM_32 ; 75 } ; 76 77 return 0 ; 78} /* data_detect */ 79 80static void 81vote_for_format (VOTE * vote, const unsigned char * data, int datalen) 82{ 83 int k ; 84 85 memset (vote, 0, sizeof (VOTE)) ; 86 87 datalen -= datalen % 4 ; 88 89 for (k = 0 ; k < datalen ; k ++) 90 { if ((k % 4) == 0) 91 { if (data [k] == 0 && data [k + 1] != 0) 92 vote->le_int_24_32 += 4 ; 93 94 if (data [2] != 0 && data [3] == 0) 95 vote->le_int_24_32 += 4 ; 96 97 if (data [0] != 0 && data [3] > 0x43 && data [3] < 0x4B) 98 vote->le_float += 4 ; 99 100 if (data [3] != 0 && data [0] > 0x43 && data [0] < 0x4B) 101 vote->be_float += 4 ; 102 } ; 103 } ; 104 105 return ; 106} /* vote_for_format */ 107 108