包装Speex语音与奥格在iOS(Packing Speex with Ogg on iOS)

2019-08-17 09:34发布

我使用libogg和libogg,我已经成功地使用这些库添加到我的iPhone Xcode项目和编码我的声音与Speex语音。 问题是,我无法弄清楚如何打包带OGG音频那些包。 是否有人知道那种数据包如何看起来还是有参考代码,我可以使用。

我知道在Java中这是非常简单的(你有一个专用的功能),而不是iOS上。 请帮忙。

Answer 1:

UPD 2013年9月10日:请参见演示项目 ,基本上采用PCM audiodata从波的容器中,Speex编解码器进行编码,并打包到一切OGG容器。 也许以后我会创造在IOS所有的Speex程序一个完整的库/框架。

UPD 2015年2月16日:演示项目重新发布在GitHub上。


我也一直在尝试的Speex在iOS近日,有不同程度的成功,但这里是我发现的。 基本上,如果你想带些Speex语音编码的语音转换成一个OGG文件,你需要做以下三个步骤(假设libogg和libspeex已经被编译并添加到项目中)。

1)与添加的Speex报头中的第一页OGG; libspeex提供了内置的工具为(下面的代码是从我的项目,不是最优的,只是举例的缘故):

// create speex header 
SpeexHeader spxHeader;
SpeexMode spxMode = speex_wb_mode;
int spxRate = 16000;
int spxNumberOfChannels = 1;
speex_init_header(&spxHeader, spxRate, spxNumberOfChannels, &spxMode);

// set audio and ogg packing parameters
spxHeader.vbr = 0;
spxHeader.bitrate = 16;
spxHeader.frame_size = 320;
spxHeader.frames_per_packet = 1;

// wrap speex header in ogg packet
int oggPacketSize;
_oggPacket.packet = (unsigned char *)speex_header_to_packet(&spxHeader, &oggPacketSize);
_oggPacket.bytes = oggPacketSize;
_oggPacket.b_o_s = 1;
_oggPacket.e_o_s = 0;
_oggPacket.granulepos = 0;
_oggPacket.packetno = 0;

// submit the packet to the ogg streaming layer
ogg_stream_packetin(&_oggStreamState, &_oggPacket);
free(_oggPacket.packet);

// form an ogg page
ogg_stream_flush(&_oggStreamState, &_oggPage);

// write the page to file
[_oggFile appendBytes:&_oggStreamState.header length:_oggStreamState.header_fill];
[_oggFile appendBytes:_oggStreamState.body_data length:_oggStreamState.body_fill];

2)添加与第二OGG页面Vorbis的评论 :

// form any comment you like (I use custom struct with all fields)
vorbisCommentStruct *vorbisComment = calloc(sizeof(vorbisCommentStruct), sizeof(char));
...

// wrap Vorbis comment in ogg packet
_oggPacket.packet = (unsigned char *)vorbisComment;
_oggPacket.bytes = vorbisCommentLength;
_oggPacket.b_o_s = 0;
_oggPacket.e_o_s = 0;
_oggPacket.granulepos = 0;
_oggPacket.packetno = _oggStreamState.packetno;

// the rest should be same as in previous step
...

3)添加随后OGG页用相似的方法您的Speex编码的音频。

首先,决定你想要多少帧与音频数据有每个OGG页面上(0-255;我选择79相当任意):

_framesPerOggPage = 79;

然后,对于每个帧:

// calculate current granule position of audio data within ogg file 
int curGranulePos = _spxSamplesPerFrame * _oggTotalFramesCount;

// wrap audio data in ogg packet
oggPacket.packet = (unsigned char *)spxFrame;
oggPacket.bytes = spxFrameLength;
oggPacket.granulepos = curGranulePos;
oggPacket.packetno = _oggStreamState.packetno;
oggPacket.b_o_s = 0;
oggPacket.e_o_s = 0;

// submit packets to streaming layer until their number reaches _framesPerOggPage
...

// if we've reached this limit, we're ready to create another ogg page

ogg_stream_flush(&_oggStreamState, &_oggPage);

[_oggFile appendBytes:&_oggStreamState.header length:_oggStreamState.header_fill];
[_oggFile appendBytes:_oggStreamState.body_data length:_oggStreamState.body_fill];

// finally, if this is the last frame, flush all remaining packets,
// which have been created but not packed into a page, to the last page 
// (don't forget to set oggPacket.e_o_s to 1 for this frame)

而已。 希望这将有助于。 任何更正或疑问,欢迎。



文章来源: Packing Speex with Ogg on iOS
标签: ogg speex jspeex