opus

OpusEncoder

1:獲得 OpusEncoder結(jié)構(gòu)的大小

   int opus_encoder_get_size (int channels); 

2:分配和初始化 encoder狀態(tài).
一個(gè)編碼器狀態(tài)在同一時(shí)間不得用于多于一個(gè)音頻流挥下。同樣,編碼器狀態(tài)不能對(duì)于每幀重新初始化蒋院。

  OpusEncoder* opus_encoder_create (opus_int32 Fs, int channels, int application, int *error);

[in] Fs opus_int32: 輸入信號(hào)的采樣率 (Hz)跑慕,必須是8000瞧筛、12000、16000瓦灶、24000奶陈、或48000。
[in] channels int:輸入信號(hào)的通道數(shù) (1 or 2)
[in] application int:編碼模式(OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY)
[out] error int*: 錯(cuò)誤代碼
注意:無(wú)論選擇什么樣的采樣率和通道數(shù), 如果選擇的比特率太低蔚舀,Opus編碼器可以切換到一個(gè)較低的音頻帶寬或通道數(shù)饵沧。這也意味著總是使用48 kHz立體聲輸入和讓編碼器優(yōu)化編碼是安全的。
application:編碼模式(三種):
OPUS_APPLICATION_VOIP:在給定比特率條件下為聲音信號(hào)提供最高質(zhì)量赌躺,它通過(guò)高通濾波和強(qiáng)調(diào)共振峰和諧波增強(qiáng)了輸入信號(hào)狼牺。它包括帶內(nèi)前向錯(cuò)誤檢查以預(yù)防包丟失。典型的VOIP應(yīng)用程序使用這種模式寿谴。由于進(jìn)行了增強(qiáng)锁右,即使是高比特率的情況下,輸出的聲音與輸入相比,聽(tīng)起來(lái)可能不一樣咏瑟。
OPUS_APPLICATION_AUDIO:對(duì)大多數(shù)非語(yǔ)音信號(hào)拂到,如音樂(lè),在給定比特率條件下提供了最高的質(zhì)量码泞。使用這種模式的場(chǎng)合包括音樂(lè)兄旬、混音(音樂(lè)/聲音),廣播,和需要不到15 毫秒的信號(hào)延遲的其他應(yīng)用。
OPUS_APPLICATION_RESTRICTED_LOWDELAY:配置低延遲模式將為減少延遲禁用語(yǔ)音優(yōu)化模式余寥。這種模式只能在剛初始化或剛重設(shè)編碼器的情況下使用领铐,因?yàn)樵谶@些情況下編解碼器的延遲被修改了

3:初始化一個(gè)以前分配的編碼器狀態(tài)。
所指向的內(nèi)存必須至少是opus_encoder_get_size()返回的大小.
int opus_encoder_init (OpusEncoder *st, opus_int32 Fs, int channels, int application)
4:對(duì)一個(gè) Opus幀進(jìn)行編碼
opus_int32 opus_encode (OpusEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes)
5:根據(jù)浮點(diǎn)輸入對(duì)一個(gè) Opus幀進(jìn)行編碼
opus_int32 opus_encode_float (OpusEncoder *st, const float *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes)
6:釋放一個(gè)根據(jù)opus_encoder_create()已分配的OpusEncoder 對(duì)象宋舷。
void opus_encoder_destroy (OpusEncoder *st)
7:改變一些編碼器的參數(shù)設(shè)置绪撵。
所有這些參數(shù)都已有缺省值,所以只在必要的情況下改變它們
int opus_encoder_ctl (OpusEncoder *st, int request,...)

opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate)); //(比特率)的單位是比特/秒(b / s)
opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); //(復(fù)雜性)是一個(gè)值從1到10,1最低祝蝠,10最高音诈,值越大越復(fù)雜
opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type));(信號(hào)的類(lèi)型)包括OPUS_AUTO (缺省), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC

8:為了對(duì)一個(gè)幀進(jìn)行編碼,必須正確地用音頻數(shù)據(jù)的幀(2.5, 5, 10, 20, 40 或60 毫秒)來(lái)調(diào)用
opus_encode()opus_encode_float()函數(shù)绎狭。

//audio_frame(音頻幀)是opus_int16(或用于```opus_encode_float()```的浮點(diǎn))格式的音頻數(shù)據(jù)
//frame_size(幀大邢附Α)是樣本中幀的最大數(shù)(每個(gè)通道)
//packet(包)是寫(xiě)成壓縮數(shù)據(jù)的字節(jié)數(shù)組
//max_packet是可以寫(xiě)入包的字節(jié)數(shù)的最大值推薦(4000字節(jié))。不要使用max_packet控制VBR的目標(biāo)比特率,而應(yīng)該用OPUS_SET_BITRATE CTL
opus_encode(enc, audio_frame, frame_size, packet, max_packet)

opus_encode()opus_encode_float()返回實(shí)際寫(xiě)入包的字節(jié)數(shù)儡嘶。返回值可以是負(fù)數(shù),這表明一個(gè)錯(cuò)誤已經(jīng)發(fā)生喇聊。如果返回值是1個(gè)字節(jié),那么包不需要傳播(DTX)。
一旦一個(gè)編碼器狀態(tài)已不再需要蹦狂,可以用以下方式解構(gòu):
opus_encoder_destroy(enc);
如果編碼器是用opus_encoder_init()創(chuàng)建的誓篱,而不是使用opus_encoder_create()函數(shù),那么不需要采取行動(dòng)鸥咖,要求從潛在的釋放為它手動(dòng)分配的內(nèi)存(上述例子是調(diào)用 free(enc))中分離燕鸽。

////////////////////////////////////////////////////////////////////////////////////////////////////////

OpusDecoder

