1/* 2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24// AIFFSupport.c created by CJS on Wed 10-May-2000 25 26#ifndef __AIFF_SUPPORT_H__ 27#include "AIFFSupport.h" 28#endif 29 30#ifndef __APPLE_CDDA_FS_DEBUG_H__ 31#include "AppleCDDAFileSystemDebug.h" 32#endif 33 34#ifndef __APPLE_CDDA_FS_VNODE_OPS_H__ 35#include "AppleCDDAFileSystemVNodeOps.h" 36#endif 37 38 39// System Includes 40#include <sys/systm.h> 41#include <libkern/OSByteOrder.h> 42 43 44#if defined(__LITTLE_ENDIAN__) 45 46// Conversion Routines 47static void 48SwapContainerChunk ( ContainerChunk * chunk ); 49 50static void 51SwapFormatVersionChunk ( FormatVersionChunk * chunk ); 52 53static void 54SwapExtCommonChunk ( ExtCommonChunk * chunk ); 55 56static void 57SwapSoundDataChunk ( SoundDataChunk * chunk ); 58 59static void 60SwapCDAIFFHeader ( CDAIFFHeader * header ); 61 62static void 63SwapFloat80 ( Float80 * value ); 64 65 66//----------------------------------------------------------------------------- 67// SwapContainerChunk - This converts a little endian representation 68// of a ContainerChunk into a big endian 69// representation 70//----------------------------------------------------------------------------- 71 72static void 73SwapContainerChunk ( ContainerChunk * chunk ) 74{ 75 76 chunk->ckID = OSSwapInt32 ( chunk->ckID ); 77 chunk->ckSize = OSSwapInt32 ( chunk->ckSize ); 78 chunk->formType = OSSwapInt32 ( chunk->formType ); 79 80} 81 82 83//----------------------------------------------------------------------------- 84// SwapContainerChunk - This converts a little endian representation 85// of a FormatVersionChunk into a big endian 86// representation 87//----------------------------------------------------------------------------- 88 89static void 90SwapFormatVersionChunk ( FormatVersionChunk * chunk ) 91{ 92 93 chunk->ckID = OSSwapInt32 ( chunk->ckID ); 94 chunk->ckSize = OSSwapInt32 ( chunk->ckSize ); 95 chunk->timeStamp = OSSwapInt32 ( chunk->timeStamp ); 96 97} 98 99 100//----------------------------------------------------------------------------- 101// SwapExtCommonChunk - This converts a little endian representation 102// of an ExtCommonChunk into a big endian 103// representation 104//----------------------------------------------------------------------------- 105 106static void 107SwapExtCommonChunk ( ExtCommonChunk * chunk ) 108{ 109 110 SwapFloat80 ( &chunk->sampleRate ); 111 112 chunk->ckID = OSSwapInt32 ( chunk->ckID ); 113 chunk->ckSize = OSSwapInt32 ( chunk->ckSize ); 114 chunk->numChannels = OSSwapInt16 ( chunk->numChannels ); 115 chunk->numSampleFrames = OSSwapInt32 ( chunk->numSampleFrames ); 116 chunk->sampleSize = OSSwapInt16 ( chunk->sampleSize ); 117 chunk->compressionType = OSSwapInt32 ( chunk->compressionType ); 118 119} 120 121 122//----------------------------------------------------------------------------- 123// SwapSoundDataChunk - This converts a little endian representation 124// of a SoundDataChunk into a big endian 125// representation 126//----------------------------------------------------------------------------- 127 128static void 129SwapSoundDataChunk ( SoundDataChunk * chunk ) 130{ 131 132 chunk->ckID = OSSwapInt32 ( chunk->ckID ); 133 chunk->ckSize = OSSwapInt32 ( chunk->ckSize ); 134 chunk->offset = OSSwapInt32 ( chunk->offset ); 135 chunk->blockSize = OSSwapInt32 ( chunk->blockSize ); 136 137} 138 139 140//----------------------------------------------------------------------------- 141// SwapCDAIFFHeader - This converts a little endian representation 142// of a CDAIFFHeader into a big endian 143// representation 144//----------------------------------------------------------------------------- 145 146static void 147SwapCDAIFFHeader ( CDAIFFHeader * header ) 148{ 149 150 SwapContainerChunk ( &header->containerChunk ); 151 SwapFormatVersionChunk ( &header->formatVersionChunk ); 152 SwapExtCommonChunk ( &header->commonChunk ); 153 SwapSoundDataChunk ( &header->soundDataChunk ); 154 155} 156 157 158//----------------------------------------------------------------------------- 159// SwapFloat80 - This converts a little endian representation 160// of a Float80 into a big endian representation 161//----------------------------------------------------------------------------- 162 163static void 164SwapFloat80 ( Float80 * data ) 165{ 166 167 data->exp = OSSwapInt16 ( data->exp ); 168 data->man[0] = OSSwapInt16 ( data->man[0] ); 169 data->man[1] = OSSwapInt16 ( data->man[1] ); 170 data->man[2] = OSSwapInt16 ( data->man[2] ); 171 data->man[3] = OSSwapInt16 ( data->man[3] ); 172 173} 174 175 176#endif /* defined(__LITTLE_ENDIAN__) */ 177 178 179//----------------------------------------------------------------------------- 180// BuildCDAIFFHeader - This routine builds a CDAIFFHeader and explicitly 181// makes it Big Endian (as defined by AIFF standard) 182//----------------------------------------------------------------------------- 183 184void 185BuildCDAIFFHeader ( CDAIFFHeader * header, uint32_t fileSize ) 186{ 187 188 ExtCommonChunk * commonChunkPtr = NULL; 189 SoundDataChunk * soundDataChunkPtr = NULL; 190 ContainerChunk * containerChunkPtr = NULL; 191 FormatVersionChunk * formatVersionChunkPtr = NULL; 192 uint32_t dataSize = fileSize - kPhysicalMediaBlockSize; 193 194 // Get the address of each sub-structure to make this easier to read 195 commonChunkPtr = &header->commonChunk; 196 soundDataChunkPtr = &header->soundDataChunk; 197 containerChunkPtr = &header->containerChunk; 198 formatVersionChunkPtr = &header->formatVersionChunk; 199 200 // Setup the version chunk 201 formatVersionChunkPtr->ckID = kFormatVersionID; 202 formatVersionChunkPtr->ckSize = ( uint32_t )( sizeof ( FormatVersionChunk ) - sizeof ( ChunkHeader ) ); 203 formatVersionChunkPtr->timeStamp = kAIFCVersion1; 204 205 // Setup the common chunk 206 commonChunkPtr->ckID = kCommonID; 207 commonChunkPtr->ckSize = ( uint32_t )( sizeof ( ExtCommonChunk ) - sizeof ( ChunkHeader ) ); 208 commonChunkPtr->numChannels = kStereo; // 2 channels 209 commonChunkPtr->numSampleFrames = dataSize / 4; // 4 = ( k16BitsPerSample / 8 ) * kStereo 210 commonChunkPtr->sampleSize = k16BitsPerSample; // Set the sample size to 16 bits 211 commonChunkPtr->sampleRate.exp = 0x400E; // Set the sample rate to 44.1 KHz 212 commonChunkPtr->sampleRate.man[0] = 0xAC44; // Set the sample rate to 44.1 KHz 213 commonChunkPtr->sampleRate.man[1] = 0x0000; // Set the sample rate to 44.1 KHz 214 commonChunkPtr->sampleRate.man[2] = 0x0000; // Set the sample rate to 44.1 KHz 215 commonChunkPtr->sampleRate.man[3] = 0x0000; // Set the sample rate to 44.1 KHz 216 217 // Data streamed off disc is in little endian format 218 commonChunkPtr->compressionType = k16BitLittleEndianFormat; 219 220 // Setup the soundData chunk 221 soundDataChunkPtr->ckID = kSoundDataID; 222 soundDataChunkPtr->offset = ( uint32_t ) ( kPhysicalMediaBlockSize - sizeof ( CDAIFFHeader ) ); 223 soundDataChunkPtr->ckSize = ( uint32_t ) ( ( sizeof ( SoundDataChunk ) - sizeof ( ChunkHeader ) ) + 224 dataSize + soundDataChunkPtr->offset ); 225 soundDataChunkPtr->blockSize = 0; 226 227 // Setup the container chunk 228 containerChunkPtr->ckID = kFormID; 229 containerChunkPtr->ckSize = ( uint32_t ) 230 ( ( sizeof ( ContainerChunk ) - sizeof ( ChunkHeader ) ) + // size of container chunk variables 231 ( formatVersionChunkPtr->ckSize + sizeof ( ChunkHeader ) ) + // size of common chunk 232 ( commonChunkPtr->ckSize + sizeof ( ChunkHeader ) ) + // size of common chunk 233 ( soundDataChunkPtr->ckSize + sizeof ( ChunkHeader ) ) ); // size of sound data chunk 234 235 // Save as uncompressed AIFF-C 236 containerChunkPtr->formType = kAIFCID; 237 238#if defined(__LITTLE_ENDIAN__) 239 240 // Convert from natural byte order to big endian byte order 241 // because AIFF Header data MUST be big endian (the audio data 242 // doesn't necessarily have to) 243 SwapCDAIFFHeader ( header ); 244 245#endif /* defined(__LITTLE_ENDIAN__) */ 246 247} 248 249 250//----------------------------------------------------------------------------- 251// End Of File 252//----------------------------------------------------------------------------- 253