• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Save PCM Stream to AIFF File (was How to play RAW PCM data using CA?)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Save PCM Stream to AIFF File (was How to play RAW PCM data using CA?)


  • Subject: Save PCM Stream to AIFF File (was How to play RAW PCM data using CA?)
  • From: malcom <email@hidden>
  • Date: Sun, 26 Apr 2009 16:46:36 +0200

> However, if that proves too difficult, you could change from saving the raw NSData to using the CoreAudio
> AudioFile API to save a CAF file instead of the raw data.  You will certainly be able to open an audio file created > with the AudioFIle API (Or ExtAudioFile, if needed).

I've tried to save the file using AudioFileCreate() (to create the
file itself) and AudioFileSetUserData() to fill up with my samples.
Everything works fine... in fact file data is written correctly but
I'm unable to play it (every player I've used says simply "File Format
Error").
I've also tried to import it in Audacity as RAW file and it works fine
(but I need to set the "endianess" parameter on import. Due to this
fact probability I've set a wrong type in my
AudioStreamBasicDescription's mFormatFlags. Could be the problem?

This is my code. It's pretty simple and you can try it in a second.
Chirp function generate 16bit/mono/44100 sound samples (as an array of shorts).

void WriteChirpAIFFFile(FSRef fsRef, CFStringRef newFile);
short* generateChirpSignalBuffer(double freq_start,double freq_end,int
duration_secs,long sample_rate, int bits_persample, int
*ret_totalSamples);

#define kFileName			@"testme.aiff"
#define kDefaultLocation	@"~/Desktop/"

- (void) testAiffFileCreation {
	FSRef fsRef;
	// try to make an AIFF file in desktop (this call fails if the file exists yet)
	NSString *fPath = [[NSString
stringWithFormat:@"%@%@",kDefaultLocation,kFileName]
stringByStandardizingPath];
	if ([[NSFileManager defaultManager] fileExistsAtPath:fPath] == YES)
		[[NSFileManager defaultManager] removeFileAtPath: fPath
handler:nil]; // remove old file if it exists

	// make our aiff file
	CFURLGetFSRef((CFURLRef)[NSURL fileURLWithPath:[kDefaultLocation
stringByStandardizingPath]], &fsRef);
	WriteChirpAIFFFile(fsRef, (CFStringRef)kFileName);
}

void WriteChirpAIFFFile(FSRef fsRef, CFStringRef newFile) {
	// setup the format
	Float64 sampleRate = 44100;	// 44100 sample rate frequency
	UInt32 bitsPerChannel = 16;	// 16 bits of data
	double start_freq = 1000;	// starting frequency is 1000Hz
	double end_freq = 10000;	// end frequency is 10000Hz
	int duration = 10;		// duration of chirp is 10 seconds

	// setup audio stream description
	AudioStreamBasicDescription aiffFormat;
	aiffFormat.mSampleRate = sampleRate;			// sample rate data
	aiffFormat.mFormatID = kAudioFormatLinearPCM;	// linear pulse-code
modulation data

	// importing my stream data in Audacity I need to set the endianess
parameter (not big endian or little endian)
	// so... the error could be in here, but I don't know how to solve it.
	aiffFormat.mFormatFlags  = kLinearPCMFormatFlagIsSignedInteger |
	kLinearPCMFormatFlagIsPacked |
	kLinearPCMFormatFlagIsBigEndian;

	aiffFormat.mBytesPerPacket = 4;					// The number of bytes in a packet of data.
	aiffFormat.mFramesPerPacket = 1;				// In uncompressed audio, a
Packet is one frame, (mFramesPerPacket == 1)
	aiffFormat.mBytesPerFrame = 4;					// The number of bytes in a packet of data.
	aiffFormat.mChannelsPerFrame = 1;
	aiffFormat.mBitsPerChannel = bitsPerChannel;

	FSRef outRef;
	AudioFileID audioFileID;
	// create our AIFF audio file structure (headers only)
	OSStatus status = AudioFileCreate(&fsRef, newFile,
kAudioFileAIFFType, &aiffFormat, 0, &outRef, &audioFileID);
	if (status == kAudioFormatUnsupportedDataFormatError)
		NSLog(@"error: audio format is not supported"); // ops something
wrong in audio format params...
	else if (status == noErr) NSLog(@"all done, file was created"); // okay
	else NSLog(@"Other error occurred: %d",status); // something else goes wrong

	int total_fileSize = 0;
	// generate chirp signal from 1000Hz to 10000Hz of 10 secs at
16bit/44100 sample rate
	short *arr =	generateChirpSignalBuffer(start_freq, end_freq,
duration, (long)sampleRate, bitsPerChannel,&total_fileSize);
	// copy buffer data to file
	status = AudioFileSetUserData(audioFileID, kAudioFileAIFFType, 0,
total_fileSize, arr);
	if (status == noErr)
		NSLog(@"%d bytes of data, our chirp stream of shorts, was copied
successfully to aiff file",total_fileSize);

	// close and free memory
	// AT THIS TIME THE FILE IS CORRECTLY FILLED WITH OUR STREAM DATA BUT
	// BOTH THE FINDER AND AUDIO APPS SAYS "FILE FORMAT ERROR".
	// IF I TRY TO IMPORT IT AS RAW DATA (or import the raw buffer data
without the aiff headers)
	// IT WORKS FINE!
	// JUST A NOTE: in Audacity i need to import is as endianess format
	AudioFileClose(audioFileID);
	free(arr);
}

#define MIN_INT	-32768
#define MAX_INT 32767
#define PI		3.141592653

short* generateChirpSignalBuffer(double freq_start,double freq_end,int
duration_secs,long sample_rate, int bits_persample, int
*ret_totalSamples) {
	long len_array = (long)duration_secs*sample_rate; // this is the
number of samples to generate
	*ret_totalSamples = len_array; // store the total sample we will make
	short *wavesamples = malloc(len_array*sizeof(short));
	int i; for (i=0; i < len_array; i++) // some funky initializations...
		wavesamples[i] = 0;

	double k = (freq_end-freq_start)/len_array;
	double freq = freq_start; // this is our time-to-time frequency value
	double omega = (double)(PI / sample_rate);

	long t;
	for (t=0; t < len_array; t++) {
		freq += k; // increase frequency over the time with the omega value
		double c_sample = sin(omega*freq*t)*MAX_INT;
		wavesamples[t] = (short)c_sample; // okay we have our sample at time t
	}
	return wavesamples; // okay, our array now contains a sequence of
mono short signed pcm data
}
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: Save PCM Stream to AIFF File (was How to play RAW PCM data using CA?)
      • From: tahome izwah <email@hidden>
    • Re: Save PCM Stream to AIFF File (was How to play RAW PCM data using CA?)
      • From: Doug Wyatt <email@hidden>
  • Prev by Date: Audio queues...again
  • Next by Date: Re: GrahicEQ AU trouble
  • Previous by thread: RE: Audio queues...again
  • Next by thread: Re: Save PCM Stream to AIFF File (was How to play RAW PCM data using CA?)
  • Index(es):
    • Date
    • Thread