1:獲得OpusDecoder 結(jié)構(gòu)的大小
int opus_decoder_get_size (int channels)
2: 分配和初始化解碼器狀態(tài)
OpusDecoder *opus_decoder_create (opus_int32 Fs, int channels, int *error)
[out] error int*:成功時(shí)是 OPUS_OK Success或錯(cuò)誤代碼
Opus在內(nèi)部用48000 Hz來(lái)存儲(chǔ)數(shù)據(jù),所以對(duì)于FS來(lái)說(shuō)48000 Hz是缺省值啼辣。
然而,解碼器在8, 12, 16, 和 24 kHz下也可以有效解碼到緩沖御滩,所以鸥拧,由于某些原因調(diào)用者不能在全采樣率下使用數(shù)據(jù),
或知道被壓縮的數(shù)據(jù)不能在全頻率范圍內(nèi)使用削解,可以請(qǐng)求用更小的頻率解碼富弦。同樣的,解碼器可以根據(jù)調(diào)用者的請(qǐng)求氛驮,
填充單聲道或交叉立體聲的PCM緩沖區(qū)腕柜。
3:初始化以前分配的解碼器狀態(tài)
int opus_decoder_init (OpusDecoder *st, opus_int32 Fs, int channels)
4:解碼一個(gè) Opus 包

/*
st: 解碼器狀態(tài)
data 是包含壓縮數(shù)據(jù)的字節(jié)數(shù)組,輸入負(fù)載.對(duì)包丟失使用一個(gè)空指針來(lái)表示。
len 是包內(nèi)字節(jié)的精確數(shù)量盏缤,在輸入負(fù)載中的字節(jié)數(shù)
pcm 是opus_int16 (或由 opus_decode_float()定義的浮點(diǎn)型)格式的解碼后的音頻數(shù)據(jù)砰蠢。 
            輸出信號(hào)(如果是2通道有交叉)。長(zhǎng)度等于frame_size*channels*sizeof(opus_int16)
frame_size是可以放入解碼幀的每個(gè)通道各樣本中幀的最大值唉铜,在PCM可用空間中每通道的樣本數(shù)台舱。
            如果小于最大包的時(shí)長(zhǎng)(120毫秒,4848kHz5760個(gè))潭流,這個(gè)函數(shù)將不能解碼一些包竞惋。
            如果是PLC (data==NULL) 或 FEC (decode_fec=1)的情況,那么frame_size必須正好是丟失音頻的時(shí)長(zhǎng)灰嫉,
            否則解碼器無(wú)法在解碼下一個(gè)包時(shí)進(jìn)入優(yōu)化狀態(tài)拆宛。對(duì)于PLC 和 FEC 的情況,frame_size必須是2.5毫秒的倍數(shù)讼撒。
decode_fec 對(duì)于請(qǐng)求任何帶內(nèi)前向錯(cuò)誤糾正數(shù)據(jù)進(jìn)行解碼的狀態(tài)標(biāo)志 (0 or 1) 
            如果沒(méi)有這樣的數(shù)據(jù)可用浑厚,幀在解碼時(shí)被認(rèn)為已經(jīng)丟失
*/
int opus_decode (OpusDecoder *st, const unsigned char *data, opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)

5:解碼一個(gè)浮點(diǎn)輸出的Opus 包

int opus_decode_float (OpusDecoder *st, const unsigned char *data, opus_int32 len, float *pcm, int frame_size, int decode_fec)

(1)opus_decode()和opus_decode_float() 返回從包解碼后的每通道樣本的數(shù)量。如果這個(gè)值是負(fù)的椿肩,表示有錯(cuò)誤發(fā)生瞻颂。
如果包損壞或音頻緩沖太小不足以容納解碼后的音頻,錯(cuò)誤就會(huì)發(fā)生郑象。
Opus是包含重疊塊的有狀態(tài)的編解碼器贡这,其結(jié)果是Opus 包并不是彼此獨(dú)立編碼。
包必須按正確的次序厂榛,連續(xù)地進(jìn)入解碼器進(jìn)行正確的解碼盖矫。丟失的包可以用遺失隱藏來(lái)替換,遺失隱藏用一個(gè)空的指針和0長(zhǎng)度的包來(lái)調(diào)用解碼器击奶。
(2)一個(gè)單獨(dú)的編解碼器狀態(tài)在一個(gè)時(shí)間只能由一個(gè)單獨(dú)的線程來(lái)訪問(wèn)辈双,調(diào)用者執(zhí)行任何需要的鎖定。
各分開(kāi)的音頻數(shù)據(jù)流可以用各自分開(kāi)的解碼器狀態(tài)平行地進(jìn)行解碼柜砾,除非API庫(kù)在編譯時(shí)用了NONTHREADSAFE_PSEUDOSTACK定義湃望。

6:向一個(gè)Opus解碼器執(zhí)行CTL 函數(shù)
int opus_decoder_ctl (OpusDecoder *st, int request,...)
7:釋放通過(guò)opus_decoder_create().分配過(guò)的OpusDecoder
void opus_decoder_destroy (OpusDecoder *st)
8:將一個(gè) opus 包解析成1個(gè)或多個(gè)幀

/*
[in]    data    char*:要進(jìn)行解析的 Opus包
[in]    len    opus_int32: 數(shù)據(jù)的大小
[out]    out_toc    char*: TOC 指針
[out]    frames    char*[48] 封裝過(guò)的幀
[out]    size    short[48] 封裝過(guò)的幀的大小
[out]    payload_offset    int*: 返回在包內(nèi)負(fù)載的位置(按字節(jié))
返回: 幀的數(shù)量
*/
int opus_packet_parse (const unsigned char *data, opus_int32 len, unsigned char *out_toc, const unsigned char *frames[48], short size[48], int *payload_offset);

