ARGUMENT - みる会図書館


検索対象: Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-
11件見つかりました。

1. Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-

実装編 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 = 8 ; tmp ト BITSTREAM_GETLOWERBITS (stream—>bit_count , stream—>bit—count ; n_bits while (n—bits > stream—>bit—count) { * 2 回目以降は 8 t 単位で入力し t にセット */ * 初回ループでは t の上位ビットにセット / * 最上位ビットからデータを埋めていく return BITSTREAM_APIRESULT_ 工 NVALID_ARGUMENT ; if (n—bits > sizeof (uint64_t) * 8 ) { / * 入力可能な最大ビット数を越えている * / return BITSTREAM_AP 工 RESULT_INVAL 工 D_MODE ; 第 2 章 n—bits , uint64—t *val) int32_t ch; uint64—t tmp = 0 ; / * 引数チェック * / if (stream = = NULL Ⅱ val = = NULL) { return BITSTREAM_APIRESULT_INVAL 工 D_ARGUMENT ; / * 読み込みモードでない場合は即時リターン */ if ( ! (stream—>flags & BITSTREAM_FLAGS-F 工 LEOPENMODE READ) ) { stream—>bit—buffer) くく n_bits; / * プバイト読み込みとエラー処理 */ if ( ()h = fgetc (stream->fp) ) = EOF) { if (feof (stream->fp) ) { / * 途中でファイル終端に達していたら、ループを抜ける * / goto END-OF_STREAM; } else { / * それ以外のエラー * / return BITSTREAM_APIRESULT_ 工 OERROR ; END_OF_STREAM : / * 端数ビットの処理 stream—>bit—buffer stream—>bit_count (uint8—t) ch ; * 残ったビット分を t の最下位ビットにセット * / stream—>bit—count n_bits; tmp ト (uint64-t) BITSTREAM_GETLOWERB 工 TS (n_bits , bit—buffer > > stream—>bit_count) ) ; / * 正常終了 */ *val tmp ; return B 工 TSTREAM_APIRESULT_OK ; (uint32—t) (stream—>

2. Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-

2.3 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 ala—predictor. c リスト 2.11 プリエンファシスフィルター処理 ( ala ー p て edicto て . c ) / * プリエンファシス ( t32 , マ ce ) */ ALAPredictorApiResu1t ALAEmphasisFi1ter—PreEmphasisInt32 ( int32—t* data, uint32—t num—samples , int32—t coef—shift) uint32—t smpl ; int32-t prev—int32, tmp-int32; const int32—t coef—numer = (int32-t) ( ( 1 くく coef-shift) / * 引数チェック * / if (data = = NULL) { return ALAPRED 工 CTOR—AP 工 RESULT—INVAL 工 D-ARGUMENT ; / * フィルタ適用 * / prev—int32 0 ; smpl く num-samples ; smpl + + ) { for (smpl tmp—int32 = data Csmp1] ; (int32—t) ALAUTIL 工 TY-SHIFT—RIGHT—AR 工 T}NET 工 C (prev—int32 * data [smpl] coef—numer, coef—shift) ; prev—int32 tmp—int32 ; return ALAPRED 工 CTOR—APIRESULT—OK ; 63 入力データ data をその場で ( ⅲ - place で ) 書き換える関数である。フィルター計算は固 定小数乗算を使用しており、式 2.7 の″に該当する係数との乗算を、 ( 1 くく coef-shift) 1 との乗算処理と、 coef-shift の右シフト処理に分けて実現している。 ALA バージョ ン 1.0.0 では、 coef-shift は 5 に設定されているため、フィルター係数″の値は ″ = ( 25 ー 1 ) / 25 = 31 / 32 = 0.96875 に相当する。 デ工ンファシスフィルター処理 デ工ンファシスフィルター処理の実装をリスト 2.12 に示す。 408 409 410 411 412 413 414 415 416 417 418 419 リスト 2.12 デ工ンファシスフィルター処理 (ala_predictor. c) / * デ工ンファシス ( をれ t32 , をれマ乙 ace ) * / ALAPredictorApiResu1t ALAEmphasisFilter—DeEmphasisInt32 ( int32—t* data, uint32—t num—samples , int32—t coef—shift) uint32—t smpl ; const int32-t coef—numer = (int32-t) ( ( 1 くく coef-shift) / * 引数チェック */ if (data = = NULL) { return ALAPRED 工 CTOR_AP 工 RESULT_ 工 NVAL 工 D—ARGUMENT ;

3. Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-

70 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 } 第 2 章 実装編 / * 読み込みモードでは実行不可能 * / stream—>bit—buffer ー = (uint8—t) ( 1 くく stream—>bit—count) ; if (bit ! = 0 ) { / * ビット出力バッフアに値を格納 */ stream—>bit_count— / * バイト出力するまでのカウントを減らす */ return BITSTREAM_AP 工 RESULT_INVAL 工 D—MODE ; if (stream->flags & BITSTREAM-FLAGS—FILEOPENMODE READ) { / * バッフア出力・更新 * / if (stream—>bit—count if (fputc(stream—>bit-buffer , stream->fp) return BITSTREAM-APIRESULT—IOERROR ; stream—>bit_count = 8 ; stream—>bit—buffer = 0 ; return B 工 TSTREAM_APIRESULT_OK ; = EOF) { lbit だけ出力する場合、その値は即座にファイルに書き出されず、一旦 1 バイ stre ー > bit ー co t に記録されており、このカウントが 0 になったときに始めてバイト ト分のバッファ stream->bit-buffer に蓄えられる。 bit の書き出しカウント数は 複数 bit 出力を行う処理をリスト 2.14 に示す。 複数 bit 出力処理 単位の書き出し (fputc 関数 ) が実行される。 210 211 212 213 214 215 216 217 218 219 リスト 2.14 複数 bit 出力処理 (bit-stream ・ c) * 乙の右側 ( 下位 ) れ一 ts 出力 ( 最大 6 イ t 出力可能 ) * BitStream-PutBits(stream, 3 , の , ・は次と同じ : * BitStream-PutBit(stream, プ ) , ・ BitStream—PutBit(stream, 1 ) , ・ BitStream-PutBit (stream, の , ・ BitStreamApiResu1t BitStream—PutBits (struct BitStream* stream, n—bits , uint64—t val) / * 引数チェック * / if (stream = = NULL) { て e t urn B ITS TREAM_AP IRESULT_ INVAL 工 D_ARGUMENT ; uint32_t

4. Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-

2.4 bit_stream . c いただきたい。 表 2.4 ファイル名 4 ー 02 井戸の茶椀 . wav 1 ー 01 火焔太鼓 . wav 02 My Song. wav 09 瑠璃子 . wav 30 ー自分だけの繩き . wav 29 一重ねる努力 .wav 残差計算前後のエントロピー計算結果 に区切って計測を行ったため、残差計算前のエントロピー値が表 1.5 と異なることに注意 69 4 ー 02 Let's アイカッ ! ( Short サイズ ) . wav 5 ー 02 カレンダーガール (TV-size) . wav 元の信号 [byte] 15.16 15.10 14.59 13.73 13.66 13.04 11.91 11.04 残差 [byte] 5.44 7.88 7.86 6.01 8.27 9.42 12.88 12.82 全てのファイルにおいて、残差計算によってエントロピーが減少することを確認し た。ただし工ントロピーの減少度合いは音源依存で、 4 ー 02 井戸の茶椀 . wav に見られ るようにエントロピーが半分以下になるファイルがある一方、 5 ー 02 カレンダーガール (TV-size) . wav のように、エントロピーが 1 割程度しか減少しないファイルが存在した。 2 4 bit_stream . c bit-stream. c には、 bit 単位でファイル入出力を行う関数群が集められている。この モジュールは bit 単位の入出力機能に限らず、 CPU の差異により発生するバイトオー ダー ( 工ンディアン ) を揃える目的も兼ねている。実装は [ 7 ] の bitio. c を参考に、僅か lbit だけ出力を行う処理をリスト 2.13 に示す。 lbit 出力処理 2.4.1 bit 単位の出力処理 な機能拡張を行っている。 177 178 179 180 181 182 リスト 2.13 lbit 出力処理 (bit_stream. c) / * れ出力 * / BitStreamApiResu1t BitStream—PutBit(struct BitStream* stream, bit) / * 引数チェック */ if (stream = = NULL) { return BITSTREAM_APIRESULT_INVALID_ARGUMENT ; uint8_t

5. Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-

2.4 bit_stream . c 73 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 } return B 工 TSTREAM_APIRESULT_ 工 NVALID_ARGUMENT ; / * 読み込みモードでない場合は即時リターン * / if ( ! (stream->flags & BITSTREAM—FLAGS—F 工 LEOPENMODE—READ) ) { return B 工 TSTREAM_APIRESULT_ 工 NVALID_MODE ; / * 入力ビットカウントをプ減らし、バッフアの対象ビットを出力 * / if (stream—>bit—count > 0 ) { stream—>bit_count— (*bit) (stream—>bit—buffer > > stream—>bit—count) & 1 ; return B 工 TSTREAM—APIRESULT_OK ; / * プバイト読み込みとエラー処理 * / if ( ()h = fgetc (stream->fp) ) if (feof(stream → (p)) { / * ファイル終端に達した * / return BITSTREAM_APIRESULT_EOS ; } else { / * それ以外のエラー * / return BITSTREAM_AP 工 RESULT_IOERROR ; / * カウンタとバッフアの更新 * / stream—>bit_count = 7 ; (uint8-t) ch; stream—>bit_buffer / * 取得したバッフアの最上位ビットを出力 * / (*bit) (stream->bit—buffer > > 7 ) & 1 ; return BITSTREAM—APIRESULT_OK ; = EOF) { 常に読み込み予定の bit を含むデータ 1 バイト分をバッファ stream->bit-buffer に 取得しておき、バッフアに残っている bit 数のカウンタ stream->bit_count が残って いる限りはそこから lbit 取り出す。カウンタ stream → bit-count が 0 になったら次の データを fgetc 関数によって 1 バイト取得してバッファ stream->bit-buffer とカウ ンタ stream → bit-count を補充し、 lbit を取り出す。 複数 bit 取得処理 最後に複数 bit 取得を行う処理をリスト 2.18 に示す。 リスト 2.18 複数 bit 取得処理 (bit-stream. c) 302 / * n-bits 取得 ( 最大 6 イい t ) し、その値を右詰めして出力 */ 303 BitStreamApiResu1t BitStream_GetBits(struct BitStream* stream, uint32—t

6. Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-

2.4 bit_stream. c 71 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 } / * 読み込みモードでは実行不可能 * / stream—>bit—buffer ー = (uint8—t)BITSTREAM—GETLOWERBITS (stream¯> n_bits = n_bits stream—>bit_count ; whi1e (n—bits > = stream—>bit—count) { * 2 回目以降は 8 し概単位で出力 */ * 初回ループでは端数 ( 出力に必要なビット数 ) 分を埋め出力 / * 乙の上位ビットから順次出力 return B 工 TSTREAM_APIRESULT—OK ; if (n—bits / * 0 ビット出力では何もしない * / return BITSTREAM_APIRESULT—工 NVALID—ARGUMENT ; if (n-bits > sizeof (uint64—t) * 8 ) { / * 出力可能な最大ビット数を越えている * / return B 工 TSTREAM_APIRESULT_ 工 NVALID—MODE ; if (stream->flags & B 工 TSTREAM-FLAGS-FILEOPENMODE—READ) { = EOF) { return BITSTREAM-AP 工 RESULT—IOERROR ; if (fputc (stream—>bit—buffer, stream—>fp) bit—count , va1 > > n—bits) ; / * 端数ビットの処理 : stream—>bit_count stream—>bit—buffer = 0 ; 8 ; * 残った分をバッフアの上位ビットにセット */ assert(n—bits く = 8 ) ; stream—>bit_count n_bits ; stream—>bit—buffer ー = (uint8—t) (BITSTREAM—GETLOWERB 工 TS (n—bits , stream—>bit—count) ; return BITSTREAM_AP 工 RESULT-OK ; val) くく コメントにもあるようにアプリケーション側で出力対象の値を lbit 単位に分けて出力 を行えばリスト 2.14 に相当する処理を実現できるが、その処理の簡略化のために本関数 リスト 2.15 上位 bit からの出力処理 (bit- ト 2.15 の while ループに表れている。 力する。即ち、出力対象の引数値 val の最上位 bit から順に出力を行う。この処理はリス 1 バイト (8bit) を超える数値出力の際には、本モジュールはビッグエンディアンで出 を用意している。 stream . C

7. Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-

60 第 2 章実装編 と、 M は L チャンネルと R チャンネルの符号が同一 ( 同相 ) の成分が強められ、符号が Ⅳ , S はそれぞれ中心、側面成分を示している。一方、相関除去の立場から考えてみる 逆 ( 逆相 ) が弱められた成分、 S は M と逆の性質を持った成分と考えられる。 M , S は以下の式 2.5 , 2.6 によってなに戻すことができる。 MS 処理の実装解説 MS 処理の実装をリスト 2.7 に示す。 リスト 2.7 LR 信号を MS 信号に変換 (ala_predictor. c) ( 2.5 ) ( 2 ・ 6 ) 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 ALAPredictorApiResu1t ALAChanne1Decorre1ator_LRtoMS 工Ⅱt32 (int32_t **data, uint32—t num—channels , uint32_t num_samples) uint32—t smpl ; int32_t mid, side ; / * 引数チェック * / if ( (data ! = NULL) Ⅱ (data[0] ! = NULL) Ⅱ (data[l] ! = NULL) Ⅱ (num-channels く 2 ) ) { return ALAPRED 工 CTOR-APIRESULT_INVALID_ARGUMENT ; / * サンプル単位でー > 処理 * / f0 て (smpl 0 ; smpl く num—samples ; smpl + + ) { / * 注意 : 除算は右シフト必須 ( / 2 ではだめ。 0 方向に丸められる ) * / mid = (int32—t ) ALAUT 工 LITY—SH 工 FT—R 工 GHT-ARITHMET 工 C (data [ 0 ] [smpl] + data [ 1 ] [smpl] , 1 ) ; side = data[0] [smpl] ー dataC1] Csmp1] ; dataCO] [smpl] = mid; dataC1] [smpl] Side ; return ALAPRED 工 CTOR-AP 工 RESULT_OK ; 単純な MS 処理の式 2.3 , 2.4 とは異なり、以下のコードにより変換を行っている。 496 497 498 リスト 2.8 MS 変換処理部分 (ala_predictor. c) / * 注意 : 除算は右シフト必須 ( / 2 ではだめ。 0 方向に丸められる ) * / mid = (int32-t) ALAUTILITY_SH 工 FT_RIGHT_ARITHMET 工 C (data [ 0 ] [smpl] + data [ 1 ] Csmp1] , side = data[0] [smpl] ー dataC1] Csmp1] ;

8. Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-

56 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 第 2 章 int32—t* residual) 実装編 const int32—t* data, uint32—t num—samples , const int32—t* parcor—coef , uint32—t order, uint32—t samp , 0 て d ; int32—t* forward—residual ; int32_t* backward_residual ; int32—t mul—temp ; / * 丸め誤差軽減のための加算定数 = 0.5 * / (IUL くく 14 ) ; const int32_t half / * 引数チェック * / if (lpc = = NULL Ⅱ data = = NULL Ⅱ parcor—coef = = NULL Ⅱ residual = = NULL) { return ALAPRED 工 CTOR—APIRESULT_INVAL 工 D—ARGUMENT ; / * 次数チェック * / if ( 0 て de て > lpc—>max-order) { return ALAPRED 工 CTOR_APIRESULT-EXCEED_MAX—ORDER; / * オート変数にポインタをコピー * / lpc—>forward—residual ; forward_residual lpc—>backward—residual ; backward_residual / * 誤差計算 * / fo て (samp = 0 ; samp く num—samples ; samp + + ) { / * 格子型フィルタにデータ入力 * / forward—residual [ 0 ] data Csamp] ; / * 前向き誤差計算 * / for (ord = 1 ; 0 て d く = order; 0 て d + + ) { mul—temp return ALAPRED 工 CTOR-APIRESULT_OK ; residual Csamp] forward—residual [ 0 て de て ] ; / * 残差信号 * / backward—residual [ 0 ] = data Csamp] ; / * 後ろ向き誤差計算部にデータ入力 */ backward—residual [ 0 て d ] backward—residual [ord ー 1 ] ー mul—temp ; forward—residual [ 0 て d ー 1 ] + half , 15 ) ; (int32—t) ALAUTILITY—SHIFT_RIGHT_ARITHMETIC (parcor—coef Cord] * mul—temp for ( 0 て d = 0 て de て ; ord > = 1 ; ord——) { / * 後ろ向き誤差計算 * / forward—residual [ 0 て d ] forward—residual [ 0 て d ー 1 ] ー mul—temp ; backward—residual [ 0 て d ー 1 ] + half , 15 ) ; (int32—t) ALAUTIL 工 TY-SHIFT-R 工 GHT—AR 工 THMETIC (parcor-coef [ 0 て d ] *

9. Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-

81 2.5 ala—coder . c ALACODER_UPDATE-ESTIMATED-MEAN マクロは、推定平均値を更新するマクロであり、 リスト 2.28 に示す形で定義される。 リスト 2.28 ALACODER—UPDATE-ESTIMATED-MEAN マクロ (ala—coder. c 17 / * 推定平均値の更新マクロ ( 指数移動平均により推定平均値を更新 ) * / 18 #define ALACODER-UPDATE—ESTIMATED-MEAN (mean, uint) { \ (mean) = (ALAC0derFixedF10at) ( 119 * (mean) + 9 * 19 ALACODER_U 工 NT32—TO—F 工 XED—FLOAT (uint) + (IUL くく 6 ) ) > > 7 ; \ リスト 2.28 は、現在の推定平均値 E 国と新しい入力値ェに対して、更新後の推定平均 値 E / 国を以下の式 2.10 によって計算している。 119E 岡十 9 一 119 128 128 128 右シフトによる切り捨て誤差の影響を緩和するため、小数の 0.5 に相当する (IUL くく 6 ) を加算している。 式 2.10 は指数移動平均による平均値の推定式に他ならない。音声信号は画像に比べイ 号の bit 幅 ( ダイナミックレンジ ) が広いため、信号の変化が急激になりやすい。筆者は、 単純な移動平均を用いていると、信号変化の傾向についていけなくなる可能性を踏まえ、 応答性の高い平均を求める意図で更新式 2.10 を使用している。 残差の復号 残差の復号処理をリスト 2.29 に示す。 リスト 2.29 残差の復号処理 (ala-coder ・ c) / * 符号付き整数配列の復号 * / 150 ALAC0derApiResu1t ALAC0der—GetDataArray ( 151 struct ALACoder* coder , struct BitStream* strm, 152 int32—t** data, uint32—t num—channels , uint32—t num—samples) 153 154 uint32—t ch , smpl , uint ; 155 156 / * 引数チェック * / 157 = NULL) ) { if ( (strm = = NULL) Ⅱ (data = = NULL) Ⅱ (coder 158 return ALACODER— AP 工 RESULT—工 NVAL 工 D ー ARGUMENT ; 159 160 161 / * 平均値初期値の取得 */ 162 fo て ()h = 0 ; ch く num—channels ; c 五 + + ) { 163 uint64_t bitsbuf ; 164 BitStream-GetBits (strm, 16 , &bitsbuf) ; 165 = ALACODER_UINT32_TO_FIXED_FLOAT (bitsbuf) ; coder—>estimated—mean [ch] 166 167 168 20 } ( 2.10 )

10. Introduction to Lossless Audio Codec ロスレス音声コーデック -基本理論と実装-

78 114 { 147 146 145 144 143 142 141 140 139 138 137 136 135 134 133 132 131 130 129 128 127 126 125 124 123 122 121 120 119 118 117 116 115 第 2 章 = NULL) ) { 実装編 uint32—t smpl , ch , uint ; / * 引数チェック */ for (smpl = 0 ; smpl く num—samples ; smpl + + ) { uint64—t mean_uint for ()h = 0 ; ch く num_channels ; ch + + ) { / * 各チャンネルの平均値をセット庵己録 */ return ALACODER—APIRESULT_INVALID_ARGUMENT ; if ( (strm = = NULL) Ⅱ (data = NULL) Ⅱ (coder mean—uint + = ALAUTILITY_S 工 NT32—TO—U 工 NT32 (data Cch] [smpl] ) ; mean_uint / = num_samples ; / * 平均の最大は符号無し 16 い t 整数の最大値に制限 * / mean-uint = ALAUTIL 工 TY-MIN (mean—uint , UINT16_MAX) ; BitStream—PutBits(strm, 16 , mean_uint) ; return ALACODER—APIRESULT_OK ; ALACODER_UPDATE_ESTIMATED_MEAN (coder->estimated_mean [ch] , uint) ; / * 推定平均値を更新 * / —>estimated—mean [ch] ) , uint ) ; ALACoder—PutRiceC0de (strm , ALACODER_CALCULATE-R 工 CE_PARAMETER(coder / * ライス符号化 */ uint = ALAUT 工 LITY-SINT32_TO_UINT32 (data [ch] [smpl] ) ; / * 符号なし整数に変換 * / 0 ; smpl く num-samples ; smpl + + ) { for (smpl for ()h = 0 ; ch く num_channels; ch + + ) { / * 各チャンネル毎に符号化 * / ALACODER_U 工 NT32_TO_FIXED_FLOAT (mean_uint) coder—>estimated—mean [ch] 148 } 符号化処理の前に、推定平均値の初期値を決める必要がある。推定平均値の初期値を設 定する処理をリスト 2.23 に示す。 122 123 124 125 126 127 128 129 130 リスト 2.23 推定平均値の初期化 (ala_coder. c) / * 各チャンネルの平均値をセット庵己録 */ fO て ()h = 0 ; ch く num_channels ; ch + + ) { uint64_t mean_uint for (smpl 0 ; smpl く num-samples ; smpl + + ) { mean-uint + = ALAUTILITY-S 工 NT32-TO-U 工 NT32 (data Cch] [smpl] ) ; mean_uint / = num_samples ; / * 平均の最大は符号無し 16 t 整数の最大値に制限 * / mean-uint = ALAUTIL 工 TY—M 工 N (mean—uint , UINT16_MAX) ;