我想从应用程序捆绑包中读取声音文件,复制它,使用其最大音量级别(增益值或峰值功率,我不确定技术名称),然后将其作为另一个文件再次写入捆绑包。
我已经完成了复制和写入部分。生成的文件与输入文件相同。我使用AudioToolbox框架中的AudioFile服务的AudioFileReadBytes()和AudioFileWriteBytes()函数来完成这个任务。
因此,我有输入文件的字节以及其音频数据格式(通过使用带有kAudioFilePropertyDataFormat的AudioFileGetProperty()函数),但我找不到一个变量来处理原始文件的最大音量级别。
为了澄清我的目的,我正在尝试生成另一个声音文件,其音量水平相对于原始文件增加或减少,因此我不关心用户或iOS设置的系统音量水平。
使用我提到的框架能否实现这一点?如果不能,是否有其他替代建议?
谢谢
编辑: 在查看Sam的答案时,我决定通过另一种方式扩展问题。
我可以使用AudioQueue服务将现有声音文件(位于捆绑包中)录制到另一个文件中,并在录制阶段使用框架调整音量级别吗?
更新: 以下是我如何读取输入文件和写入输出的代码。下面的代码降低了“某些”幅度值的声音级别,但带有大量噪音。有趣的是,如果我选择0.5作为幅度值,它会增加声音级别而不是降低声音级别,但当我使用0.1作为幅度值时,它会降低声音。这两种情况都涉及到扰动噪音。我想这就是Art谈论规范化的原因,但我对规范化一无所知。
我已经完成了复制和写入部分。生成的文件与输入文件相同。我使用AudioToolbox框架中的AudioFile服务的AudioFileReadBytes()和AudioFileWriteBytes()函数来完成这个任务。
因此,我有输入文件的字节以及其音频数据格式(通过使用带有kAudioFilePropertyDataFormat的AudioFileGetProperty()函数),但我找不到一个变量来处理原始文件的最大音量级别。
为了澄清我的目的,我正在尝试生成另一个声音文件,其音量水平相对于原始文件增加或减少,因此我不关心用户或iOS设置的系统音量水平。
使用我提到的框架能否实现这一点?如果不能,是否有其他替代建议?
谢谢
编辑: 在查看Sam的答案时,我决定通过另一种方式扩展问题。
我可以使用AudioQueue服务将现有声音文件(位于捆绑包中)录制到另一个文件中,并在录制阶段使用框架调整音量级别吗?
更新: 以下是我如何读取输入文件和写入输出的代码。下面的代码降低了“某些”幅度值的声音级别,但带有大量噪音。有趣的是,如果我选择0.5作为幅度值,它会增加声音级别而不是降低声音级别,但当我使用0.1作为幅度值时,它会降低声音。这两种情况都涉及到扰动噪音。我想这就是Art谈论规范化的原因,但我对规范化一无所知。
AudioFileID inFileID;
CFURLRef inURL = [self inSoundURL];
AudioFileOpenURL(inURL, kAudioFileReadPermission, kAudioFileWAVEType, &inFileID)
UInt32 fileSize = [self audioFileSize:inFileID];
Float32 *inData = malloc(fileSize * sizeof(Float32)); //I used Float32 type with jv42's suggestion
AudioFileReadBytes(inFileID, false, 0, &fileSize, inData);
Float32 *outData = malloc(fileSize * sizeof(Float32));
//Art's suggestion, if I've correctly understood him
float ampScale = 0.5f; //this will reduce the 'volume' by -6db
for (int i = 0; i < fileSize; i++) {
outData[i] = (Float32)(inData[i] * ampScale);
}
AudioStreamBasicDescription outDataFormat = {0};
[self audioDataFormat:inFileID];
AudioFileID outFileID;
CFURLRef outURL = [self outSoundURL];
AudioFileCreateWithURL(outURL, kAudioFileWAVEType, &outDataFormat, kAudioFileFlags_EraseFile, &outFileID)
AudioFileWriteBytes(outFileID, false, 0, &fileSize, outData);
AudioFileClose(outFileID);
AudioFileClose(inFileID);