Opus_decode在內(nèi)部執(zhí)行這個(gè)操作,所以大多數(shù)應(yīng)用程序不需要用到這個(gè)函數(shù)痰驱。這個(gè)函數(shù)不復(fù)制各幀证芭,返回的指針是輸入包內(nèi)部的指針。

9:獲得一個(gè) Opus包的帶寬

/* 
[in]    data    char*: Opus 包
返回值:
OPUS_BANDWIDTH_NARROWBAND    窄帶 (4kHz bandpass)
OPUS_BANDWIDTH_MEDIUMBAND    中等帶寬 (6kHz bandpass)
OPUS_BANDWIDTH_WIDEBAND    寬帶 (8kHz bandpass)
OPUS_BANDWIDTH_SUPERWIDEBAND    高寬帶 (12kHz bandpass)
OPUS_BANDWIDTH_FULLBAND    全寬帶 (20kHz bandpass)
OPUS_INVALID_PACKET    通過(guò)的被壓縮數(shù)據(jù)已損壞或其格式不被支持
*/
int opus_packet_get_bandwidth (const unsigned char *data)

1:獲得Opus 包每幀的樣本數(shù)
int opus_packet_get_samples_per_frame (const unsigned char *data, opus_int32 Fs)
2:獲得Opus 包的通道數(shù)

/*
[in]    dec    OpusDecoder*: 解碼器狀態(tài)
[in]    packet    char*: Opus包
[in]    len    opus_int32: 包的長(zhǎng)度
返回:樣本的數(shù)量
返回值:OPUS_INVALID_PACKET:通過(guò)的被壓縮數(shù)據(jù)已損壞或其格式不被支持担映。
*/
int opus_packet_get_nb_channels (const unsigned char *data)

3:獲得Opus 包所有幀的數(shù)量
int opus_packet_get_nb_frames (const unsigned char packet[], opus_int32 len)
4:獲得Opus 包的樣本數(shù)
int opus_packet_get_nb_samples (const unsigned char packet[], opus_int32 len, opus_int32 Fs)
5:獲得Opus 包的樣本數(shù)
int opus_decoder_get_nb_samples (const OpusDecoder *dec, const unsigned char packet[], opus_int32 len)
Multistream API允許將多個(gè)Opus數(shù)據(jù)流組合成一個(gè)包废士,能夠支持多達(dá)255通道
多流Opus包的格式是定義在Ogg封裝的規(guī)格,也是基于RFC 6716附錄B所闡述的自限定Opus框架蝇完。標(biāo)準(zhǔn)的Opus包正好是多流Opus包的退化版本官硝,可以用對(duì)流API進(jìn)行編碼和解碼矗蕊,只要在初始化編碼器和解碼器時(shí)將流數(shù)量設(shè)置為1.
編碼器的輸出通道應(yīng)使用Vorbis(免費(fèi)音樂(lè)格式)的通道規(guī)則。解碼器可能希望應(yīng)用一個(gè)附加的排列以映射用于實(shí)現(xiàn)不同輸出通道規(guī)則的編碼器(例如用于WAV規(guī)則的輸出)
多流包包含對(duì)應(yīng)每個(gè)流的各Opus包氢架,在單一多流包內(nèi)的所有Opus包必須有相同的時(shí)長(zhǎng)傻咖。因此,一個(gè)多流包的時(shí)長(zhǎng)可以從位于包開(kāi)始位置的第一個(gè)流的TOC序列提取达箍,就象一個(gè)基本的Opus流

1:獲得OpusMSEncoder結(jié)構(gòu)的大小
opus_int32 opus_multistream_encoder_get_size (int streams, int coupled_streams)
2:分配和初始化多流編碼器狀態(tài)
OpusMSEncoder *opus_multistream_encoder_create (opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int application, int *error)
3:初始化以前分配的多流編碼器狀態(tài)
int opus_multistream_encoder_init (OpusMSEncoder *st, opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int application)
4:編碼一個(gè)多流Opus幀
int opus_multistream_encode (OpusMSEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes)
5:從浮點(diǎn)型輸入編碼一個(gè)多流Opus幀
int opus_multistream_encode_float (OpusMSEncoder *st, const float *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes)
** 6: 釋放經(jīng)opus_multistream_encoder_create () 分配過(guò)的OpusMSEncoder **
void opus_multistream_encoder_destroy (OpusMSEncoder *st)
7:向一個(gè)多流Opus編碼器執(zhí)行CTL 函數(shù)
int opus_multistream_encoder_ctl (OpusMSEncoder *st, int request,...)

///////////////////////////////////////////////////////////////////////////////////////////////////

