>> 古い記事: MIDIキーボードを Ubuntu Studio + LMMS に繋いでピコピコした音で弾く
<< 新しい記事: 対訳: クリエイティブ・コモンズが営利・非営利の利用法について調査を始めたとのこと

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

雑メモ: libsndfile を使ってみた

まあ、いろいろと適当ですけど…… いやほんと適当なのでちゃんとやりたい人は The libsndfile API とかを見てください。


Ubuntu Linux の場合は
  $ sudo apt-get install  libsndfile1-dev


16bit の場合

---- 32767
∫
----  1
----  0
---- -1
∫
---- -32767

指定されたフレーム数だけ読み込んで値を表示

/*
gcc snd-003.c -lsndfile -o snd-003.exe
snd-003.exe wav_file_name frames_to_display

frames_to_display で指定されたフレーム数だけ読み込んで値を表示。
入力ファイルのフォーマットは 16bit, ステレオ(チャンネル数=2)。
*/

#include <stdio.h>
#include <sndfile.h>

int main( int argc, char** argv ){

  // ファイル名
  char* file_in =  argv[1] ;
  // 読み込むフレーム数
  int frames_to_read = atoi( argv[2] );

  // ファイルハンドラ
  SNDFILE* sf;
  // チャンネル数、サンプリング周波数などを持つ構造体
  SF_INFO sinfo;

  // sf_open の前に 0 にしておく
  sinfo.format = 0;

  // ファイル開く
  sf = sf_open( file_in, SFM_READ, &sinfo );

  printf( "%s\n", argv[1] );
  printf( "--------\n" );

  // 読み込むフレーム数
  sf_count_t count = 1;

  // 読み込んだ値を入れる配列
  short val[2];

  // 1フレームずつ読み込んで値を表示
  int a;
  for( a = 0; a < frames_to_read; a++ ){
    sf_readf_short( sf, val, count) ;

    printf( "% 4d:  L: % 6d  -  R: % 6d \n", a, val[0], val[1] );
  }

  // ファイル閉じる
  sf_close( sf );

  return 0;
}

読んでそのまま書き込み

/*
20080914
gcc snd-004.c -lsndfile -o snd-004.exe
snd-004.exe file_in file_out

file_in を読み込んで 1フレームずつ読み、file_out に移し替える
入力ファイルのフォーマットは 16bit, ステレオ(チャンネル数=2)とする。
*/

#include <stdio.h>
#include <sndfile.h>

int main( int argc, char** argv ){
  char* file_in  = argv[1] ;
  char* file_out = argv[2] ;

  SNDFILE* sfr;
  SNDFILE* sfw;
  // チャンネル数、サンプリング周波数などを持つ構造体
  SF_INFO sinfo;

  sinfo.format = 0;

  // ファイル開く
  // 入力
  sfr = sf_open( file_in, SFM_READ, &sinfo );
  // 出力 - 入力ファイルと同じフォーマットなので、sinfo をそのまま渡す
  sfw = sf_open( file_out, SFM_WRITE, &sinfo );

  printf( "sinfo.frames   = %d  \n", sinfo.frames   );
  printf( "sinfo.format   = 0x%x\n", sinfo.format   );
  printf( "sinfo.channels = %d  \n", sinfo.channels );
  printf( "sinfo.sections = %d  \n", sinfo.sections );
  printf( "sinfo.seekable = %d  \n", sinfo.seekable );

  printf( "--------\n" );

  sf_count_t count = 1;
  short val[ (int)count * sinfo.channels ];

  int a = 0;
  sf_count_t read_num;
  while(1){
    // これ以上データがないという場合には count と異なる値が返ってくる
    read_num = sf_readf_short(  sfr, val, count) ;
    printf( "% 4d:  L: % 6d  -  R: % 6d  -  %6d \n", a, val[0], val[1], read_num );

    if( read_num != count ){ 
      // ファイル終端まで達したらループ抜ける
      break; 
    } else {
      // 読み込みに成功していれば書き込む
      sf_writef_short( sfw, val, count) ;
    }

    a++;
  }

  // ファイル閉じる
  sf_close( sfr );
  sf_close( sfw );

  return 0;
}

サイン波を書き出す

参考: TaptAudio: sample.cpp Source File / unpaid_p10l: Parser/Reader for Korg KMP and KSF Files

/*
20080915
gcc snd-006.c -lsndfile -o snd-006.exe
snd-006.exe file_out frequency length_sec

周波数(Hz)、長さ(秒)を指定してサイン波を書き出す。
出力ファイルのフォーマットは 16bit, モノラル(チャンネル数=1)とする。
*/

#include <stdio.h>
#include <stdlib.h> // atof
#include <math.h> // atan, pow
#include <sndfile.h>

#define PI ( 4*atan(1.0) )

#define SAMPLE_RATE 44100
#define BIT_DEPTH 16

// 16bit のとき 2^15 - 1 = 32767
#define AMP_MAX (pow(2,(BIT_DEPTH-1)) - 1)

short frame2sine( int frame, double freq){
  //  double sec = (double)(frame % SAMPLE_RATE) / SAMPLE_RATE;
  double sec = (double)frame / SAMPLE_RATE;
  return (short)( sin( sec * 2 * PI * freq ) * AMP_MAX );
}

int main( int argc, char** argv ){
  char* file_out = argv[1] ;
  double freq = atof(argv[2]) ;
  double length_sec = atof(argv[3]) ;

  SNDFILE* sfw;
  SF_INFO sfinfo;

  // .wav の場合最低限この3つは指定しないといけないっぽい
  sfinfo.samplerate = SAMPLE_RATE;
  sfinfo.channels = 1;
  sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;

  // 書き込み用に sf_open() する前にフォーマットをチェック
  if( sf_format_check( &sfinfo ) == 0 ){
    printf( "invalid format: %d\n", sf_format_check( &sfinfo ) );
    exit(1);
  }

  sfw = sf_open( file_out, SFM_WRITE, &sfinfo );

  sf_count_t frames = 1;
  short val[ (int)frames * sfinfo.channels ];

  int a = 0;
  sf_count_t write_num;
  for( a=0; a < (int)(SAMPLE_RATE * length_sec); a++ ){
    val[0] = frame2sine(a, freq);
    write_num = sf_writef_short( sfw, val, frames ) ;
  }

  sf_close( sfw );

  return 0;
}

参考

>> 古い記事: MIDIキーボードを Ubuntu Studio + LMMS に繋いでピコピコした音で弾く
<< 新しい記事: 対訳: クリエイティブ・コモンズが営利・非営利の利用法について調査を始めたとのこと
** ホームに戻る

コメント

  1. tkmrkt #- |
  2. 2010/03/31(水) 23:46:35 |
  3. URL
  4. [ 編集]
DJMixを自動でやるようなソフトを作ってみたいと
思っているものです。
audacityというオープンソースのソフトが
libsndfile使ってるみたいなので、そこからたどり
着きました。音楽ファイルの波形のデータ(周波数?)
の取り方チャント書いてあるサイト始めて見たので、
感動しました。大変参考になりました。
ありがとうございました。また寄せてもらいます。
あ、よかったら私のブログも見てみてください。
(あまり参考とかには全然ならないかもしれないですが、、、)

コメントの投稿

管理者にだけ表示を許可する

|
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。