Ejemplo n.º 1
0
/*return value == 0 sucess
               == -1 fails
 */
static int open_output(void)
{
    OSStatus				err = 0; //no err
    UInt32				count,
                                        bufferSize;
    AudioDeviceID			device = kAudioDeviceUnknown;
    AudioStreamBasicDescription		format;

    // get the default output device for the HAL
    count = sizeof(globals.device);
    // it is required to pass the size of the data to be returned
    err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
                                   &count, (void *) &device);
    if (err != 0) goto Bail;
    
    // get the buffersize that the default device uses for IO
    count = sizeof(globals.deviceBufferSize);
              // it is required to pass the size of the data to be returned
    err = AudioDeviceGetProperty(device, 0, 0, kAudioDevicePropertyBufferSize,
                                 &count, &bufferSize);
    if (err != 0) goto Bail;
   
    if( globals.deviceBufferSize>BUFLEN ){
        fprintf(stderr, "globals.deviceBufferSize NG: %ld\n",
                globals.deviceBufferSize);
        exit(1);
    }
   
         // get a description of the data format used by the default device
    count = sizeof(globals.deviceFormat);
         // it is required to pass the size of the data to be returned
    err = AudioDeviceGetProperty(device, 0, 0,
                                 kAudioDevicePropertyStreamFormat,
                                 &count, &format);
    if (err != 0) goto Bail;
    FailWithAction(format.mFormatID != kAudioFormatLinearPCM, err = -1, Bail);
                    // bail if the format is not linear pcm
    
    // everything is ok so fill in these globals
    globals.device = device;
    globals.deviceBufferSize = bufferSize;
    globals.deviceFormat = format;
    init_variable();
    
    err = AudioDeviceAddIOProc(globals.device, appIOProc, 0 );
                    // setup our device with an IO proc
    if (err != 0) goto Bail;

    globals.deviceFormat.mSampleRate = dpm.rate;

#if 0
    globals.deviceFormat.mFormatFlags =  kLinearPCMFormatFlagIsBigEndian
                                       | kLinearPCMFormatFlagIsPacked
                                       | kLinearPCMFormatFlagIsSignedInteger;
    globals.deviceFormat.mBytesPerPacket = 4;
    globals.deviceFormat.mBytesPerFrame = 4;
    globals.deviceFormat.mBitsPerChannel = 0x10;
    
    err = AudioDeviceSetProperty(device, &inWhen, 0, 0,
                                 kAudioDevicePropertyStreamFormat,
                                 count, &globals.deviceFormat);
    if (err != 0) goto Bail;
#endif

#if 0
    fprintf(stderr, "deviceBufferSize = %d\n", globals.deviceBufferSize);
    fprintf(stderr, "mSampleRate = %g\n", globals.deviceFormat.mSampleRate);
    fprintf(stderr, "mFormatID = 0x%08x\n", globals.deviceFormat.mFormatID);
    fprintf(stderr, "mFormatFlags = 0x%08x\n",
            globals.deviceFormat.mFormatFlags);
    fprintf(stderr, "mBytesPerPacket = 0x%08x\n",
            globals.deviceFormat.mBytesPerPacket);
    fprintf(stderr, "mBytesPerFrame = 0x%08x\n",
            globals.deviceFormat.mBytesPerFrame);
    fprintf(stderr, "mBitsPerChannel = 0x%08x\n",
            globals.deviceFormat.mBitsPerChannel);
#endif

