在iOS上使用Flac进行分块编码 [英] Chunked Encoding using Flac on iOS

查看:186
本文介绍了在iOS上使用Flac进行分块编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到了一个有助于将WAV文件转换为Flac的库:
https://github.com / jhurt / wav_to_flac

I found a library that helps to convert WAV file to Flac: https://github.com/jhurt/wav_to_flac

同时成功将Flac编译到平台并且工作正常。

Also succeed to compile Flac to the platform and it works fine.

我在使用wav格式捕获音频后将其转换为Flac,然后发送到我的服务器,我一直在使用这个库。

I've been using this library after capturing the audio on wav format to convert it to Flac and then send to my server.

问题是音频文件可能是浪费了很长时间然后宝贵的时间。

Problem is that the audio file could be long and then precious time is wasted.

我想将音频编码为Flac格式并在捕获时同时将其发送到服务器而不是之后捕获停止,所以,我需要一个关于如何做到这一点的帮助(直接从音频编码Flac,以便我可以将它发送到我的服务器)...

The thing is that I want to encode the audio as Flac format and send that to server on the same time when capturing and not after capturing stops, So, I need a help here on how to do that (encode Flac directly from the audio so I could send it to my server)...

推荐答案

在我的libsprec库中,你可以看到一个记录WAV文件的例子(这里)和con将其转换为FLAC(此处)。 (致谢:音频录音部分在很大程度上依赖于Erica Sadun的工作,作为记录。)

In my library called libsprec, you can see an example of both recording a WAV file (here) and converting it to FLAC (here). (Credits: the audio recording part heavily relies on Erica Sadun's work, for the record.)

现在,如果你想一步完成,强>你也可以这样做。诀窍是你必须首先初始化音频队列 FLAC库,然后交错对它们的调用,i。即当您在音频队列的回调函数中获得一些音频数据时,您立即对其进行FLAC编码。

Now if you want to do this in one step, you can do that as well. The trick is that you have to do the initialization of both the Audio Queues and the FLAC library first, then "interleave" the calls to them, i. e. when you get some audio data in the callback function of the Audio Queue, you immediately FLAC-encode it.

但是,我不认为这是在两个单独的步骤中记录和编码要快得多。处理的重要部分是记录和编码本身的数学,所以重新读取相同的缓冲区(或者我敢,甚至是文件!)不会增加处理时间。

I don't think, however, that this would be much faster than recording and encoding in two separate steps. The heavy part of the processing is the recording and the maths in the encoding itself, so re-reading the same buffer (or I dare you, even a file!) won't add much to the processing time.

这就是说,你可能想做这样的事情:

That said, you may want to do something like this:

// First, we initialize the Audio Queue

AudioStreamBasicDescription desc;
desc.mFormatID = kAudioFormatLinearPCM;
desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
desc.mReserved = 0;
desc.mSampleRate = SAMPLE_RATE;
desc.mChannelsPerFrame = 2; // stereo (?)
desc.mBitsPerChannel = BITS_PER_SAMPLE;
desc.mBytesPerFrame = BYTES_PER_FRAME;
desc.mFramesPerPacket = 1;
desc.mBytesPerPacket = desc.mFramesPerPacket * desc.mBytesPerFrame;

AudioQueueRef queue;

status = AudioQueueNewInput(
    &desc,
    audio_queue_callback, // our custom callback function
    NULL,
    NULL,
    NULL,
    0,
    &queue
);

if (status)
    return status;

AudioQueueBufferRef buffers[NUM_BUFFERS];

for (i = 0; i < NUM_BUFFERS; i++) {
    status = AudioQueueAllocateBuffer(
        queue,
        0x5000, // max buffer size
        &buffers[i]
    );
    if (status)
        return status;

    status = AudioQueueEnqueueBuffer(
        queue,
        buffers[i],
        0,
        NULL
    );
    if (status)
        return status;
}

// Then, we initialize the FLAC encoder:
FLAC__StreamEncoder *encoder;
FLAC__StreamEncoderInitStatus status;
FILE *infile;
const char *dataloc;
uint32_t rate;      /* sample rate */
uint32_t total;     /* number of samples in file */
uint32_t channels;  /* number of channels */
uint32_t bps;       /* bits per sample */
uint32_t dataoff;   /* offset of PCM data within the file */
int err;

/*
 * BUFFSIZE samples * 2 bytes per sample * 2 channels
 */
FLAC__byte buffer[BUFSIZE * 2 * 2];

/*
 * BUFFSIZE samples * 2 channels
 */
FLAC__int32 pcm[BUFSIZE * 2];


/*
 * Create and initialize the FLAC encoder
 */
encoder = FLAC__stream_encoder_new();
if (!encoder)
    return -1;


FLAC__stream_encoder_set_verify(encoder, true);
FLAC__stream_encoder_set_compression_level(encoder, 5);
FLAC__stream_encoder_set_channels(encoder, NUM_CHANNELS); // 2 for stereo
FLAC__stream_encoder_set_bits_per_sample(encoder, BITS_PER_SAMPLE); // 32 for stereo 16 bit per channel
FLAC__stream_encoder_set_sample_rate(encoder, SAMPLE_RATE);

status = FLAC__stream_encoder_init_stream(encoder, flac_callback, NULL, NULL, NULL, NULL);
if (status != FLAC__STREAM_ENCODER_INIT_STATUS_OK)
    return -1;


// We now start the Audio Queue...
status = AudioQueueStart(queue, NULL);

// And when it's finished, we clean up the FLAC encoder...
FLAC__stream_encoder_finish(encoder);
FLAC__stream_encoder_delete(encoder);

// and the audio queue and its belongings too
AudioQueueFlush(queue);
AudioQueueStop(queue, false);

for (i = 0; i < NUM_BUFFERS; i++)
    AudioQueueFreeBuffer(queue, buffers[i]);

AudioQueueDispose(queue, true);

// In the audio queue callback function, we do the encoding:

void audio_queue_callback(
    void *data,
    AudioQueueRef inAQ,
    AudioQueueBufferRef buffer,
    const AudioTimeStamp *start_time,
    UInt32 num_packets,
    const AudioStreamPacketDescription *desc
)
{
    unsigned char *buf = buffer->mAudioData;

    for (size_t i = 0; i < num_packets * channels; i++) {
        uint16_t msb = *(uint8_t *)(buf + i * 2 + 1);
        uint16_t usample = (msb << 8) | lsb;

        union {
            uint16_t usample;
            int16_t  ssample;
        } u;

        u.usample = usample;
        pcm[i] = u.ssample;
    }

    FLAC__bool succ = FLAC__stream_encoder_process_interleaved(encoder, pcm, num_packets);
    if (!succ)
        // handle_error();
}

// Finally, in the FLAC stream encoder callback:

FLAC__StreamEncoderWriteStatus flac_callback(
    const FLAC__StreamEncoder *encoder,
    const FLAC__byte buffer[],
    size_t bytes,
    unsigned samples,
    unsigned current_frame,
    void *client_data
)
{
    // Here process `buffer' and stuff,
    // then:

    return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
}

欢迎您。

这篇关于在iOS上使用Flac进行分块编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