opus_int32 opus_multistream_decoder_get_size (int streams, int coupled_streams)
OpusMSDecoder *opus_multistream_decoder_create (opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping, int *error)
int opus_multistream_decoder_init (OpusMSDecoder *st, opus_int32 Fs, int channels, int streams, int coupled_streams, const unsigned char *mapping)
int opus_multistream_decode (OpusMSDecoder *st, const unsigned char *data, opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
int opus_multistream_decode_float (OpusMSDecoder *st, const unsigned char *data, opus_int32 len, float *pcm, int frame_size, int decode_fec)
int opus_multistream_decoder_ctl (OpusMSDecoder *st, int request,...)
void opus_multistream_decoder_destroy (OpusMSDecoder *st)
OPUS_SET_COMPLEXITY
OPUS_SET_BITRATE
OPUS_SET_VBR
OPUS_SET_VBR_CONSTRAINT
OPUS_SET_PACKET_LOSS_PERC
OPUS_SET_MAX_BANDWIDTH

OPUS_SET_FORCE_CHANNELS
OPUS_SET_BANDWIDTH
OPUS_SET_SIGNAL
OPUS_SET_APPLICATION
OPUS_SET_INBAND_FEC
OPUS_SET_DTX
OPUS_SET_LSB_DEPTH
OPUS_SET_EXPERT_FRAME_DURATION
OPUS_SET_PREDICTION_DISABLED

1. 簡(jiǎn)介

SILK 是Skype 內(nèi)部開(kāi)發(fā)的一個(gè)語(yǔ)音頻編解碼器没龙,作為Skype 到Skype 調(diào)用的默認(rèn)編解碼器。SILK 在音頻帶寬缎玫、網(wǎng)絡(luò)碼率和復(fù)雜度等方面的高度可擴(kuò)展性使其成為可選擇多種模式和應(yīng)用的編解碼器硬纤。
Skype 鼓勵(lì)第三方合作伙伴組織(3GPP)在可能與Skype 互操作的網(wǎng)絡(luò)中采用SILK。因此赃磨,本文件定義了將SILK 語(yǔ)音頻編碼數(shù)據(jù)打包所用的RTP 負(fù)載格式和文件存儲(chǔ)格式筝家,這些數(shù)據(jù)是以最兼容方式實(shí)現(xiàn)SILK 必不可少的。本文件進(jìn)一步描述了RTP 負(fù)載格式和文件存儲(chǔ)格式媒體類(lèi)型注冊(cè)邻辉。
關(guān)于SILK 的更多信息可以通過(guò)以下鏈接獲得:
https://developer.skype.com/silk

2. 本文件使用的公約溪王、定義和縮略語(yǔ)

本文件中出現(xiàn)的關(guān)鍵詞“MUST”,“MUST NOT”值骇,“REQUIRED”莹菱,“SHALL”,“SHALL NOT”吱瘩,“SHOULD”道伟,“SHOULD NOT”,“RECOMMEDED”使碾,“MAY”蜜徽,“OPTIONAL”的解釋參見(jiàn)RFC 2119 [1]。
定義和縮略詞:
CPU —— 中央處理單元
IP —— 網(wǎng)絡(luò)協(xié)議
MTU —— 最大傳輸單元
PSTN —— 公共交換電話網(wǎng)
Samples —— 語(yǔ)音或音頻采樣點(diǎn)
SDP —— 會(huì)話描述協(xié)議

3. SILK 編解碼器

SILK 語(yǔ)音頻編解碼器在音頻帶寬票摇、網(wǎng)絡(luò)碼率和復(fù)雜度等方面具有高度的可擴(kuò)展性拘鞋。
SILK 支持四種不同的音頻帶寬:窄帶8000 Hz 采樣率,中帶12000 Hz 采樣率矢门,寬帶16000 Hz 采樣率盆色,超寬帶24000 Hz 采樣率。窄帶模式應(yīng)該(SHOULD)只用于PSTN 網(wǎng)絡(luò)的接口或者用在不支持大于8000 Hz 采樣率的低端設(shè)備上祟剔。中帶模式應(yīng)該(SHOULD)用于不支持大于12000 Hz 采樣率的更低端設(shè)備或者嚴(yán)重的網(wǎng)絡(luò)帶寬限制的條件下(例如無(wú)線設(shè)備)傅事。寬帶模式應(yīng)該(SHOULD)用于所有不支持大于16000 Hz 采樣率的所有網(wǎng)絡(luò)協(xié)議平臺(tái)。超寬帶模式應(yīng)該(SHOULD)用于所有支持24000 Hz 或者更高采樣率的平臺(tái)峡扩。
平均目標(biāo)網(wǎng)絡(luò)碼率在表1 對(duì)應(yīng)音頻帶寬下規(guī)定的范圍內(nèi)是可變的。平均網(wǎng)絡(luò)目標(biāo)碼率可以實(shí)時(shí)定義和修正障本,而實(shí)際碼率依賴(lài)于輸入信號(hào)教届,且隨時(shí)間而改變响鹃。實(shí)際碼率可能高于或低于表1 規(guī)定的自適應(yīng)目標(biāo)碼率。推薦采用表中碼率范圍的上限案训。

表1. fs 代表以赫茲為單位的采樣率买置,BR 代表以千位每秒為單位的自適應(yīng)目標(biāo)碼率范圍

Fs (Hz) BR (kbps)
8000 5 – 20 窄帶
12000 7 – 25 中帶
16000 8 – 30 寬帶
24000 20 – 40 超寬帶

復(fù)雜度可擴(kuò)展用于實(shí)時(shí)優(yōu)化CPU 資源,多用于與網(wǎng)絡(luò)碼率的權(quán)衡强霎。
SILK 內(nèi)部幀長(zhǎng)為20 ms忿项。SILK 編碼器可以設(shè)置為捆綁5 個(gè)內(nèi)部幀為一個(gè)輸出幀,允許編碼語(yǔ)音頻數(shù)據(jù)的幀長(zhǎng)為20城舞,40轩触,60,80家夺,100 ms脱柱。表2 顯示了不同幀長(zhǎng)和采樣率時(shí)一幀語(yǔ)音或者音頻包含的采樣點(diǎn)數(shù)。

表2. 不同幀長(zhǎng)和采樣率時(shí)拉馋,一幀包含的采樣點(diǎn)數(shù)

幀長(zhǎng) 20ms 40ms 60ms 80ms 120ms
窄帶采樣點(diǎn) 160 320 480 640 800
中帶采樣點(diǎn) 240 480 720 960 1200
寬帶采樣點(diǎn) 320 640 960 1280 1600
超寬帶采樣點(diǎn) 480 960 1440 1920 2400

SILK 操作在非常低的算法延遲榨为,包括算法打包延遲(例如20,40煌茴,60随闺,80,100 ms)加上5 ms 前瞻延遲蔓腐。

3.1.自適應(yīng)采樣頻率

SILK 編碼的語(yǔ)音頻信號(hào)內(nèi)部采樣率可以隨著傳輸時(shí)間而變化矩乐,這可能在以下兩種情況下發(fā)生。
第一種情況是合住,SILK 提供一種內(nèi)部邏輯绰精,決定自動(dòng)將編碼的語(yǔ)音頻信號(hào)內(nèi)部采樣率調(diào)整到最有效的采樣率,這個(gè)最有效采樣率取決于輸入信號(hào)和信道容量信息透葛。
這種內(nèi)部邏輯使得SILK 支持擁塞控制和網(wǎng)絡(luò)負(fù)荷管理笨使。
第二種情況是,SILK 提供手動(dòng)設(shè)置編碼的語(yǔ)音頻信號(hào)最大內(nèi)部采樣率的API 功能僚害。這個(gè)最大內(nèi)部采樣率不能(MUST NOT)被設(shè)置高于呼叫建立協(xié)商時(shí)商定的采樣率硫椰,
這是因?yàn)镾ILK 的早期版本不能解碼內(nèi)部采樣率高于解碼端輸出采樣率(解碼器API 采樣率)的信號(hào)。
對(duì)于以上兩種情況萨蚕,只有被編碼成碼流的語(yǔ)音頻信號(hào)的內(nèi)部采樣率被切換時(shí)靶草,SILK 編碼器輸入的語(yǔ)音頻信號(hào)和解碼器輸出的語(yǔ)音頻信號(hào)的采樣率才能單獨(dú)設(shè)置而互不影響。
會(huì)話建立的時(shí)候岳遥,解碼端應(yīng)該(SHOULD)將系統(tǒng)可以利用的所有采樣率(率參數(shù))發(fā)信號(hào)給給編碼端