Bail:
    return (err);
}
Ejemplo n.º 2
0
//	----------------------------------------------------------------------------------------------------
bool	PlatformInterfaceDBDMA_Mapped::init ( IOService* device, AppleOnboardAudio* provider, UInt32 inDBDMADeviceIndex )
{
	bool					result = FALSE;
	IOService* 				theService;
	IORegistryEntry			*macio;
	IORegistryEntry			*gpio;
	IORegistryEntry			*i2s;
	IORegistryEntry			*i2sParent;
	IOMemoryMap				*map;

	debugIOLog ( 3, "+ PlatformInterfaceDBDMA_Mapped::init ( %p, %p, %d )", device, provider, inDBDMADeviceIndex );
	
	FailIf ( NULL == provider, Exit );
	FailIf ( NULL == device, Exit );

	result = super::init ( device, provider, inDBDMADeviceIndex );
	if ( result ) 
	{
		mKeyLargoService = IOService::waitForService ( IOService::serviceMatching ( "KeyLargo" ) );
		debugIOLog ( 3, "  sound's name is %s",  ( (IORegistryEntry*)device)->getName () );
		
		i2s =  ( ( IORegistryEntry*)device)->getParentEntry ( gIODTPlane );
		FailWithAction ( 0 == i2s, result = false, Exit );
		debugIOLog ( 3, "  parent name is '%s'", i2s->getName () );

		if ( 0 == strcmp ( "i2s-a", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell0;
		}
		else if ( 0 == strcmp ( "i2s-b", i2s->getName () ) ) 
		{
			mI2SInterfaceNumber = kUseI2SCell1;
		}
		else if ( 0 == strcmp ( "i2s-c", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell2;
		}
		else if ( 0 == strcmp ( "i2s-d", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell3;
		}
		else if ( 0 == strcmp ( "i2s-e", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell4;
		}
		else if ( 0 == strcmp ( "i2s-f", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell5;
		}
		else if ( 0 == strcmp ( "i2s-g", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell6;
		}
		else if ( 0 == strcmp ( "i2s-h", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell7;
		}
		debugIOLog ( 5, "  mI2SInterfaceNumber = %d", mI2SInterfaceNumber );
		
		i2sParent = i2s->getParentEntry ( gIODTPlane );
		FailWithAction ( 0 == i2sParent, result = false, Exit );
		debugIOLog ( 3, "  parent name of '%s' is %s", i2s->getName (), i2sParent->getName () );

		macio = i2sParent->getParentEntry ( gIODTPlane );
		FailWithAction ( 0 == macio, result = false, Exit );
		debugIOLog ( 3, "  macio name is %s", macio->getName () );
		
		gpio = macio->childFromPath ( kGPIODTEntry, gIODTPlane);
		FailWithAction ( !gpio, result = false, Exit);
		debugIOLog ( 3, "  gpio name is %s", gpio->getName () );

		theService = ( OSDynamicCast ( IOService, i2s ) );
		FailWithAction ( !theService, result = false, Exit );

		map = theService->mapDeviceMemoryWithIndex ( inDBDMADeviceIndex );
		FailWithAction ( 0 == map, result = false, Exit );

		// cache the config space
		mSoundConfigSpace = (UInt8 *)map->getPhysicalAddress();

		// sets the clock base address figuring out which I2S cell we're on
		if ((((UInt32)mSoundConfigSpace ^ kI2S0BaseOffset) & 0x0001FFFF) == 0) 
		{
			//	[3060321]	ioBaseAddress is required by this object in order to enable the target
			//				I2S I/O Module for which this object is to service.  The I2S I/O Module
			//				enable occurs through the configuration registers which reside in the
			//				first block of ioBase.		rbm		2 Oct 2002
			mIOBaseAddress = (void *)((UInt32)mSoundConfigSpace - kI2S0BaseOffset);
			mIOBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)mSoundConfigSpace - kI2S0BaseOffset), 256);
			mI2SInterfaceNumber = kUseI2SCell0;
		}
		else if ((((UInt32)mSoundConfigSpace ^ kI2S1BaseOffset) & 0x0001FFFF) == 0) 
		{
			//	[3060321]	ioBaseAddress is required by this object in order to enable the target
			//				I2S I/O Module for which this object is to service.  The I2S I/O Module
			//				enable occurs through the configuration registers which reside in the
			//				first block of ioBase.		rbm		2 Oct 2002
			mIOBaseAddress = (void *)((UInt32)mSoundConfigSpace - kI2S1BaseOffset);
			mIOBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)mSoundConfigSpace - kI2S1BaseOffset), 256);
			mI2SInterfaceNumber = kUseI2SCell1;
		}
		else 
		{
			debugIOLog (3, "  AudioI2SControl::init ERROR: unable to setup ioBaseAddress and i2SInterfaceNumber");
		}
		FailIf (NULL == mIOBaseAddressMemory, Exit);

		//	[3060321]	ioConfigurationBaseAddress is required by this object in order to enable the target
		//				I2S I/O Module for which this object is to service.  The I2S I/O Module
		//				enable occurs through the configuration registers which reside in the
		//				first block of ioBase.		rbm		2 Oct 2002
		
		mIOConfigurationBaseAddress = (void *)mIOBaseAddressMemory->map()->getVirtualAddress();
		FailIf ( NULL == mIOConfigurationBaseAddress, Exit );

		//
		//	There are three sections of memory mapped I/O that are directly accessed by the Apple02Audio.  These
		//	include the GPIOs, I2S DMA Channel Registers and I2S control registers.  They fall within the memory map 
		//	as follows:
		//	~                              ~
		//	|______________________________|
		//	|                              |
		//	|         I2S Control          |
		//	|______________________________|	<-	soundConfigSpace = ioBase + i2s0BaseOffset ...OR... ioBase + i2s1BaseOffset
		//	|                              |
		//	~                              ~
		//	~                              ~
		//	|______________________________|
		//	|                              |
		//	|       I2S DMA Channel        |
		//	|______________________________|	<-	i2sDMA = ioBase + i2s0_DMA ...OR... ioBase + i2s1_DMA
		//	|                              |
		//	~                              ~
		//	~                              ~
		//	|______________________________|
		//	|            FCRs              |
		//	|            GPIO              |	<-	gpio = ioBase + gpioOffsetAddress
		//	|         ExtIntGPIO           |	<-	fcr = ioBase + fcrOffsetAddress
		//	|______________________________|	<-	ioConfigurationBaseAddress
		//	|                              |
		//	~                              ~
		//
		//	The I2S DMA Channel is mapped in by the Apple02DBDMAAudioDMAEngine.  Only the I2S control registers are 
		//	mapped in by the AudioI2SControl.  The Apple I/O Configuration Space (i.e. FCRs, GPIOs and ExtIntGPIOs)
		//	are mapped in by the subclass of Apple02Audio.  The FCRs must also be mapped in by the AudioI2SControl
		//	object as the init method must enable the I2S I/O Module for which the AudioI2SControl object is
		//	being instantiated for.
		//
		//	The physical addresses for memory mapped I/O within the KeyLargo system I/O controller are as follows:
		//	
		//
		//
		//                                       ______________________________
		//                                     /|                              |
		//                                    / |                              |
		//	                                 /  |______________________________|
		//	 ______________________________ /   |                              |
		//	|                              |    |       I2S 1 ('i2s-b')        |
		//	|                              |    |______________________________|....0xnnn11000	[0x80011000]
		//	|                              |    |                              |
		//	|                              |    |       I2S 0 ('i2s-a')        |
		//	|                              |    |______________________________|....0xnnn10000	[0x80001000]
		//	|       Device Registers       |   / 
		//	|                              |  /
		//	|                              | /   ______________________________ 
		//	|                              |/  /|                              |
		//	|______________________________|__/ |                              |
		//	|                              |    |______________________________|
		//	|                              |    |                              |
		//	|                              |    |    I2S 1 Rx DMA ('i2s-b')    |
		//	|                              |    |______________________________|....0xnnn08300	[0x80008300]
		//	|    DMA Channel Registers     |    |                              |
		//	|                              |    |    I2S 1 Tx DMA ('i2s-b')    |
		//	|                              |    |______________________________|....0xnnn08200	[0x80008200]
		//	|                              |    |                              |
		//	|______________________________|    |    I2S 0 Rx DMA ('i2s-a')    |
		//	|                              |\   |______________________________|....0xnnn08100	[0x80008100]
		//	|                              | \  |                              |
		//	|      Reserved: read "0"      |  \ |    I2S 0 Tx DMA ('i2s-a')    |
		//	|                              |   \|______________________________|....0xnnn08000	[0x80008000]
		//	|______________________________|
		//	|                              |
		//	|                              |
		//	|   Apple I/O Configuration    |
		//	|                              |
		//	|______________________________|....0xnnn00000	[0x80011000]
		//	
		//	Map the I2S configuration registers
		mIOI2SBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)mSoundConfigSpace), kI2S_IO_CONFIGURATION_SIZE);
		FailIf ( NULL == mIOI2SBaseAddressMemory, Exit );
		mI2SBaseAddress = (void *)mIOI2SBaseAddressMemory->map()->getVirtualAddress();
		FailIf (NULL == mI2SBaseAddress, Exit);
		
		debugIOLog (3, "  mI2SInterfaceNumber         = %d", mI2SInterfaceNumber);
		debugIOLog (3, "  mIOI2SBaseAddressMemory     = %p", mIOI2SBaseAddressMemory);
		debugIOLog (3, "  mI2SBaseAddress             = %p", mI2SBaseAddress);
		debugIOLog (3, "  mIOBaseAddressMemory        = %p", mIOBaseAddressMemory);
		debugIOLog (3, "  mIOConfigurationBaseAddress = %p", mIOConfigurationBaseAddress);
	}
