Audio file format issue in objective c

吃可爱长大的小学妹 提交于 2020-01-13 06:47:06

问题


I have written an audio WAV (have recorded my voice) file using AVAudioRecorder. The final file format is a WAV file. File was successfully saved and I can hear my voice. I want to send this file to a back End server (web-service). But my server accepting only data and FMT information in WAV . It is not accepting my wav file because of my wav file infromation with FLLR, data, FMT. I have checked my WAV file information in Riffpad tool. It's showing FLLR, data, FMT. But I want only data and fmt. Because my server side accepts only data and FMT. So please advice how to remove FLLR in my wav file in programmatically?

My source code for the record:

  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;
    }

回答1:


Thank God and your support friends. Yes finally i solved my issues. I don't know the way is correct. But my issues is solved. I recorded voice using above code and save my audio .Then again i will export the audio using the following code. I got this code from 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;
 }



回答2:


Solution on Swift with seeking edges of data

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
}

}



来源:https://stackoverflow.com/questions/32312508/audio-file-format-issue-in-objective-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!