3.2.自適應(yīng)網(wǎng)絡(luò)碼率

SILK 編碼器可以設(shè)置不同的平均目標(biāo)碼率輸出編碼的語(yǔ)音頻數(shù)據(jù)奕翔。規(guī)定的平均目標(biāo)碼率是為積極信號(hào)(例如非靜音幀)設(shè)置的,
因此每一幀的實(shí)際碼率根據(jù)數(shù)據(jù)語(yǔ)音頻信號(hào)的感知重要性而變化浩蓉。平均目標(biāo)碼率可以以幀為單位進(jìn)行調(diào)整派继,這使SILK 支持擁塞控制和網(wǎng)絡(luò)負(fù)荷管理宾袜。
為了有效的實(shí)現(xiàn)這些,必須提供信道容量和存儲(chǔ)設(shè)備的相關(guān)信息驾窟。這些信息可以通過(guò)多種渠道獲得庆猫,但不再本文件討論范圍。
當(dāng)無(wú)法獲得信道容量信息時(shí)绅络,SILK 可以以固定的平均目標(biāo)碼率運(yùn)行月培。這個(gè)固定的平均目標(biāo)碼率必須謹(jǐn)慎選擇,因?yàn)槌^(guò)信道容量時(shí)可能導(dǎo)致額外的延遲和語(yǔ)音幀丟失恩急。
除非最寬帶寬網(wǎng)絡(luò)接口技術(shù)的信道限制是已知的杉畜,否則推薦使用表1 中提供的最大平均目標(biāo)碼率達(dá)到最好的語(yǔ)音音質(zhì)。

3.3.不連續(xù)傳輸(DTX)

SILK 編解碼器是碼率自適應(yīng)的假栓。對(duì)于特定的輸入信號(hào)寻行,比如靜音周期,碼率會(huì)被自動(dòng)削減匾荆。在連續(xù)傳輸模式下拌蜘,當(dāng)輸入信號(hào)允許的時(shí)候,編碼器會(huì)削減碼率牙丽,
但是简卧,到接收器的傳輸不會(huì)被中斷。因此烤芦,接收到的信號(hào)在全部傳輸過(guò)程中使碼率最小化但保持較高水平的音質(zhì)举娩。
在SILK 的平均碼率需要進(jìn)一步削減的情況下,SILK 編碼器可以設(shè)置成不連續(xù)傳輸(DTX)构罗,此時(shí)部分編碼信號(hào)铜涉,即輸入語(yǔ)音頻信號(hào)的靜音周期,不被傳送到接收端遂唧。
在接收端芙代,沒(méi)有傳送的部分將被SILK 解碼器當(dāng)作丟失幀處理,即產(chǎn)生舒適噪聲信號(hào)代替沒(méi)有傳送的語(yǔ)音頻信號(hào)部 分盖彭。
SILK 的不連續(xù)傳輸模式的語(yǔ)音頻音質(zhì)會(huì)比連續(xù)模式稍差纹烹。因此,推薦(RECOMMENDED)使用SILK 的連續(xù)模式召边,除非網(wǎng)絡(luò)帶寬的限制比較嚴(yán)格铺呵。

3.4.前向差錯(cuò)糾正(FEC)

