我想将一些原始声音数据制作成AIFF文件格式。我知道音频数据的细节。我尝试从音频创建一个wave,但这不起作用。 OS X确实有一个函数来创建头,但它直接解决了一个文件,我可能不想那样做(那个函数,SetupAIFFHeader
在64位代码中已被弃用且不可用。)
答案 0 :(得分:2)
Apple的Core Audio API将创建数据并将数据写入AIFF文件和其他格式。它工作得很好,但在我看来,API很难使用。我将在下面粘贴一些示例代码,但您可能想要更改它。 AudioFileWriteBytes
一次可以写入超过2个字节。 AudioToolbox/ExtendedAudioFile.h
中还有另一个包装器API,它允许您编写32位浮点数等格式,并将其转换为基础格式,无论是AIFF / PCM还是压缩格式。
double sampleRate = 44100;
double duration = ...;
long nSamples = (long)(sampleRate * duration);
// Format struct for 1 channel, 16 bit PCM audio
AudioStreamBasicDescription asbd;
memset(&asbd, 0, sizeof(asbd));
asbd.mSampleRate = sampleRate;
asbd.mFormatID = kAudioFormatLinearPCM;
asbd.mFormatFlags = kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger;
asbd.mBitsPerChannel = 16;
asbd.mChannelsPerFrame = 1;
asbd.mFramesPerPacket = 1;
asbd.mBytesPerFrame = 2;
asbd.mBytesPerPacket = 2;
CFURLRef url = makeUrl("hello.aiff");
AudioFileID audioFile;
OSStatus res;
res = AudioFileCreateWithURL(url, kAudioFileAIFFType, &asbd,
kAudioFileFlags_EraseFile, &audioFile);
checkError(res);
UInt32 numBytes = 2;
for (int i=0; i<nSamples; i++) {
SInt16 sample = ... // something between SHRT_MIN and SHRT_MAX;
sample = OSSwapHostToBigInt16(sample);
res = AudioFileWriteBytes(audioFile, false, i*2, &numBytes, &sample);
checkError(res);
}
res = AudioFileClose(audioFile);
checkError(res);
checkError
断言res == noErr。 makeUrl
看起来像:
CFURLRef makeUrl(const char *cstr) {
CFStringRef path = CFStringCreateWithCString(0, cstr, kCFStringEncodingUTF8);
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, 0, false);
CFRelease(path);
return url;
}
答案 1 :(得分:0)
尽管我讨厌轮子改造,但我怀疑你最好的选择是推出自己的AIFF救援套路。
AIFF是Amiga上使用的旧电子艺术EA-IFF格式的延伸;它是一系列4字节标识符(类似于FOURCC),块长度和数据有效负载。维基百科的文章内容非常丰富,并提供了其他网站的链接,其中包含有关格式的详细信息。
答案 2 :(得分:0)
我能够写一个合适的AIFF文件。得到我的最后一点是我使用sizeof()表示结构的大小,其中大小省略了前八个字节。我确实使用Apple弃用的AIFF.h标头来获取结构,似乎QuickTime X和7都没有读取我在其中设置的元数据。
你可以在PlayerPRO的PlayerPRO 6分支机构看到我的作品。它位于函数PPApp_AppDelegate.m
-createAIFFDataFromSettings:data:
的文件中
答案 3 :(得分:0)
以下是一些C代码,这些代码将使用macOS的Apple CoreAudio
和AudioToolbox
框架创建AIFF文件。
#include <string.h>
#include <math.h>
#include "CoreAudio/CoreAudio.h"
#include "CoreAudio/CoreAudioTypes.h"
#include "AudioToolbox/AudioToolbox.h"
#include "AudioToolbox/AudioFile.h"
CFURLRef MakeUrl(const char *cstr);
void CheckError(OSStatus res);
AudioStreamBasicDescription asbd;
AudioFileID audioFile;
OSStatus res;
void CheckError(OSStatus result) {
if (result == noErr) return;
switch(result) {
case kAudioFileUnspecifiedError:
printf("kAudioFileUnspecifiedError");
break;
case kAudioFileUnsupportedFileTypeError:
printf("kAudioFileUnsupportedFileTypeError");
break;
case kAudioFileUnsupportedDataFormatError:
printf("kAudioFileUnsupportedDataFormatError");
break;
case kAudioFileUnsupportedPropertyError:
printf("kAudioFileUnsupportedPropertyError");
break;
case kAudioFileBadPropertySizeError:
printf("kAudioFileBadPropertySizeError");
break;
case kAudioFilePermissionsError:
printf("kAudioFilePermissionsError");
break;
case kAudioFileNotOptimizedError:
printf("kAudioFileNotOptimizedError");
break;
case kAudioFileInvalidChunkError:
printf("kAudioFileInvalidChunkError");
break;
case kAudioFileDoesNotAllow64BitDataSizeError:
printf("kAudioFileDoesNotAllow64BitDataSizeError");
break;
case kAudioFileInvalidPacketOffsetError:
printf("kAudioFileInvalidPacketOffsetError");
break;
case kAudioFileInvalidFileError:
printf("kAudioFileInvalidFileError");
break;
case kAudioFileOperationNotSupportedError:
printf("kAudioFileOperationNotSupportedError");
break;
case kAudioFileNotOpenError:
printf("kAudioFileNotOpenError");
break;
case kAudioFileEndOfFileError:
printf("kAudioFileEndOfFileError");
break;
case kAudioFilePositionError:
printf("kAudioFilePositionError");
break;
case kAudioFileFileNotFoundError:
printf("kAudioFileFileNotFoundError");
break;
default:
printf("unknown error");
break;
}
exit(result);
}
CFURLRef MakeUrl(const char *cstr) {
CFStringRef path = CFStringCreateWithCString(0, cstr, kCFStringEncodingUTF8);
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, 0, false);
CFRelease(path);
return url;
}
int main() {
double sampleRate = 44100.0;
double duration = 10.0;
long nSamples = (long)(sampleRate * duration);
memset(&asbd, 0, sizeof(asbd));
// Format struct for 1 channel, 16 bit PCM audio
asbd.mSampleRate = sampleRate;
asbd.mFormatID = kAudioFormatLinearPCM;
asbd.mFormatFlags = kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger;
asbd.mBitsPerChannel = 16;
asbd.mChannelsPerFrame = 1;
asbd.mFramesPerPacket = 1;
asbd.mBytesPerFrame = 2;
asbd.mBytesPerPacket = 2;
CFURLRef url = MakeUrl("sinpos.aiff");
res = AudioFileCreateWithURL(url, kAudioFileAIFFType, &asbd,
kAudioFileFlags_EraseFile, &audioFile);
CheckError(res);
UInt32 numBytes = 2;
int freq = 44; // 100 for approx 440Hz, 2940 for 15Hz, 44 for 1000Hz
for (int i=0; i<nSamples; i++) {
int x = (i % freq);
double angle = 2.0*3.1459*x/freq;
double s = 1.0*32767*sin(angle);
SInt16 sample = (SInt16) s;
sample = OSSwapHostToBigInt16(sample);
res = AudioFileWriteBytes(audioFile, false, i*2, &numBytes, &sample);
CheckError(res);
}
res = AudioFileClose(audioFile);
CheckError(res);
exit(0);
}
Makefile
如下:
aiffcreate: aiffcreate.c
gcc -o $@ $< -framework AudioToolbox -framework CoreFoundation -framework CoreAudio -lm
clean:
rm *.aiff aiffcreate || true
只需在命令行上发出./aiffcreate
命令即可运行此操作,然后将创建一个名为sinpos.aiff
的文件,该文件的纯净1000Hz音调持续10秒。