我使用AVAudioRecorder编写了一个音频WAV(录制了我的声音)文件。最终的文件格式是WAV文件。文件已成功保存,我可以听到我的声音。我想将此文件发送到后端服务器(Web服务)。但我的服务器只接受WAV中的数据和FMT信息。它不接受我的wav文件,因为我的wav文件信息与FLLR,数据,FMT。我在Riffpad工具中检查了我的WAV文件信息。它显示FLLR,数据,FMT。但我只想要数据和fmt。因为我的服务器端只接受数据和FMT。那么请建议如何以编程方式删除我的wav文件中的FLLR?
我的记录源代码:
NSError *error;
// Recording settings
NSMutableDictionary *settings = [NSMutableDictionary dictionary];
[settings setValue: [NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[settings setValue: [NSNumber numberWithFloat:22050] forKey:AVSampleRateKey];
[settings setValue: [NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey]; // mono
[settings setValue: [NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[settings setValue: [NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
//[settings setValue: [NSNumber numberWithInt:16] forKey:AudioSampleType];
// File URL
NSURL *url = [NSURL fileURLWithPath:FILEPATH];
//NSLog(@"Url file path ::: %@",url);
// Create recorder
recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];
if (!recorder)
{
// NSLog(@"Error establishing recorder: %@", error.localizedFailureReason);
return;
}
答案 0 :(得分:1)
感谢上帝和你的支持朋友。是的,最后我解决了我的问题。我不知道方式是否正确。但我的问题已经解决了。我使用上面的代码录制语音并保存我的音频。然后我将再次使用以下代码导出音频。我从https://developer.ibm.com/answers/questions/180732/seems-watson-text-to-speech-service-returns-a-wav.html
获得了此代码-(NSData*) stripAndAddWavHeader:(NSData*) wav {
unsigned long wavDataSize = [wav length] - 44;
NSData *WaveFile= [NSMutableData dataWithData:[wav subdataWithRange:NSMakeRange(44, wavDataSize)]];
NSMutableData *newWavData;
newWavData = [self addWavHeader:WaveFile];
return newWavData;
}
- (NSMutableData *)addWavHeader:(NSData *)wavNoheader {
int headerSize = 44;
long totalAudioLen = [wavNoheader length];
long totalDataLen = [wavNoheader length] + headerSize-8;
long longSampleRate = 22050.0;
int channels = 1;
long byteRate = 8 * 44100.0 * channels/8;
Byte *header = (Byte*)malloc(44);
header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (Byte) (totalDataLen & 0xff);
header[5] = (Byte) ((totalDataLen >> 8) & 0xff);
header[6] = (Byte) ((totalDataLen >> 16) & 0xff);
header[7] = (Byte) ((totalDataLen >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (Byte) channels;
header[23] = 0;
header[24] = (Byte) (longSampleRate & 0xff);
header[25] = (Byte) ((longSampleRate >> 8) & 0xff);
header[26] = (Byte) ((longSampleRate >> 16) & 0xff);
header[27] = (Byte) ((longSampleRate >> 24) & 0xff);
header[28] = (Byte) (byteRate & 0xff);
header[29] = (Byte) ((byteRate >> 8) & 0xff);
header[30] = (Byte) ((byteRate >> 16) & 0xff);
header[31] = (Byte) ((byteRate >> 24) & 0xff);
header[32] = (Byte) (2 * 8 / 8); // block align
header[33] = 0;
header[34] = 16; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (Byte) (totalAudioLen & 0xff);
header[41] = (Byte) ((totalAudioLen >> 8) & 0xff);
header[42] = (Byte) ((totalAudioLen >> 16) & 0xff);
header[43] = (Byte) ((totalAudioLen >> 24) & 0xff);
NSMutableData *newWavData = [NSMutableData dataWithBytes:header length:44];
[newWavData appendBytes:[wavNoheader bytes] length:[wavNoheader length]];
return newWavData;
}
答案 1 :(得分:0)
在Swift上寻求数据边缘的解决方案
class MediaUtil {
private static func dataToUTF8String(data: NSData, offset: Int, length: Int) -> String? {
let range = NSMakeRange(offset, length)
let subdata = data.subdata(with: range)
return String(data: subdata, encoding: String.Encoding.utf8)
}
private static func dataToUInt32(data: NSData, offset: Int) -> Int {
var num: UInt32 = 0
let length = 4
let range = NSMakeRange(offset, length)
data.getBytes(&num, range: range)
return Int(num)
}
static func repairWAVHeader(data: NSMutableData)->Data {
// resources for WAV header format:
// [1] http://unusedino.de/ec64/technical/formats/wav.html
// [2] http://soundfile.sapp.org/doc/WaveFormat/
var newData = Data()
// update RIFF chunk size
let fileLength = data.length
var riffChunkSize = UInt32(fileLength - 8)
let riffChunkSizeRange = NSMakeRange(4, 4)
data.replaceBytes(in: riffChunkSizeRange, withBytes: &riffChunkSize)
// find data subchunk
var subchunkID: String?
var subchunkSize = 0
var fieldOffset = 12
let fieldSize = 4
while true {
// prevent running off the end of the byte buffer
if fieldOffset + 2*fieldSize >= data.length {
return newData
}
// read subchunk ID
subchunkID = dataToUTF8String(data: data, offset: fieldOffset, length: fieldSize)
fieldOffset += fieldSize
if subchunkID == "data" {
break
}
// read subchunk size
subchunkSize = dataToUInt32(data: data, offset: fieldOffset)
fieldOffset += fieldSize + subchunkSize
}
let rllrRange = NSMakeRange(0, fieldOffset)
data.replaceBytes(in: rllrRange, withBytes: nil, length: 0)
newData = newWavHeader(pcmDataLength: data.length)
newData.append(data as Data)
return newData
}
private static func newWavHeader(pcmDataLength: Int) -> Data {
var header = Data()
let headerSize = 44
let bitsPerSample = Int32(16)
let numChannels: Int32 = 1
let sampleRate: Int32 = 16000
// RIFF chunk descriptor
let chunkID = [UInt8]("RIFF".utf8)
header.append(chunkID, count: 4)
var chunkSize = Int32(pcmDataLength + headerSize - 4).littleEndian
let chunkSizePointer = UnsafeBufferPointer(start: &chunkSize, count: 1)
header.append(chunkSizePointer)
let format = [UInt8]("WAVE".utf8)
header.append(format, count: 4)
// "fmt" sub-chunk
let subchunk1ID = [UInt8]("fmt ".utf8)
header.append(subchunk1ID, count: 4)
var subchunk1Size = Int32(16).littleEndian
let subchunk1SizePointer = UnsafeBufferPointer(start: &subchunk1Size, count: 1)
header.append(subchunk1SizePointer)
var audioFormat = Int16(1).littleEndian
let audioFormatPointer = UnsafeBufferPointer(start: &audioFormat, count: 1)
header.append(audioFormatPointer)
var headerNumChannels = Int16(numChannels).littleEndian
let headerNumChannelsPointer = UnsafeBufferPointer(start: &headerNumChannels, count: 1)
header.append(headerNumChannelsPointer)
var headerSampleRate = Int32(sampleRate).littleEndian
let headerSampleRatePointer = UnsafeBufferPointer(start: &headerSampleRate, count: 1)
header.append(headerSampleRatePointer)
var byteRate = Int32(sampleRate * numChannels * bitsPerSample / 8).littleEndian
let byteRatePointer = UnsafeBufferPointer(start: &byteRate, count: 1)
header.append(byteRatePointer)
var blockAlign = Int16(numChannels * bitsPerSample / 8).littleEndian
let blockAlignPointer = UnsafeBufferPointer(start: &blockAlign, count: 1)
header.append(blockAlignPointer)
var headerBitsPerSample = Int16(bitsPerSample).littleEndian
let headerBitsPerSamplePointer = UnsafeBufferPointer(start: &headerBitsPerSample, count: 1)
header.append(headerBitsPerSamplePointer)
// "data" sub-chunk
let subchunk2ID = [UInt8]("data".utf8)
header.append(subchunk2ID, count: 4)
var subchunk2Size = Int32(pcmDataLength).littleEndian
let subchunk2SizePointer = UnsafeBufferPointer(start: &subchunk2Size, count: 1)
header.append(subchunk2SizePointer)
return header
}
}