Exit:
	debugIOLog ( 3, "- PlatformInterfaceDBDMA_Mapped::init ( %p, %p, %d ) returns %lX", device, provider, inDBDMADeviceIndex, result );
	return result;
}
Ejemplo n.º 3
0
void TLevelWriter3gp::saveSoundTrack(TSoundTrack *st)
{
	Track theTrack;
	OSErr myErr = noErr;
	SoundDescriptionV1Handle mySampleDesc;
	Media myMedia;
	Handle myDestHandle;
	SoundComponentData sourceInfo;
	SoundComponentData destInfo;
	SoundConverter converter;
	CompressionInfo compressionInfo;
	int err;

	if (!st)
		throw TException("null reference to soundtrack");

	if (st->getBitPerSample() != 16) {
		throw TImageException(m_path, "Only 16 bits per sample is supported");
	}

	theTrack = NewMovieTrack(m_movie, 0, 0, kFullVolume);
	myErr = GetMoviesError();
	if (myErr != noErr)
		throw TImageException(m_path, "error creating audio track");

	FailIf(myErr != noErr, CompressErr);

	myDestHandle = NewHandle(0);

	FailWithAction(myDestHandle == NULL, myErr = MemError(), NoDest);

	*myDestHandle = (char *)st->getRawData();

	//////////
	//
	// create a media for the track passed in
	//
	//////////

	// set new track to be a sound track
	m_soundDataRef = nil;
	m_hSoundMovieData = NewHandle(0);

	// Construct the Handle data reference
	err = PtrToHand(&m_hSoundMovieData, &m_soundDataRef, sizeof(Handle));

	if ((err = GetMoviesError() != noErr))
		throw TImageException(getFilePath(), "can't create Data Ref");

	myMedia = NewTrackMedia(theTrack, SoundMediaType, st->getSampleRate(), m_soundDataRef, HandleDataHandlerSubType); //track->rate >> 16

	myErr = GetMoviesError();
	if (myErr != noErr)
		throw TImageException(m_path, "error setting audio track");
	FailIf(myErr != noErr, Exit);

	// start a media editing session
	myErr = BeginMediaEdits(myMedia);
	if (myErr != noErr)
		throw TImageException(m_path, "error beginning edit audio track");

	FailIf(myErr != noErr, Exit);

	sourceInfo.flags = 0x0;
	sourceInfo.format = kSoundNotCompressed;
	sourceInfo.numChannels = st->getChannelCount();
	sourceInfo.sampleSize = st->getBitPerSample();
	sourceInfo.sampleRate = st->getSampleRate();
	sourceInfo.sampleCount = st->getSampleCount();
	sourceInfo.buffer = (unsigned char *)st->getRawData();
	sourceInfo.reserved = 0x0;

	destInfo.flags = kNoSampleRateConversion | kNoSampleSizeConversion |
					 kNoSampleFormatConversion | kNoChannelConversion |
					 kNoDecompression | kNoVolumeConversion |
					 kNoRealtimeProcessing;

	destInfo.format = k16BitNativeEndianFormat;

	destInfo.numChannels = st->getChannelCount();
	destInfo.sampleSize = st->getBitPerSample();
	destInfo.sampleRate = st->getSampleRate();
	destInfo.sampleCount = st->getSampleCount();
	destInfo.buffer = (unsigned char *)st->getRawData();
	destInfo.reserved = 0x0;

	SoundConverterOpen(&sourceInfo, &destInfo, &converter);

	myErr = SoundConverterGetInfo(converter, siCompressionFactor, &compressionInfo);
	if (myErr != noErr)
		throw TImageException(m_path, "error getting audio converter info");

	myErr = GetCompressionInfo(fixedCompression, sourceInfo.format, sourceInfo.numChannels, sourceInfo.sampleSize, &compressionInfo);
	if (myErr != noErr)
		throw TImageException(m_path, "error getting audio compression info");
	FailIf(myErr != noErr, ConverterErr);

	compressionInfo.bytesPerFrame = compressionInfo.bytesPerPacket * destInfo.numChannels;

	//////////
	//
	// create a sound sample description
	//
	//////////

	// use the SoundDescription format 1 because it adds fields for data size information
	// and is required by AddSoundDescriptionExtension if an extension is required for the compression format

	mySampleDesc = (SoundDescriptionV1Handle)NewHandleClear(sizeof(SoundDescriptionV1));
	FailWithAction(myErr != noErr, myErr = MemError(), Exit);

	(**mySampleDesc).desc.descSize = sizeof(SoundDescriptionV1);
	(**mySampleDesc).desc.dataFormat = destInfo.format;
	(**mySampleDesc).desc.resvd1 = 0;
	(**mySampleDesc).desc.resvd2 = 0;
	(**mySampleDesc).desc.dataRefIndex = 1;
	(**mySampleDesc).desc.version = 1;
	(**mySampleDesc).desc.revlevel = 0;
	(**mySampleDesc).desc.vendor = 0;
	(**mySampleDesc).desc.numChannels = destInfo.numChannels;
	(**mySampleDesc).desc.sampleSize = destInfo.sampleSize;
	(**mySampleDesc).desc.compressionID = 0;
	(**mySampleDesc).desc.packetSize = 0;
	(**mySampleDesc).desc.sampleRate = st->getSampleRate() << 16;
	(**mySampleDesc).samplesPerPacket = compressionInfo.samplesPerPacket;
	(**mySampleDesc).bytesPerPacket = compressionInfo.bytesPerPacket;
	(**mySampleDesc).bytesPerFrame = compressionInfo.bytesPerFrame;
	(**mySampleDesc).bytesPerSample = compressionInfo.bytesPerSample;

	//////////
	//
	// add samples to the media
	//
	//////////

	myErr = AddMediaSample(myMedia, myDestHandle,
						   0,
						   destInfo.sampleCount * compressionInfo.bytesPerFrame,
						   1,
						   (SampleDescriptionHandle)mySampleDesc,
						   destInfo.sampleCount * compressionInfo.samplesPerPacket,
						   0,
						   NULL);

	if (myErr != noErr)
		throw TImageException(m_path, "error adding audio samples");

	FailIf(myErr != noErr, MediaErr);

	myErr = EndMediaEdits(myMedia);
	if (myErr != noErr)
		throw TImageException(m_path, "error ending audio edit");

	FailIf(myErr != noErr, MediaErr);

	//////////
	//
	// insert the media into the track
	//
	//////////

	myErr = InsertMediaIntoTrack(theTrack, 0, 0, GetMediaDuration(myMedia), fixed1);
	if (myErr != noErr)
		throw TImageException(m_path, "error inserting audio track");

	FailIf(myErr != noErr, MediaErr);
	goto Done;

ConverterErr:
NoDest:
CompressErr:
Exit:

Done:

MediaErr:
	if (mySampleDesc != NULL)
		DisposeHandle((Handle)mySampleDesc);

	if (converter)
		SoundConverterClose(converter);

	if (myErr != noErr)
		throw TImageException(m_path, "error saving audio track");
}