SILK 編解碼器允許在SILK 碼流中嵌入“帶內(nèi)”前向差錯(cuò)糾正(FEC)數(shù)據(jù)。這種FEC 方案將前一幀(n-1)或者前兩幀(n-2)的冗余信息加到當(dāng)前幀(n)隧熙。
對(duì)于每一幀片挂,編碼器根據(jù)以下信息決定是否使用FEC :(1)外部提供的信道丟包率估計(jì)值;(2)外部提供的信道容量估計(jì)值贞盯;(3)語(yǔ)音頻信號(hào)對(duì)丟包的敏感度宴卖;
(4)接收端解碼器是否顯示可以利用“帶內(nèi)”FEC 信息滋将。發(fā)送“帶內(nèi)”FEC 信息的決定完全受編碼器控制,因此不需要關(guān)于負(fù)載或存儲(chǔ)格式的特殊注意事項(xiàng)症昏。
在接收端,當(dāng)某一幀丟失而未來(lái)幀可接收到的時(shí)候父丰,解碼器可以利用這些附加信息肝谭。為了使用FEC 數(shù)據(jù),抖動(dòng)緩沖區(qū)需要提供包含SILK
未來(lái)幀的負(fù)載和相對(duì)SIK 上一解碼幀偏移量的信息蛾扇。
一個(gè)特殊的API 函數(shù)可以搜索可用的FEC 數(shù)據(jù)攘烛,如果搜索成功的話,可以作為當(dāng)前丟失幀提供給解碼器镀首。
如果這種FEC 方案沒(méi)有在接收端實(shí)現(xiàn)的話坟漱,F(xiàn)EC不應(yīng)該(SHOULD NOT)被使用,因?yàn)樗鼘?dǎo)致網(wǎng)絡(luò)帶寬的低效使用更哄。解碼器支持FEC 的話芋齿,應(yīng)該(SHOULD)在會(huì)話建立的時(shí)候顯示。

