2016-09-29 5 views
1

私のアプリはオーディオファイルを生成する必要があり、最後のAndroidバージョンに続いてファイルジェネレータを作成しています。 Androidでは、OKIOを使用して、ネイティブNSDataを使用するIOとiOSを処理します。WAVファイルを作成するために間違ったバイトが生成されました

すべてのWAVファイルには、データリーダー(メディアプレーヤー)のパラメータを知らせるためのヘッダーが必要です。

インターネット上で提供されているいくつかの仕様に従って、このファイルジェネレータを使用してバイトを書き込みます。

//Audio file content, this variable will be used 
//to storage the audio data (PCM). 
var content = [UInt8]() //This is not empty. 
var fileSize: Int = 0 //this is not zero. 

//Total size of the file, with the header. 
let totalFileSize = fileSize + HEADER_SIZE 

//Header data 
let header = NSMutableData() 

//RIFF 
header.append([UInt8]("RIFF".utf8), length: 4) 

//Size of the entity file 
header.append(Data(bytes: readInt(Int32(totalFileSize).littleEndian))) 

//WAVE 
header.append([UInt8]("WAVE".utf8), length: 4) 

//FMT 
header.append([UInt8]("fmt ".utf8), length: 4) 

//BITRATE 
header.append(Data(bytes: readInt(BITRATE.littleEndian))) 

//Audio format 
var audioFormat = AUDIO_FORMAT_PCM.littleEndian 
header.append(&audioFormat, length: 2) 

//Number of channels 
var audioChannels = CHANNELS.littleEndian 
header.append(&audioChannels, length: 2) 

//Sample rate 
var sampleRate = SAMPLE_RATE.littleEndian 
header.append(&sampleRate, length: 4) 

//Byte rate 
var byteRate = ((SAMPLE_RATE*UInt32(CHANNELS)*UInt32(BYTES_PER_SAMPLE))/UInt32(8)).littleEndian 
header.append(&byteRate, length: 4) 

//Block align 
var blockAlign = (UInt16(CHANNELS) * UInt16(BYTES_PER_SAMPLE)/UInt16(8)).littleEndian 
header.append(&blockAlign, length: 2) 

//Bytes per sample 
var bytesPerSample = BYTES_PER_SAMPLE.littleEndian 
header.append(&bytesPerSample, length: 2) 

//Data 
header.append([UInt8]("data".utf8), length: 4) 

//Size of the audio data 
var sizeLittleEndian = UInt32(fileSize).littleEndian 
header.append(&sizeLittleEndian, length: 4) 

print(header.length) //44 

これは、バッファ上のIntを書くために、このメソッドを使用しています:Androidのオン

func readInt(_ i: Int32) -> [UInt8] { 
    return [UInt8(truncatingBitPattern: (i >> 24) & 0xff), 
      UInt8(truncatingBitPattern: (i >> 16) & 0xff), 
      UInt8(truncatingBitPattern: (i >> 8) & 0xff), 
      UInt8(truncatingBitPattern: (i  ) & 0xff)] 
} 

、ファイルは問題なく生成されています。しかし、iOSではこれらの2つのパラメータが間違っています。 (ほとんどのトップファイルはAndroidのコードを生成し、底部がiOSのコードによって生成された)を見て:

enter image description here

スウィフト3

に私は本当にあなたが私を助けることができ、何が起こっているか分からないのですか?

+0

これを解決しましたか? – astromme

+0

はい:解決しました! –

+0

ここに回答を投稿できますか? – astromme

答えて

0

書かれたtotalFileSizeはiOSでビッグエンディアンに見えますが、Androidでは小さいです。たぶん、あなたは.littleEndianそれを2回送っていますか?

のiOS dataブロックしますか?そこに妥当なサンプル値はdata後ですが、あなたには、いくつかのCoreAudio構造(多分AudioUnitExtAudioFileのアドレスを撮影したようにiOSの上に見えるのAndroid上で、右のいずれかを見ていませんAudioConverter?)。

+0

データを提供するコードを削除しました。しかし、それは単にPCMファイルを読み込んで、バイトとそのバイトを一時バッファに入れます。 –

+0

最初の質問については、私は本当に知らない、これは値または位置に関連していますか? –

+0

ああ、 '.caf'ファイルのヘッダをあなたのwavファイルに書きました。それはうまく終わらないだろう。はい、 '.caf'ファイルはlpcmですが、どのような形式ですか?最初にデコードする必要があります。 'totalFileSize'の値はwavファイルでは間違っています –

0

主要な問題の1つは、readInt関数がビッグエンディアンを返すことです。リトルエンディアンである必要があります。

とにかく、これは私のために働いた。これは私がWAVファイルを初期化する方法です。誰かを助けることを願っています。

func createHeader() { 

    let sampleRate:Int32 = 44100 
    let chunkSize:Int32 = 36 
    let subChunkSize:Int32 = 16 
    let format:Int16 = 1 
    let channels:Int16 = 1 
    let bitsPerSample:Int16 = 16 
    let byteRate:Int32 = sampleRate * Int32(channels * bitsPerSample/8) 
    let blockAlign: Int16 = channels * 2 
    let dataSize:Int32 = 0 

    let header = NSMutableData() 

    header.append([UInt8]("RIFF".utf8), length: 4) 
    header.append(intToByteArray(chunkSize), length: 4) 

    //WAVE 
    header.append([UInt8]("WAVE".utf8), length: 4) 

    //FMT 
    header.append([UInt8]("fmt ".utf8), length: 4) 

    header.append(intToByteArray(subChunkSize), length: 4) 
    header.append(shortToByteArray(format), length: 2) 
    header.append(shortToByteArray(channels), length: 2) 
    header.append(intToByteArray(sampleRate), length: 4) 
    header.append(intToByteArray(byteRate), length: 4) 
    header.append(shortToByteArray(blockAlign), length: 2) 
    header.append(shortToByteArray(bitsPerSample), length: 2) 


    header.append([UInt8]("data".utf8), length: 4) 

    header.append(intToByteArray(dataSize), length: 4) 

    header.write(to: fileURL!, atomically: true) 

} 

func intToByteArray(_ i: Int32) -> [UInt8] { 
    return [ 
      //little endian 
      UInt8(truncatingBitPattern: (i  ) & 0xff), 
      UInt8(truncatingBitPattern: (i >> 8) & 0xff), 
      UInt8(truncatingBitPattern: (i >> 16) & 0xff), 
      UInt8(truncatingBitPattern: (i >> 24) & 0xff) 
    ] 
} 

func shortToByteArray(_ i: Int16) -> [UInt8] { 
    return [ 
     //little endian 
     UInt8(truncatingBitPattern: (i  ) & 0xff), 
     UInt8(truncatingBitPattern: (i >> 8) & 0xff) 
    ] 
} 
関連する問題