14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------* 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * riff.c * 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Copyright 2007, 2008 Nuance Communciations, Inc. * 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the 'License'); * 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * you may not use this file except in compliance with the License. * 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * You may obtain a copy of the License at * 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 * 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software * 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * distributed under the License is distributed on an 'AS IS' BASIS, * 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * See the License for the specific language governing permissions and * 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * limitations under the License. * 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/ 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "plog.h" 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "riff.h" 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define MTAG NULL 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef struct ChunkContext_t 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char tag[4]; 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project long start; 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int length; 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectChunkContext; 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef enum 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FIND_RIFF, 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FIND_CHUNK, 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FIND_LIST 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} DescendType; 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint isLittleEndian() 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char b[4]; 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *(int *)b = 1; 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return (int)b[0]; 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* waveReadFunc 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * - converts data to an array of signed shorts 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * - fills in *length with the number of samples converted 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * - allocates memory for *samples 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * - returns GS_OK if conversion was successful or GS_ERROR and an error 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * message in res if not. If the conversion fails the function must free 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * all the memory it had allocated before returning. 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * On entry 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * wf - points to the WaveFormat structure that describes the data format 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * cb - data read from the RIFF file 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * data - descriptor for the "data" chunk 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef ESR_ReturnCode(waveReadFunc)(WaveFormat *wf, ChunkContext *data, 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cb, short **samples, int *length, int doSwap); 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode readPCMWave(WaveFormat *wf, ChunkContext *data, 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cb, short **samples, int *length, int doSwap); 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode readMulawWave(WaveFormat *wf, ChunkContext *data, 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cb, short **samples, int *length, int doSwap); 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode readAlawWave(WaveFormat *wf, ChunkContext *data, 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cb, short **samples, int *length, int doSwap); 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic struct 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int id; 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project waveReadFunc *func; 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectWaveCodecs[] = { 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project {WAVEFORMAT_PCM, readPCMWave}, 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project {WAVEFORMAT_MULAW, readMulawWave}, 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project {WAVEFORMAT_ALAW, readAlawWave}, 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project {0, 0}, 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project }; 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/************* FIXME: regroup all swap routines outahere; 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * ditto for audio conversion routines 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void swapInt(int *i) 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *a = (char *)i, t; 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project t = a[0]; 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project a[0] = a[3]; 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project a[3] = t; 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project t = a[1]; 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project a[1] = a[2]; 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project a[2] = t; 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void swapShort(short *s) 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *a = (char *)s, t; 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project t = a[0]; 1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project a[0] = a[1]; 1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project a[1] = t; 1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int swapConstInt(const int value) 1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int converted = value; 1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned char *cp = (unsigned char *) & converted; 1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *cp ^= *(cp + 3); 1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *(cp + 3) ^= *cp; 1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *cp ^= *(cp + 3); 1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *(cp + 1) ^= *(cp + 2); 1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *(cp + 2) ^= *(cp + 1); 1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *(cp + 1) ^= *(cp + 2); 1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return converted; 1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic short swapConstShort(const short value) 1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project short converted = value; 1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned char *cp = (unsigned char *) & converted; 1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned char tmp = *cp; 1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *cp = *(cp + 1); 1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *++cp = tmp; 1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return converted; 1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* len == number of bytes to swap 1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void short_byte_swap(short *buf, int len) 1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cp, *end, tmp; 1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project end = ((char *)buf) + (len << 1); 1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (cp = (char *)buf; cp < end; cp++) 1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project tmp = *cp; 1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *cp = *(cp + 1); 1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *++cp = tmp; 1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* len == number of bytes to swap 1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void int_byte_swap(int *buf, int len) 1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cp, *end; 1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project end = ((char *)buf) + (len << 2); 1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (cp = (char *)buf; cp < end; cp += 4) 1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *cp ^= *(cp + 3); 1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *(cp + 3) ^= *cp; 1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *cp ^= *(cp + 3); 1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *(cp + 1) ^= *(cp + 2); 1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *(cp + 2) ^= *(cp + 1); 1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *(cp + 1) ^= *(cp + 2); 1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void swapWaveFormat(WaveFormat *wf) 1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapShort(&wf->nFormatTag); 1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapShort(&wf->nChannels); 1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapInt(&wf->nSamplesPerSec); 1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapInt(&wf->nAvgBytesPerSec); 1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapShort(&wf->nBlockAlign); 1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapShort(&wf->wBitsPerSample); 1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //swapShort(&wf->cbSize); 1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int ulaw2linear(unsigned char ulawbyte) 1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static int exp_lut[8] = 1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 0, 132, 396, 924, 1980, 4092, 8316, 16764 1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project }; 1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int sign, exponent, mantissa, sample; 1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ulawbyte = ~ulawbyte; 1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sign = (ulawbyte & 0x80); 1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project exponent = (ulawbyte >> 4) & 0x07; 1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project mantissa = ulawbyte & 0x0F; 1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sample = exp_lut[exponent] + (mantissa << (exponent + 3)); 1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (sign != 0) sample = -sample; 1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return sample; 1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int alaw2linear(unsigned char alawbyte) 1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int sign, achord, astep, delta, sample; 1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned char alawcode; 1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static int exp_lut[8] = 1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1, 1, 2, 4, 8, 16, 32, 64 2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project }; 2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project alawcode = alawbyte ^ 0x55; 2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sign = (alawcode & 0x80); 2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project achord = (alawcode >> 4) & 0x07; 2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project astep = alawcode & 0x0F; 2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delta = ((achord == 0) ? 1 : 0); 2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sample = ((2 * astep + 33) * exp_lut[achord]) - 32 * delta; 2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (sign != 0) sample = -sample; 2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sample = sample * 8; 2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return sample; 2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* Converts PCM wave data 2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * cb: input :1 2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode readPCMWave(WaveFormat *wf, ChunkContext *data, 2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cb, short **samples, int *length, int doSwap) 2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i; 2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nChannels != 1) 2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,"PCM WAVE file contains more than one data channel", 2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_STATIC); 2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->wBitsPerSample != 16 && wf->wBitsPerSample != 8) 2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,GS_Spf(0,"%d bits per sample PCM format not supported", 2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //wf->wBitsPerSample),GS_VOLATILE); 2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *length = data->length * 8 / wf->wBitsPerSample; 2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *samples = MALLOC(*length * sizeof(short), MTAG); 2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->wBitsPerSample == 16) 2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(*samples, cb, *length*sizeof(short)); 2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) 2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0;i < *length;i++) swapShort(*samples + i); 2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0;i < *length;i++)(*samples)[i] = (short)((unsigned)(cb[i]) - 128) << 8; 2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* Converts CCITT u-law wave data 2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode readMulawWave(WaveFormat *wf, ChunkContext *data, 2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cb, short **samples, int *length, int doSwap) 2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i; 2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nChannels != 1) 2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,"u-law WAVE file contains more than one data channel", 2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_STATIC); 2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->wBitsPerSample != 8) 2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,GS_Spf(0,"%d bits per sample u-law format not supported", 2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //wf->wBitsPerSample),GS_VOLATILE); 2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *length = data->length; 2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *samples = MALLOC(*length * sizeof(short), MTAG); 2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0;i < *length;i++) 2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project (*samples)[i] = (short) ulaw2linear(cb[i]); 2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* Converts a-law wave data 2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode readAlawWave(WaveFormat *wf, ChunkContext *data, 2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cb, short **samples, int *length, int doSwap) 2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i; 2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nChannels != 1) 2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,"u-law WAVE file contains more than one data channel", 2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_STATIC); 2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->wBitsPerSample != 8) 2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,GS_Spf(0,"%d bits per sample u-law format not supported", 2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //wf->wBitsPerSample),GS_VOLATILE); 2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *length = data->length; 2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project samples = MALLOC(*length * sizeof(short), MTAG); 2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0;i < *length;i++)(*samples)[i] = alaw2linear(cb[i]); 2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* ------------------------------------------------------------------------- */ 2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* RIFF INTERFACE UTILS */ 3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid free_swiRiff(SwiRiffStruct *swichunk) 3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk->segs.num_tuples) 3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE(swichunk->segs.tuples); 3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->segs.num_tuples = 0; 3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk->kvals.num_pairs) 3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE(swichunk->kvals.kvpairs[0].key); 3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE(swichunk->kvals.kvpairs); 3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->kvals.num_pairs = 0; 3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectchar *getSwiRiffKVal(SwiRiffStruct *swichunk, char *key) 3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i; 3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0; i < swichunk->kvals.num_pairs; i++) 3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (! strcmp(swichunk->kvals.kvpairs[i].key, key)) 3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return swichunk->kvals.kvpairs[i].value; 3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return NULL; 3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* ------------------------------------------------------------------------- */ 3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int riffDescend(FILE *f, ChunkContext *c, ChunkContext *parent, DescendType t, int doSwap) 3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char form[4], tag[4]; 3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int len; 3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project long start, end; 3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project end = 0; 3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!parent) start = 0; 3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project start = parent->start; 3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project end = start + parent->length; 3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fseek(f, start, SEEK_SET) < 0) 3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,"seek failed",GS_STATIC); 3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project switch (t) 3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project case FIND_RIFF: 3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project while (1) 3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(form, 1, 4, f) != 4) break; 3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(&len, sizeof(int), 1, f) != 1) 3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) 3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapInt(&len); 3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (strncmp(form, "RIFF", 4)) 3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { /* skip this non-RIFF chunk */ 3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fseek(f, (long)len, SEEK_CUR) < 0) break; 3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project start += len + 8; 3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (end && start >= end) 3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,"RIFF form type not found",GS_STATIC); 3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project continue; 3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(tag, 1, 4, f) != 4) break; 3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!strncmp(tag, c->tag, 4)) 3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project c->start = start + 12; 3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project c->length = len - 4; 3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //if(feof(f)) GS_SetResult(res,"RIFF form type not found",GS_STATIC); 3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //else GS_SetResult(res,"Corrupt RIFF file",GS_STATIC); 3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project case FIND_CHUNK: 3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project while (1) 3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(tag, 1, 4, f) != 4) break; 3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(&len, sizeof(int), 1, f) != 1) 3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) 3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapInt(&len); 3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!strncmp(tag, c->tag, 4)) 3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project c->start = start + 8; 3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project c->length = len; 3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fseek(f, (long)len, SEEK_CUR) < 0) break; 3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project start += len + 8; 3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (end && start >= end) 4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,"RIFF chunk not found",GS_STATIC); 4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //if(feof(f)) GS_SetResult(res,"RIFF chunk not found",GS_STATIC); 4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //else GS_SetResult(res,"corrupt RIFF file",GS_STATIC); 4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project case FIND_LIST: 4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project while (1) 4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(form, 1, 4, f) != 4) break; 4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(&len, sizeof(int), 1, f) != 1) 4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) 4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapInt(&len); 4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (strncmp(form, "LIST", 4)) 4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { /* skip this non-LIST chunk */ 4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fseek(f, (long)len, SEEK_CUR) < 0) break; 4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project start += len + 8; 4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (end && start >= end) 4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,"RIFF form type not found",GS_STATIC); 4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project continue; 4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(tag, 1, 4, f) != 4) break; 4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!strncmp(tag, c->tag, 4)) 4304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project c->start = start + 12; 4324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project c->length = len - 4; 4334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 4344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //if(feof(f)) GS_SetResult(res,"RIFF form type not found",GS_STATIC); 4384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //else GS_SetResult(res,"Corrupt RIFF file",GS_STATIC); 4394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 4404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_AppendResult(res,"bad search flag",GS_STATIC); 4434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 4444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 4454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int riffAscend(FILE *f, ChunkContext *c) 4474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 4484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fseek(f, c->start + c->length, SEEK_SET) < 0) 4494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,"seek failed",GS_STATIC); 4514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 4524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 4544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 4554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic ESR_ReturnCode readSwiChunk(FILE *f, ChunkContext *parent, SwiRiffStruct *swichunk, int doSwap) 4584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 4594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ESR_ReturnCode rc = ESR_SUCCESS; 4604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ChunkContext chunk, list_chunk; 4614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int sub_length; 4624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->segs.num_tuples = 0; 4634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->kvals.num_pairs = 0; 4644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(chunk.tag, "swi ", 4); 4664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffDescend(f, &chunk, parent, FIND_LIST, doSwap) == ESR_SUCCESS) 4674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* is it as "swi " list? */ 4694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(list_chunk.tag, "segs", 4); 4704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffDescend(f, &list_chunk, &chunk, FIND_CHUNK, doSwap) == ESR_SUCCESS) 4714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fread(&swichunk->segs.num_tuples, 1, sizeof(int), f); 4734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) swapInt(&swichunk->segs.num_tuples); 4744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sub_length = list_chunk.length - sizeof(int); 4764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (sub_length) 4774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->segs.tuples = MALLOC(sub_length, MTAG); 4794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!swichunk->segs.tuples) 4804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->segs.num_tuples = 0; /* so that the free routine will work */ 4824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_OUT_OF_MEMORY; 4834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (fread(swichunk->segs.tuples, 1, sub_length, f) != (size_t)sub_length) 4854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_FATAL_ERROR; 4874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (rc != ESR_SUCCESS) 4894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project goto swichunk_cleanup; 4904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 4934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->segs.tuples = NULL; 4944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(list_chunk.tag, "kvs ", 4); 4964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* start searching from after "swi" */ 4974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffDescend(f, &list_chunk, &chunk, FIND_CHUNK, doSwap) == ESR_SUCCESS) 4984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i, num_pairs; 5004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fread(&num_pairs, 1, sizeof(int), f); 5024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) swapInt(&num_pairs); 5034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->kvals.num_pairs = num_pairs; 5044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sub_length = list_chunk.length - sizeof(int); 5064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (sub_length) 5074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 5084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *kvpair_buf = NULL; 5094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project RiffKVPair *pairs; 5104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->kvals.kvpairs = (RiffKVPair *)CALLOC(num_pairs, sizeof(RiffKVPair), MTAG); 5124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kvpair_buf = CALLOC(sub_length, sizeof(char), MTAG); 5134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!swichunk->kvals.kvpairs || !kvpair_buf) 5144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 5154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (kvpair_buf) FREE(kvpair_buf); 5164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk->kvals.kvpairs) FREE(swichunk->kvals.kvpairs); 5174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->kvals.num_pairs = 0; 5184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_OUT_OF_MEMORY; 5194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project goto swichunk_cleanup; 5204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->kvals.kvpairs[0].key = kvpair_buf; 5234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(kvpair_buf, 1, sub_length, f) != (size_t)sub_length) 5244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 5254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_FATAL_ERROR; 5264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project goto swichunk_cleanup; 5274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (pairs = swichunk->kvals.kvpairs, i = 0; i < swichunk->kvals.num_pairs; i++, pairs++) 5294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 5304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pairs->key = kvpair_buf; 5314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kvpair_buf += strlen(kvpair_buf) + 1; 5324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pairs->value = kvpair_buf; 5334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kvpair_buf += strlen(kvpair_buf) + 1; 5344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 5374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->kvals.kvpairs = NULL; 5384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* no matter what was found or not found, return with the file pointer in 5414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * the state that it was upon entering this function */ 5424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffAscend(f, parent) != ESR_SUCCESS) 5434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 5444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_FATAL_ERROR; 5454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project goto swichunk_cleanup; 5464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectswichunk_cleanup: 5494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (rc == ESR_FATAL_ERROR) free_swiRiff(swichunk); 5504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return rc; 5514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 5524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* Reads RIFF format WAVE files 5554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 5564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode riffReadWave2L16(FILE *f, double from, double to, 5574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project short **samples, int *rate, int *length, SwiRiffStruct *swichunk) 5584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 5594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ChunkContext chunk, parent; 5604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project WaveFormat *wf; 5614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cb; 5624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ESR_ReturnCode rc; 5634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i, ifrom, ito; 5644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int doSwap = ! isLittleEndian(); 5654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* find the WAVE chunk */ 5674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(parent.tag, "WAVE", 4); 5684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffDescend(f, &parent, NULL, FIND_RIFF, doSwap) != ESR_SUCCESS) 5694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 5704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_AppendResult(res,"\nnot a RIFF waveform audio file",NULL); 5714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 5724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Wave format */ 5754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(chunk.tag, "fmt ", 4); 5764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffDescend(f, &chunk, &parent, FIND_CHUNK, doSwap) != ESR_SUCCESS) 5774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 5784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_AppendResult(res,"\nwaveform audio file has no \"fmt \" chunk.",NULL); 5794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 5804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (chunk.length < sizeof(WaveFormat)) 5824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project wf = MALLOC(sizeof(WaveFormat), MTAG); 5834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 5844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project wf = MALLOC(chunk.length, MTAG); 5854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(wf, 1, chunk.length, f) != (size_t)chunk.length) 5874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 5884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)wf); 5894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,"fmt chunk read failed.",GS_STATIC); 5904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 5914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) swapWaveFormat(wf); 5934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *rate = wf->nSamplesPerSec; 5944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* data chunk */ 5964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffAscend(f, &chunk) != ESR_SUCCESS) 5974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 5984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 5994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(chunk.tag, "data", 4); 6014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffDescend(f, &chunk, &parent, FIND_CHUNK, doSwap) != ESR_SUCCESS) 6024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 6034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_AppendResult(res,"\nwaveform audio file has no \"data\" chunk.",NULL); 6044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 6054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cb = MALLOC(chunk.length, MTAG); /* waveform */ 6074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(cb, 1, chunk.length, f) != (size_t)chunk.length) 6084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 6094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)wf); 6104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)cb); 6114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,"truncated \"data\" chunk",GS_STATIC); 6124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 6134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk) 6164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 6174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = readSwiChunk(f, &parent, swichunk, doSwap); 6184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (rc != ESR_SUCCESS) 6194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 6204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)wf); 6214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)cb); 6224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return rc; 6234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0;WaveCodecs[i].func;i++) 6274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nFormatTag == WaveCodecs[i].id) 6294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 6304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = (WaveCodecs[i].func)(wf, &chunk, cb, samples, length, doSwap); 6314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)wf); 6324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)cb); 6334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (rc != ESR_SUCCESS) 6344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 6354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk) free_swiRiff(swichunk); 6364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return rc; 6374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* handle 'from' and 'to' - this isn't very efficient, but 6394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * saves all the format conversion routines the trouble of doing so 6404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 6414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (from == 0 && to == -1) return ESR_SUCCESS; 6424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (from > 0) 6434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ifrom = (int)(from * (*rate) / 1000.0); 6444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 6454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ifrom = 0; 6464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (to >= 0) 6484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 6494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ito = (int)(to * (*rate) / 1000.0 + 0.5); 6504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (ito > *length) 6514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ito = *length; 6524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 6544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ito = *length; 6554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *length = ito - ifrom; 6574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (ifrom > 0) memmove(*samples, (*samples) + ifrom, (*length)*sizeof(short)); 6584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 6594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //GS_SetResult(res,GS_Spf(0,"WAVE format (id 0x%x) not supported", 6624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //wf->nFormatTag),GS_VOLATILE); 6634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // 6644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk) free_swiRiff(swichunk); 6654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)cb); 6664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 6674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 6684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* Reads RIFF format WAVE files and returns: 6724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * waveform: allocated with size num_bytes 6734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * audio_type is a constant string (not allocated) 6744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * If swichunk==NULL, does not look for swi-specific chunk, 6754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Returns ESR_FATAL_ERROR if num_channels != 1 6764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * If and only if ESR_SUCCESS, caller must free waveform, and swichunk contents (if any) 6774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 6784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode readRiff2Buf(FILE *f, void **waveform, unsigned int *num_bytes, 6794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const wchar_t **audio_type, SwiRiffStruct *swichunk) 6804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 6814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ChunkContext chunk, parent; 6824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project WaveFormat *wf = NULL; 6834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ESR_ReturnCode rc = ESR_SUCCESS; 6844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int doSwap = ! isLittleEndian(); 6854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *waveform = NULL; 6864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = NULL; /* for error recovery higher up */ 6884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk) 6904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { /* for error recovery */ 6914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->segs.num_tuples = 0; 6924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swichunk->kvals.num_pairs = 0; 6934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* find the WAVE chunk */ 6964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(parent.tag, "WAVE", 4); 6974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffDescend(f, &parent, NULL, FIND_RIFF, doSwap) != ESR_SUCCESS) 6984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 6994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 7004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Wave format */ 7034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(chunk.tag, "fmt ", 4); 7044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffDescend(f, &chunk, &parent, FIND_CHUNK, doSwap) != ESR_SUCCESS) 7054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 7074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (chunk.length < sizeof(WaveFormat)) 7094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project wf = MALLOC(sizeof(WaveFormat), MTAG); 7104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 7114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project wf = MALLOC(chunk.length, MTAG); 7124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(wf, 1, chunk.length, f) != (size_t)chunk.length) 7144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)wf); 7164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 7174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) swapWaveFormat(wf); 7194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nChannels != 1) 7214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)wf); 7234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 7244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) 7264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapShort(&wf->nBlockAlign); /* usually == blockAlign / nChannels */ 7284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapInt(&wf->nSamplesPerSec); 7294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapShort(&wf->nFormatTag); 7304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* data chunk */ 7334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffAscend(f, &chunk) != ESR_SUCCESS) 7344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_FATAL_ERROR; 7364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project goto cleanup; 7374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(chunk.tag, "data", 4); 7404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (riffDescend(f, &chunk, &parent, FIND_CHUNK, doSwap) != ESR_SUCCESS) 7414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_FATAL_ERROR; 7434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project goto cleanup; 7444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *num_bytes = chunk.length; /* already swapped, if need be */ 7474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *waveform = CALLOC(chunk.length, 1, MTAG); 7484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fread(*waveform, 1, chunk.length, f) != (size_t)chunk.length) 7494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_FATAL_ERROR; 7514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project goto cleanup; 7524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) 7544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nBlockAlign == 2) 7564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project short_byte_swap((short *)*waveform, chunk.length); 7574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nBlockAlign == 4) 7584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int_byte_swap((int *)*waveform, chunk.length); 7594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk) 7624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = readSwiChunk(f, &parent, swichunk, doSwap); 7644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project goto cleanup; 7654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = NULL; 7684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* assuming nchannels = 1, usually bytes_per_sample==blockAlign / nchannels (not aurora!) */ 7704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nFormatTag == WAVEFORMAT_PCM) 7714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nBlockAlign == 2) 7734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project {/* can only be L16 */ 7744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nSamplesPerSec == 8000) 7754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"audio/L16;rate=8000"; 7764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nSamplesPerSec == 16000) 7774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"audio/L16;rate=16000"; 7784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nFormatTag == WAVEFORMAT_ALAW) 7814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nSamplesPerSec == 8000) 7834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"audio/x-alaw-basic;rate=8000"; 7844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nFormatTag == WAVEFORMAT_MULAW) 7864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nSamplesPerSec == 8000) 7884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk) 7904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 7914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *encoding = getSwiRiffKVal(swichunk, "orig-encoding"); 7924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!encoding) 7934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"audio/basic;rate=8000"; 7944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (! strcmp(encoding, "g723")) 7954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"audio/basic;rate=8000;orig-encoding=g723"; 7964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (! strcmp(encoding, "g729")) 7974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"audio/basic;rate=8000;orig-encoding=g729"; 7984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 7994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // FIXME: warning because unknown orig-encoding?? 8014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // rec_test will never get here cuz already checked validity of audiotype 8024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // but to be careful pour l'avenir, should handle this 8034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"audio/basic;rate=8000"; 8044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 8074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"audio/basic;rate=8000"; 8084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nSamplesPerSec == 16000) 8104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"audio/basic;rate=16000"; 8114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nFormatTag == WAVEFORMAT_AURORA) 8144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nSamplesPerSec == 8000) 8164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"application/x-feature;rate=8000;encoding=swifeature_aurora"; 8174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nSamplesPerSec == 11000) 8184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"application/x-feature;rate=11000;encoding=swifeature_aurora"; 8194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nSamplesPerSec == 16000) 8204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"application/x-feature;rate=16000;encoding=swifeature_aurora"; 8214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nFormatTag == WAVEFORMAT_ES_202_050) 8234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf->nSamplesPerSec == 8000) 8254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"application/x-feature;rate=8000;encoding=ES_202_050"; 8264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nSamplesPerSec == 11000) 8274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"application/x-feature;rate=11000;encoding=ES_202_050"; 8284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (wf->nSamplesPerSec == 16000) 8294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *audio_type = L"application/x-feature;rate=16000;encoding=ES_202_050"; 8304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (*audio_type == NULL) 8334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_FATAL_ERROR; 8354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project goto cleanup; 8364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectcleanup: 8394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wf) FREE((char *)wf); 8404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (rc != ESR_SUCCESS) 8414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk) 8434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project free_swiRiff(swichunk); 8444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (*waveform) 8454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *)*waveform); 8474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *waveform = NULL; 8484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return rc; 8514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 8524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int getFormatTag(wchar_t *audio_type) 8544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 8554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!wcsncmp(audio_type, L"audio/basic", 11)) 8564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return WAVEFORMAT_MULAW; 8584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!wcsncmp(audio_type, L"application/x-feature;", 14) && 8604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project wcsstr(audio_type, L"encoding=swifeature_aurora")) 8614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return WAVEFORMAT_AURORA; 8634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (!wcsncmp(audio_type, L"application/x-feature;", 14) && 8654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project wcsstr(audio_type, L"encoding=ES_202_050")) 8664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return WAVEFORMAT_ES_202_050; 8684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (!wcsncmp(audio_type, L"audio/x-alaw-basic", 18)) 8704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return WAVEFORMAT_ALAW; 8724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if (!wcsncmp(audio_type, L"audio/L16", 9)) 8744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return WAVEFORMAT_PCM; 8764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 8774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return -1; 8784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 8794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* we are assuming that riffaudio->num_tuples!=0, and hence riffaudio->tuples!=NULL 8814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 8824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic unsigned char *writeSwiAudioChunk(int doSwap, int chunk_len, SwiRiffAudio *riffaudio, 8834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned char *workbuf) 8844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 8854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ChunkInfoStruct ck; 8864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int chunkinfosize = sizeof(ChunkInfoStruct); 8874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(ck.ckString, "segs", 4); 8894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ck.ckLength = chunk_len; 8904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) 8914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 8924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project swapInt(&ck.ckLength); 8934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(workbuf, &ck, chunkinfosize); 8944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project workbuf += chunkinfosize; 8954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(workbuf, &riffaudio->num_tuples, sizeof(int)); 8974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project workbuf += sizeof(int); 8984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project chunk_len -= sizeof(int); 8994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(workbuf, riffaudio->tuples, chunk_len); 9014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int_byte_swap((int *)workbuf, riffaudio->num_tuples*3 + 1); 9024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* count every tuple (3) + num_tuples itself */ 9034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return workbuf + chunk_len; 9044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 9054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 9064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 9074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(workbuf, &ck, chunkinfosize); 9084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project workbuf += chunkinfosize; 9094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(workbuf, &riffaudio->num_tuples, sizeof(int)); 9104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project workbuf += sizeof(int); 9114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project chunk_len -= sizeof(int); 9124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(workbuf, riffaudio->tuples, chunk_len); 9144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return workbuf + chunk_len; 9154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 9164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 9174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* WARNING: returns with file pointer past the 4 first chars 9194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * 9204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * If the first 4 bytes of the specified file are "RIFF", 9214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * then we assume it's a RIFF file 9224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 9234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint isRiffFile(FILE *fp) 9244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 9254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char tmpbuf[4]; 9264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fseek(fp, 0, SEEK_SET); 9274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fread(tmpbuf, 4, sizeof(char), fp); 9284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return !strncmp(tmpbuf, "RIFF", 4); 9294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 9314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* 9334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * WARNING: assuming num_channels = 1 9344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * INPUT: waveform, num_bytes (waveform length), audio_type, 9354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * swichunk (it returns unmodified, including not swapped) 9364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * OUTPUT: buf (entire riff chunk) and buflen 9374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * 9384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * AURORA special case: 9394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * sampling rate = bytes_per_sample = -1; other fields of WaveFormat undefined 9404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 9414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode convertBuf2Riff( 9424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned char *waveform, 9434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned int num_bytes, 9444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project wchar_t *audio_type, 9454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int rate, 9464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int bytes_per_sample, 9474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SwiRiffStruct *swichunk, 9484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned char **buf, 9494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned int *buflen) 9504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 9514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned int total_buflen; 9524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned char *ptr, *workbuf; 9534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project short num_channels = 1; 9544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int num_samples; 9554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int bytes_sec; 9564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project short block_align; 9574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int doSwap; 9584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ChunkInfoStruct ck; 9594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project RiffHeaderStruct header; 9604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int headerSize = sizeof(RiffHeaderStruct); 9614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int chunkInfoSize = sizeof(ChunkInfoStruct); 9624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int listChunkSize = 0; 9634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int segs_chunk_size, kvals_chunk_size; 9644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project short format_tag = (short) getFormatTag(audio_type); 9654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (format_tag == -1 || 9674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project (bytes_per_sample == -1 && format_tag != WAVEFORMAT_AURORA && 9684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project format_tag != WAVEFORMAT_ES_202_050)) 9694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 9704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project PLogError(L("audio type not supported for RIFF conversion")); 9714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_FATAL_ERROR; 9724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 9744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (bytes_per_sample > 0) 9754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project num_samples = num_bytes / bytes_per_sample; 9764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 9774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project num_samples = num_bytes; 9784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(header.riffString, "RIFF", 4); 9804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(header.waveString, "WAVE", 4); 9814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(header.fmtString, "fmt ", 4); 9824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(header.dataString, "data", 4); 9834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project total_buflen = headerSize + num_bytes; 9854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk->segs.num_tuples || swichunk->kvals.num_pairs) 9874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 9884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project listChunkSize = chunkInfoSize /* LIST chunk info */ + 4 * sizeof(char); /* "swi " */ 9894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk->segs.num_tuples) 9904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 9914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project segs_chunk_size = sizeof(int) + (swichunk->segs.num_tuples) * sizeof(RiffAudioTuple); 9924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project listChunkSize += chunkInfoSize + segs_chunk_size; 9934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 9944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk->kvals.num_pairs) 9954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 9964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i; 9974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kvals_chunk_size = 0; 9984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0; i < swichunk->kvals.num_pairs; i++) 9994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 10004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kvals_chunk_size += (strlen(swichunk->kvals.kvpairs[i].key) + 1 10014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project + strlen(swichunk->kvals.kvpairs[i].value) + 1) * sizeof(char); 10024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 10034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kvals_chunk_size += sizeof(int); /* num_pairs */ 10044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project listChunkSize += chunkInfoSize + kvals_chunk_size; 10054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 10064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project total_buflen += listChunkSize; 10074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 10084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (total_buflen > *buflen) 10094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 10104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project PLogError(L("ESR_BUFFER_OVERFLOW")); 10114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_BUFFER_OVERFLOW; 10124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 10134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project workbuf = *buf; 10144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 10154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *buflen = total_buflen; 10164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ptr = workbuf; 10174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (format_tag == WAVEFORMAT_AURORA || format_tag == WAVEFORMAT_ES_202_050) 10184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 10194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bytes_sec = AURORA_BYTES_SEC; 10204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project block_align = 4; 10214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 10224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 10234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 10244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bytes_sec = (short)(rate * num_channels * bytes_per_sample); 10254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project block_align = bytes_per_sample * num_channels; 10264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 10274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project doSwap = !isLittleEndian(); 10284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) 10294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 10304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.riffChunkLength = swapConstInt(*buflen - chunkInfoSize); 10314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.fmtChunkLength = swapConstInt(sizeof(WaveFormat)); 10324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.nFormatTag = swapConstShort(format_tag); /* codec */ 10334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.nChannels = swapConstShort(num_channels); 10344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.nSamplesPerSec = swapConstInt(rate); 10354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.nAvgBytesPerSec = swapConstInt(bytes_sec); 10364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.nBlockAlign = swapConstShort(block_align); 10374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.wBitsPerSample = swapConstShort((short)((bytes_sec * 8) / rate)); 10384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.dataLength = swapConstInt(num_bytes); 10394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(ptr, &header, headerSize); 10404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 10414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(ptr + headerSize, waveform, header.dataLength); 10424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (bytes_per_sample == 2) 10434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project short_byte_swap((short *)(ptr + headerSize), num_samples); 10444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 10454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 10464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 10474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.riffChunkLength = total_buflen - chunkInfoSize; 10484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.fmtChunkLength = sizeof(WaveFormat); 10494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.nFormatTag = format_tag; /* codec */ 10504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.nChannels = num_channels; 10514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.nSamplesPerSec = rate; 10524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.nAvgBytesPerSec = bytes_sec; 10534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.nBlockAlign = (short) block_align; 10544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.waveinfo.wBitsPerSample = (bytes_sec * 8) / rate; 10554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project header.dataLength = num_bytes; 10564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 10574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(ptr, &header, headerSize); 10584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(ptr + headerSize, waveform, header.dataLength); 10594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 10604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ptr += headerSize + header.dataLength; 10614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 10624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk->segs.num_tuples || swichunk->kvals.num_pairs) 10634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 10644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(ck.ckString, "LIST", 4); 10654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ck.ckLength = listChunkSize - chunkInfoSize; 10664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) swapInt(&ck.ckLength); 10674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(ptr, &ck, chunkInfoSize); /* copy LIST */ 10684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ptr += chunkInfoSize; 10694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 10704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy((char *)ptr, "swi ", 4); 10714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ptr += 4; 10724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 10734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk->segs.num_tuples) 10744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 10754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ptr = writeSwiAudioChunk(doSwap, segs_chunk_size, &swichunk->segs, ptr); 10764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 10774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (swichunk->kvals.num_pairs) 10784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 10794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i, num_pairs; 10804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project RiffKVPair *pairs; 10814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 10824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strncpy(ck.ckString, "kvs ", 4); 10834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ck.ckLength = kvals_chunk_size; /* num_pairs and pairs themselves */ 10844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (doSwap) swapInt(&ck.ckLength); 10854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(ptr, &ck, chunkInfoSize); 10864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ptr += chunkInfoSize; 10874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 10884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project num_pairs = (doSwap) ? swapConstInt(swichunk->kvals.num_pairs) : swichunk->kvals.num_pairs; 10894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memcpy(ptr, &num_pairs, sizeof(int)); 10904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ptr += sizeof(int); 10914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 10924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (pairs = swichunk->kvals.kvpairs, i = 0; i < num_pairs; i++, pairs++) 10934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 10944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strcpy((char *)ptr, pairs->key); 10954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ptr += strlen(pairs->key) + 1; 10964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 10974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strcpy((char *)ptr, pairs->value); 10984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ptr += strlen(pairs->value) + 1; 10994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 11004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 11014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 11024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project passert((unsigned int)(ptr - workbuf) == *buflen); 11034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 11044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 11054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 11064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 11074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1108