光脈沖數(shù)字信號(hào)在光纖傳輸過(guò)程中成翩,會(huì)受到各種不利因素的劣化影響觅捆,這些不利影響有外界的也有內(nèi)部的,也有外界的干擾信號(hào)麻敌,
內(nèi)部有電路的熱噪聲栅炒、EDFA的ASE噪聲及模分配噪聲、光纖衰耗和色散的影響等术羔,這些不利因素會(huì)使傳輸質(zhì)量下降赢赊,如接收端的光功率減少、光脈沖發(fā)生畸變级历、光信噪比降低等释移,
導(dǎo)致接收端出現(xiàn)誤碼,減少系統(tǒng)的傳輸距離鱼喉。從誤碼發(fā)生性質(zhì)看秀鞭,可分為兩類(lèi):1、隨機(jī)性誤碼2扛禽、突發(fā)性誤碼
誤碼糾錯(cuò)方法通常用三種:1锋边、自動(dòng)請(qǐng)求重發(fā)(ARQ)2、前向糾錯(cuò)(FEC)3编曼、混合糾錯(cuò)(HEC)豆巨。在海纜傳輸中主要使用前向糾錯(cuò)FEC比較多。
波分設(shè)備或者海纜SLTE/LTU設(shè)備收高誤碼掐场,其相連的SDH設(shè)備極大可能沒(méi)有誤碼往扔,因?yàn)槭盏降恼`碼經(jīng)過(guò)FEC糾錯(cuò)后就變成沒(méi)有誤碼的“好信號(hào)”傳給SDH了贩猎,SDH就沒(méi)有告警和任何誤碼了。

前向糾錯(cuò)主要是利用軟件技術(shù)(也需少量硬件)在發(fā)送端對(duì)輸入信息進(jìn)行編碼萍膛,在接收端再對(duì)之進(jìn)行解碼吭服,從而獲得增益,達(dá)到降低系統(tǒng)誤碼率蝗罗、增加傳輸距離的目的艇棕。
前向糾錯(cuò)(FEC)是指利用軟件技術(shù)在發(fā)送端對(duì)信源信息進(jìn)行一定形式的編碼(如BCH編碼、R-S編碼)串塑,
然后用新的編碼流進(jìn)行傳輸沼琉,在接收端再進(jìn)行解碼與糾錯(cuò),以此獲得增益從而增加系統(tǒng)的傳輸距離桩匪。
帶內(nèi)FEC與帶外FEC
對(duì)于SDH而言打瘪,F(xiàn)EC有帶內(nèi)與帶外之分。
帶內(nèi)FEC指對(duì)信源信息進(jìn)行編碼后的冗余碼傻昙,存放于SDH段開(kāi)銷(xiāo)中的某些尚未使用的字節(jié)中闺骚,帶內(nèi)FEC常用BCH編碼方法。
由于帶內(nèi)FEC可供使用的字節(jié)數(shù)量有限屋匕,所以它的編碼增益不高葛碧。
帶外FEC指把對(duì)SDH信息進(jìn)行編碼后的冗余碼放在SDH幀結(jié)構(gòu)的外部,然后把冗余碼與信息碼組合在一起形成新的幀信號(hào)進(jìn)行傳輸过吻。
帶外FEC通常采用R-S編碼方法进泼。由于帶外FEC的冗余碼數(shù)量可以很大,所以它的糾錯(cuò)能力遠(yuǎn)高于帶內(nèi)FEC纤虽。帶外FEC的缺點(diǎn)是增加了系統(tǒng)的傳輸速率乳绕。
對(duì)于WDM系統(tǒng)而言,采用FEC編碼所獲得的增益主要用于對(duì)OSNR的改善逼纸,以增加系統(tǒng)的傳輸距離洋措。
編碼分為信源編碼和信道編碼。FEC編碼屬于信道編碼杰刽,F(xiàn)EC編碼可理解是把信息包進(jìn)行再包裝菠发,使得傳輸時(shí)更加可靠穩(wěn)定,不易損壞或者破碎(糾正誤碼)贺嫂,
使得接收者收到時(shí)物品(通信質(zhì)量)完美滓鸠。 同時(shí)包裝使得物體體積更大(可理解為傳輸速率更大),使得要傳輸?shù)男畔⒘肯鄬?duì)而言會(huì)減少第喳。
通過(guò)FEC編碼降低誤碼率糜俗,提高通信可靠性。前向糾錯(cuò)(FEC)編碼,發(fā)送端編碼器將信息碼組編成具有一定糾錯(cuò)能力的碼字悠抹,接收端譯碼時(shí)對(duì)接收馬子進(jìn)行譯碼珠月,
若傳輸中產(chǎn)生的差錯(cuò)數(shù)目在碼的糾錯(cuò)能力之內(nèi)時(shí),譯碼器對(duì)差錯(cuò)進(jìn)行定位并加以糾正楔敌。

Opus的內(nèi)核包含兩種編碼方式啤挎,分別是CELT和SILK,它會(huì)根據(jù)不同的信號(hào)類(lèi)型(語(yǔ)音梁丘、音樂(lè))來(lái)采用不同的音頻壓縮方式侵浸。CELT與MP3功能類(lèi)似,負(fù)責(zé)音樂(lè)存儲(chǔ)氛谜,而SILK會(huì)在編碼之前優(yōu)化語(yǔ)音信號(hào)。
  音樂(lè)和語(yǔ)音
  CELT編碼可以實(shí)時(shí)壓縮音樂(lè)区端。為了達(dá)到該目標(biāo)值漫,它將數(shù)據(jù)打包為小的音頻幀,從而保證只有2.5ms的延遲织盼。
  SILK編碼首先降低采用頻率到16kHz杨何,然后才開(kāi)始真正的編碼過(guò)程。
  語(yǔ)音編碼
  語(yǔ)音信號(hào)在正式編碼之前沥邻,首先要經(jīng)過(guò)SILK編碼器的詳細(xì)分解危虱。
  語(yǔ)音識(shí)別 將語(yǔ)音與周?chē)h(huán)境噪音分隔開(kāi)。
  音高分析 降低語(yǔ)音幀的采樣率唐全。
  噪聲分析 優(yōu)化噪聲到相應(yīng)的比特率埃跷。
  預(yù)過(guò)濾器 調(diào)整信號(hào),然后將其轉(zhuǎn)移到編碼區(qū)邮利。
  音高預(yù)測(cè) 通過(guò)目前的音頻幀計(jì)算未來(lái)的音頻幀變化弥雹。
  頻率量化 使傳輸?shù)囊舾咦兊闷椒€(wěn)。
  失真優(yōu)化 確保在可接受的語(yǔ)音失真內(nèi)采用最低比特率延届。
  噪音量化 調(diào)整預(yù)過(guò)濾的噪聲與已編碼的語(yǔ)音幀剪勿。
  區(qū)域編碼 處理每一個(gè)已編碼的音頻幀信號(hào)。
  音頻編碼對(duì)比
  與其他的音頻編碼方式相比方庭,Opus在低延遲情況下覆蓋了所有的比特率厕吉。手機(jī)的語(yǔ)音編碼相對(duì)是快的,但是很難達(dá)到較高的通話質(zhì)量械念,而傳統(tǒng)的音頻編碼則在實(shí)時(shí)性上有欠缺头朱。
  新的音頻編碼標(biāo)準(zhǔn)Opus比傳統(tǒng)的MP3和AAC編碼更高效,尤其適用于網(wǎng)絡(luò)音頻傳輸订讼。更重要的是髓窜,它是一個(gè)完全開(kāi)放的標(biāo)準(zhǔn)。
  包括VoIP、在線音樂(lè)寄纵、有聲讀物和播客(Podcasts)等在內(nèi)鳖敷,網(wǎng)絡(luò)流量中相當(dāng)大的一部分貢獻(xiàn)給了音頻傳輸。上面提到的這幾項(xiàng)操作程拭,在快速的DSL線路上可以流暢地進(jìn)行定踱。
但如果使用的是蜂窩數(shù)據(jù)連接,VoIP通話就難免會(huì)產(chǎn)生令人不爽的延遲恃鞋,在線音樂(lè)也會(huì)變得時(shí)斷時(shí)續(xù)崖媚。
不過(guò),現(xiàn)在已經(jīng)有一種名為Opus的音頻編碼會(huì)解決這些問(wèn)題恤浪。它的最大優(yōu)勢(shì)是可以利用更小的帶寬帶來(lái)更高質(zhì)量的音頻畅哑,而且可以實(shí)時(shí)進(jìn)行。
除此之外水由,Opus本身的編碼是完全開(kāi)源的荠呐,開(kāi)發(fā)者不需要擔(dān)心任何專(zhuān)利授權(quán)的問(wèn)題。
  從一開(kāi)始砂客,Opus編碼就是為交互式音頻傳輸而開(kāi)發(fā)的泥张。這意味著Opus編碼不僅適用于音樂(lè),而且支持雙向音頻傳輸鞠值,例如為視頻電話和VoIP通話做了充分的優(yōu)化媚创。
2012年9月初,IETF(互聯(lián)網(wǎng)工程任務(wù)組)將其提升為正式的官方標(biāo)準(zhǔn)彤恶,也就是說(shuō)它事實(shí)上已經(jīng)成為了HTML標(biāo)準(zhǔn)的一部分钞钙。
Opus音頻編碼是由非盈利的Xiph.org基金會(huì)、Skype和Mozilla等共同主導(dǎo)開(kāi)發(fā)的粤剧。像MP3一樣歇竟,Opus也是一種有損音頻編碼,這意味著在傳輸過(guò)程中內(nèi)容會(huì)被壓縮抵恋。
低延遲是它的最大特色焕议,也就是說(shuō),它的信號(hào)延遲非常小弧关,數(shù)據(jù)包會(huì)在20ms之內(nèi)被處理盅安。相比之下, MP3文件的延遲是它的10倍世囊。
  高度的靈活性
  Opus的開(kāi)發(fā)者在靈活性上付出了很大的心血别瞭,從而保證了Opus的比特率可以從6Kb/s到510Kb/s,采樣率可以在8kHz到48kHz之間搖擺株憾,音頻信號(hào)幀可以從2.5ms到60ms蝙寨。
從內(nèi)部結(jié)構(gòu)來(lái)看晒衩,Opus是開(kāi)發(fā)者利用已經(jīng)存在的音頻編碼進(jìn)行優(yōu)化后組合而成的所謂混合編碼。Opus聯(lián)合了CELT(Constrained Energy Lapped Transform)和SILK編碼墙歪,
并且對(duì)兩者進(jìn)行了改良听系。CELT編碼由于“實(shí)時(shí)”的特性,已經(jīng)被作為OGG家族的一部分虹菲。最初來(lái)自Skype的SILK編碼靠胜,從Skype 4.0開(kāi)始已經(jīng)作為語(yǔ)音編碼的方式被引入。
  大體上毕源,Opus編碼器的結(jié)構(gòu)和功能都非常簡(jiǎn)單浪漠。首先,輸入信號(hào)被以最高達(dá)48kHz的采樣率進(jìn)行采樣霎褐。因?yàn)槿说亩湟呀?jīng)很難分辨更高采樣率音頻的更多細(xì)節(jié)了缰雇。
然后桃笙,根據(jù)頻率的不同壶栋,使數(shù)據(jù)流通過(guò)CELT或者SILK編碼器沫屡。如果最終需要的是高品質(zhì)的音樂(lè),那么CELT編碼器是首選俱饿。
而利用SILK,人們可以使用最優(yōu)化的帶寬來(lái)傳輸音頻塌忽。為了這個(gè)目標(biāo)拍埠,SILK編碼必須做一些與之前的編碼不一樣的事情。
  對(duì)話中的語(yǔ)音分析
  SILK編碼適合采樣率不超過(guò)16kHz的低頻信號(hào)土居,一個(gè)典型的場(chǎng)景就是語(yǔ)音通話枣购。因此,在Opus編碼中擦耀,所有低于16kHz采樣率的音頻內(nèi)容都由SILK編碼棉圈。
SILK編碼器包含一系列組件,在這里將它們總結(jié)為4個(gè)部分:分析眷蜓、預(yù)過(guò)濾分瘾、編碼和輸出。其中吁系,音頻分析的背后其實(shí)是語(yǔ)音識(shí)別德召。
首先,將音頻信號(hào)分為語(yǔ)音和環(huán)境噪音兩部分汽纤。將語(yǔ)音幀根據(jù)頻率分解為更小的音頻碎片上岗,SILK編碼器過(guò)濾掉延遲信息,識(shí)別出有效語(yǔ)音信號(hào)的特點(diǎn)蕴坪。
第二項(xiàng)優(yōu)化是噪聲分析肴掷,它將周?chē)h(huán)境中重復(fù)的噪音打包為越小越好的音頻子幀(sub-frames)敬锐,使其占用更小的帶寬。
利用分析階段獲得的信息呆瞻,SILK編碼器就可以進(jìn)行音高預(yù)測(cè)和頻率量化台夺。例如,如果在一段對(duì)話中栋烤,音高(pitch)沒(méi)有大的變化谒养,那么只需要傳輸變化部分的信息就可以了。
這一步的目標(biāo)是讓數(shù)據(jù)流在保證質(zhì)量的同時(shí)明郭,越少越好买窟。噪聲的量化是另一種達(dá)成目標(biāo)的方法。在這個(gè)例子中薯定,SILK編碼可以確保不進(jìn)行不必要的優(yōu)化始绍,
而且不可避免的噪聲沒(méi)有消耗過(guò)多的比特率。
  所有的高頻信號(hào)话侄,也就是頻率最高達(dá)20kHz的信號(hào)亏推,都采用CELT編碼器處理。與MP3和AAC編碼一樣年堆,它通過(guò)修改后的離散余弦變換(DCF)將頻率轉(zhuǎn)換為系數(shù)吞杭,
從而消減在隨后的量化中難以覆蓋或者人耳很難感知的頻率。開(kāi)發(fā)者為Opus定義了3個(gè)模式变丧,使得SILK和CELT也能夠同時(shí)工作:純SILK模式負(fù)責(zé)低帶寬下的語(yǔ)音傳輸芽狗;
混合模式負(fù)責(zé)高質(zhì)量的語(yǔ)音傳輸;純CELT模式負(fù)責(zé)音樂(lè)傳輸痒蓬。Firefox用戶從第15版開(kāi)始可以在不安裝插件的情況下童擎,直接播放Opus文件。
視頻播放器VLC Media Player也將集成Opus編解碼」ド梗現(xiàn)在打開(kāi)opus-codec.org/examples網(wǎng)站就可以立即試聽(tīng)采用Opus編碼的音頻文件樣例顾复。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鲁捏,隨后出現(xiàn)的幾起案子芯砸,更是在濱河造成了極大的恐慌,老刑警劉巖碴萧,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乙嘀,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡破喻,警方通過(guò)查閱死者的電腦和手機(jī)虎谢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)曹质,“玉大人婴噩,你說(shuō)我怎么就攤上這事擎场。” “怎么了几莽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵迅办,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我章蚣,道長(zhǎng)站欺,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任纤垂,我火速辦了婚禮矾策,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘峭沦。我一直安慰自己贾虽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布吼鱼。 她就那樣靜靜地躺著蓬豁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪菇肃。 梳的紋絲不亂的頭發(fā)上地粪,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音琐谤,去河邊找鬼驶忌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛笑跛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播聊品,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼飞蹂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了翻屈?” 一聲冷哼從身側(cè)響起陈哑,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎伸眶,沒(méi)想到半個(gè)月后惊窖,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡厘贼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年界酒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘴秸。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡毁欣,死狀恐怖庇谆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凭疮,我是刑警寧澤饭耳,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站执解,受9級(jí)特大地震影響寞肖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衰腌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一新蟆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桶唐,春花似錦栅葡、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至坯约,卻和暖如春熊咽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背闹丐。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工横殴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卿拴。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓衫仑,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親堕花。 傳聞我的和親對(duì)象是個(gè)殘疾皇子文狱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容