• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:LINUXでのWAV再生・停止・一時停止について)

LINUXでのWAV再生・停止・一時停止の方法とは?

このQ&Aのポイント
  • LinuxでC言語を使ってWAVファイルの再生・停止・一時停止の方法を探っています。
  • 再生と停止はできるが、一時停止後の再生がうまくいかない問題があるようです。
  • 再生済みバイト数を求めるための式に誤りがある可能性があり、式の修正が必要です。

質問者が選んだベストアンサー

  • ベストアンサー
  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.2

なんか式が違っているような。。。 1回のサンプルで必要なバイト数 =(量子化ビット数÷8)×チャンネル数 1秒で必要なバイト数 =1回のサンプルで必要なバイト数 × サンプリング周波数 =(量子化ビット数÷8)×チャンネル数 × サンプリング周波数 n秒で必要なバイト数 =1秒で必要なバイト数 × n nミリ秒で必要なバイト数 =n秒で必要なバイト数 ÷ 1,000 だと思います。

miyamura_2005
質問者

補足

教えて頂いた式を使ってやってみたのですが、 症状は変わりませんでした。 上記で求めた数値÷2をすればうまくいくのですが・・・ 問題なのは「WAVを途中から再生させること」なのですが、 再生し終わったバイト数を求めてやることに問題があるのでしょうか?

その他の回答 (5)

noname#30727
noname#30727
回答No.6

>memcpy(&再生データ[44],&元データ[44+求めたサイズ],再生データサイズ); この44というのは波形データの先頭ですか? せっかくチャンクを探すコードを書いているのだから、波形データの先頭が44バイト目であると固定してしまうのはおかしいです。 WAVファイルのフォーマットとしては、"fmt "チャンクと"data"チャンクの間に別のチャンクが入る事もありえます。 あとは、元データの配列がshortだったりすると解決なんですが。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.5

#3です。 >サンプリングレート:220050 間違ってません? (一応確認) #3のコードは問題ないように思えます。 とすると原因は他にありそうです。 どういうデバッグをしたのかわかりませんが、 ・#2の計算式を実行するときの変数、戻り値を表示  (実際に計算をしている箇所で表示する) ・サウンド再生用関数に渡す内容をファイルに出力し、  プレーヤーで再生し、バイナリエディタで元のファイル と位置関係を比較する。 ということをやってみたらどうでしょうか。 (あまり大きなファイルでは使いにくいので、2~3秒のファイルを作るといいと思います)

  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.4

使用しているwavファイルのデータ自体がおかしいということはありませんか? wavファイルの大きさ、諸元、実際に再生したときの再生時間(実測値)は矛盾なく一致していますか?

miyamura_2005
質問者

補足

WAVファイルのヘッダー情報がおかしいと再生ができません。 他のプレイヤーで問題なく再生できるのでファイル自体に問題はないと考えます。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.3

#2です。 計算式は、#2のもので間違いありません。 この式を使ってズレるのなら、原因は他にあると思います。 例えば、 ・経過時間のカウントが間違えている。 ・計算式中の変数を間違えている。  (モノラルデータをステレオで計算している) ・サウンド再生用関数への引数の渡し方を間違えている。 などです。 (他にもあるかもしれません) 怪しいのは、2番目でしょうね。 変数の値はどこから持ってきましたか?

miyamura_2005
質問者

補足

>経過時間のカウントが間違えている。 経過時間を出力して確認しているので大丈夫だと思われます。 >計算式中の変数を間違えている。 WAVファイルのヘッダーから取ってきています。 ビット数:16ビット サンプリングレート:220050 チャンネル数:2 のファイルでテストしています。 上記情報を取るためのロジックは以下のとおり。 typedef struct {   FILE* fp;    /* ファイル構造体 */   short is_pcm;  /* PCM フォーマットの場合は 1、それ以外は 0 */   short channel;  /* モノラルの場合は 1、ステレオの場合は 2 */   int  rate;   /* サンプリング周波数 */   short bits;   /* 量子化ビット数 */   long offset;  /* ファイル先頭から PCM データまでのオフセット */   int  len;    /* PCM データ部の長さ */ } WAVE; wave_readFile( char* fname ) {   char  buf[32];   int  len;   if ( ( wave.fp = fopen( fname, "r" ) ) == NULL ) {     fprintf( stderr, "Failed to open %s\n", fname );     return -1;   }   /* 先頭 4 バイトが "RIFF" であることを確認 ( 更に 4 バイトスキップしておく ) */   fread( buf, 8, 1, wave.fp );   if ( strncmp( buf, "RIFF", 4 ) != 0 ) {     fprintf( stderr, "Specified file is not RIFF file.\n" );     fclose( wave.fp );     return -1;   }   /* 次の 4 バイトが "WAVE" であることを確認 */   fread( buf, 4, 1, wave.fp );   if ( strncmp( buf, "WAVE", 4 ) != 0 ) {     fprintf( stderr, "Specified file is not WAVE file.\n" );     fclose( wave.fp );     return -1;   }   /* fmt チャンクを探す */   while ( 1 ) {     fread( buf, 8, 1, wave.fp );     len = *( int* )( &buf[4] );     if ( strncmp( buf, "fmt ", 4 ) != 0 ) {       if ( fseek( wave.fp, len, SEEK_CUR ) == -1 ) {         fprintf( stderr, "Failed to find fmt chunk.\n" );         fclose( wave.fp );         return -1;       }     }     else       break;   }   /* WAVE フォーマットを読み込む */   fread( buf, len, 1, wave.fp );   wave.is_pcm = *( ( short* )( &buf[0] ) );   wave.channel = *( ( short* )( &buf[2] ) );   wave.rate  = *( ( int*  )( &buf[4] ) );   wave.bits  = *( ( short* )( &buf[14] ) );   if ( wave.is_pcm != 1 )     wave.is_pcm = 0;   /* data チャンクを探す */   while ( 1 ) {     fread( buf, 8, 1, wave.fp );     len = *( int* )( &buf[4] );     if ( strncmp( buf, "data", 4 ) != 0 ) {       if ( fseek( wave.fp, len, SEEK_CUR ) == -1 ) {         fprintf( stderr, "Failed to find data chunk.\n" );         fclose( wave.fp );         return -1;       }     }     else       break;   }   wave.len = len;   if ( ( wave.offset = ftell( wave.fp ) ) == -1 ) {     fprintf( stderr, "Failed to find offset of PCM data.\n" );     fclose( wave.fp );     return -1;   }   return 0; } >サウンド再生用関数への引数の渡し方を間違えている。 write関数に渡しているWAVデータの作り方に間違いがあることは考えたのですが、恐らく大丈夫です。 /* 元データよりヘッダー部コピー */ memcpy(再生データ,元データ,44); /* 音声部分コピー */ memcpy(&再生データ[44],&元データ[44+求めたサイズ],再生データサイズ);

  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.1

質問の中の式はおかしいですよね。(サンプリングレートで割ると、サンプリングレートが高いほどバイト数が減ってしまいますよ。ビット数、チャンネル数についてもしかり。) もう少し質問を整理してください。

miyamura_2005
質問者

補足

元々は 再生時間=8×データサイズ÷ビット数÷サンプリングレート÷チャンネル数       =8×データサイズ÷(ビット数×サンプリングレート×チャンネル数) の計算式からデータサイズを求める計算式をだしました。 これが間違っていますか?

関連するQ&A