Re: Save PCM Stream to AIFF File (was How to play RAW PCM data using CA?)
Re: Save PCM Stream to AIFF File (was How to play RAW PCM data using CA?)
- Subject: Re: Save PCM Stream to AIFF File (was How to play RAW PCM data using CA?)
- From: malcom <email@hidden>
- Date: Mon, 27 Apr 2009 17:05:59 +0200
On Mon, Apr 27, 2009 at 4:45 PM, Doug Wyatt <email@hidden> wrote:
> If you call AudioFileWritePackets instead of AudioFileSetUserData, you will
> be storing your audio data where other applications expect to read it.
Well thank you, a big step forward. Now the file can be read by any
player but the results is a background noise. Now if I try to import
this file (as raw file in Audacity and set Byte Order: No Endianness,
look here http://yfrog.com/4cimmagine1cgrp) i can listen the correct
sound - the chirp. So probability I need to set the byte order in my
AIFF file but I don't know where is the costant for it.
I've tried with kLinearPCMFormatFlagIsNonInterleaved and
kAudioFormatFlagsAreAllClear but nothing.
(This is the fixed code for archives purpose):
#import "MainController.h"
#import <AudioToolbox/AudioToolbox.h>
void WriteChirpAIFFFile(FSRef fsRef, CFStringRef newFile);
int* 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) writeAIFF {
NSLog(@"%d",sizeof(int));
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
int *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);
AudioStreamPacketDescription asbd;
asbd.mDataByteSize = total_fileSize;
asbd.mStartOffset = 0;
asbd.mVariableFramesInPacket = 0; // not variable
UInt32 pullPackets = total_fileSize;
status = AudioFileWritePackets(audioFileID, NO, total_fileSize*4,
&asbd, 0, &pullPackets, 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
int* 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 *wavesamples = malloc(len_array*sizeof(int));
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
wavesamples[t] = (int)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