🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

2862閲覧

waveファイルの音声データだけを配列に格納したい

Anfaenger

総合スコア14

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/02/24 13:33

編集2021/02/24 16:27

waveファイルの音声データだけをC言語で配列に格納したいです。

(sinwave.wavは2000Hzの音波を1秒間出力するファイルです。)
どなたかお力添えをお願い致します。

##追記:
一から作るのはまだ早いというご指摘を頂いたので
下記サイトを参考にプログラムを更に変更してみました。
https://hwswsgps.hatenablog.com/entry/2018/08/19/172401
しかしコード-1073741819で終了してしまいます。
実際のプログラムは下記の通りです。

C++

1#include <stdio.h> 2#include <math.h> 3#include <stdlib.h> 4#include <malloc.h> 5#pragma warning(disable:4996); 6 7typedef struct 8 9{ 10 11 int fs; //サンプリング周波数 12 13 int bits; //量子化bit数 14 15 int L; //データ長 16 17} WAV_PRM; 18 19double* audiodatasize; 20 21double* audio_read(WAV_PRM* prm, char* filename); 22 23int main() 24{ 25 WAV_PRM prm_in; 26 double* data; 27 FILE* fp = fopen("sinwave.wav", "rb"); 28 FILE* txt = fopen("data.txt", "w"); 29 char fn[] = "sinwave.wav"; 30 data = audio_read(&prm_in, fn); 31 printf("%d", (int)audiodatasize); //ループ回数 32 for (int i = 0; i < (int)audiodatasize; i++) { 33 fprintf(txt, "%f\n", data[i]); 34 } 35 fclose(fp); 36 fclose(txt); 37 return 0; 38} 39 40double* audio_read(WAV_PRM* prm, char* filename) 41 42{ 43 44 //変数宣言 45 46 FILE* fp; 47 48 int n; 49 50 double* data; 51 52 char header_ID[4]; 53 54 long header_size; 55 56 char header_type[4]; 57 58 char fmt_ID[4]; 59 60 long fmt_size; 61 62 short fmt_format; 63 64 short fmt_channel; 65 66 long fmt_samples_per_sec; 67 68 long fmt_bytes_per_sec; 69 70 short fmt_block_size; 71 72 short fmt_bits_per_sample; 73 74 char data_ID[4]; 75 76 long data_size; 77 78 short data_data; 79 80 81 82 //wavファイルオープン 83 84 fp = fopen(filename, "rb"); 85 86 87 88 //wavデータ読み込み 89 90 fread(header_ID, 1, 4, fp); 91 92 fread(&header_size, 4, 1, fp); 93 94 fread(header_type, 1, 4, fp); 95 96 fread(fmt_ID, 1, 4, fp); 97 98 fread(&fmt_size, 4, 1, fp); 99 100 fread(&fmt_format, 2, 1, fp); 101 102 fread(&fmt_channel, 2, 1, fp); 103 104 fread(&fmt_samples_per_sec, 4, 1, fp); 105 106 fread(&fmt_bytes_per_sec, 4, 1, fp); 107 108 fread(&fmt_block_size, 2, 1, fp); 109 110 fread(&fmt_bits_per_sample, 2, 1, fp); 111 112 fread(data_ID, 1, 4, fp); 113 114 fread(&data_size, 4, 1, fp); 115 116 117 118 //パラメータ代入 119 120 prm->fs = fmt_samples_per_sec; 121 122 prm->bits = fmt_bits_per_sample; 123 124 prm->L = data_size / 2; 125 126 127 128 //音声データ代入 129 130 data = (double*)calloc(prm->L, sizeof(double)); 131 audiodatasize = (double*)malloc(sizeof(double) * prm->L); 132 133 for (n = 0; n < prm->L; n++) { 134 135 fread(&data_data, 2, 1, fp); 136 137 data[n] = (double)data_data / 32768.0; 138 139 } 140 141 142 143 fclose(fp); 144 145 return data; 146 147}

出力されたdata.txtの内容は下記のようになりました。

0.000000 0.281036 0.539398 0.754272 0.908325 0.989105 0.990112 0.911255 0.758942 0.545380 0.287842 0.007111 -0.274200 -0.533386 -0.749573 -0.905304 -0.988037 -0.991058 -0.914185 -0.763550 -0.551331 -0.294678 -0.014221 0.267334 0.527344 0.744843 0.902283 0.986938 0.991974 . . . 以下省略

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/02/24 15:15

> 取り出してテキストファイルに出力してみても上手く取り出せていないようです。 何を比較してうまく取り出せていないと判断したのですか? > ループ内で永遠にループしてしまっているようです……解決策が全く分かりません。 ブレークポイントを設定し、デバッグ実行して変数の値を確認したりはしてみたのですか?
t_obara

2021/02/24 15:16

「解決策が全く分かりません」とのことですが、そもそもデータサイズが想定通りになっているのかなどデバッグはしているのですか?デバッグの仕方がわからないということでしょうか。既に回答も出ていますが、提示されたコードを見る限り、Wavファイルのデータフォーマットを理解されているとは思えないです。
退会済みユーザー

退会済みユーザー

2021/02/24 15:33

WAVEファイルのヘッダ情報をググったり、既存のWAVEを読み込めているサンプルプログラムを探して、それを動かして動作を解析したり、デバッグの仕方を覚える所から始めた方が良いでしょう。RIFFの構造やWAVEFORMAT構造体も恐らく判っていなさそうなので、1から作るのはまだ貴方には早すぎます。
退会済みユーザー

退会済みユーザー

2021/02/25 01:57 編集

>下記サイトを参考にプログラムを更に変更してみました。 >(中略) >しかしコード-1073741819で終了してしまいます。 変更前のソースでは正しく動いていたのですか?そうであれば、変更の仕方が悪いだけだと思います。デバッグして終了する箇所を突き止めたり、エラーになった関数名と返すエラーコードをググって自分で調査してみてください。ここはデバッグ依頼をする場所ではないです。 初心者であれば、teratailの質問テンプレートを埋めるように質問を記述してください。開発環境などもさっぱり分からず、情報量が不足しています。 [質問するときのヒント] https://teratail.com/help/question-tips [推奨していない質問] https://teratail.com/help/avoid-asking
guest

回答2

0

自己解決

実は最終的には読み取った音声データをFFTにかけるプログラムを作ろうとしていたのですが、
試しに作ってみたら上手くいきました。
audiodatasizeでループを作ったことが異常終了の原因だったようです。

C++

1#include <stdio.h> 2#include <math.h> 3#include <stdlib.h> 4#pragma warning(disable:4996) 5 6typedef struct 7 8{ 9 10 int fs; //サンプリング周波数 11 12 int bits; //量子化bit数 13 14 int L; //データ長 15 16} WAV_PRM; 17 18FILE* fp; // ファイル入出力 19 20#define PI 4.0*atan(1.0) // 円周率 21 22void S_fft(double* x, double* y, int, int); 23#define N 4096 // N=データ総数(2,4,8,16,32,64,128,256,512,1024 のどれか) 24 25double* audio_read(WAV_PRM* prm, char* filename); 26 27double* audiodatasize; 28 29int main(void) { 30 31 WAV_PRM prm_in; 32 double* data; 33 FILE* audio = fopen("sinwave.wav", "rb"); 34 FILE* txt = fopen("data.txt", "w"); 35 char fn[] = "sinwave.wav"; 36 37 int i, Fr = 4096; 38 double dt = 0.00005; 39 double sc; 40 double* x, * y; 41 x = (double*)malloc(sizeof(double) * N); 42 y = (double*)malloc(sizeof(double) * N); 43 44 45 double fq; 46 int pw = 0; 47 printf("STG 01\n"); 48 sc = 2.0 * PI * dt; 49 for (i = 0; i < N; i++) { // 1Hzに60Hzのノイズが重なった波形の例 50 if (x != NULL && y != NULL) { 51 // x = audio_read(&prm_in, fn); 52 y[i] = 0.0; 53 } 54 } 55 x = audio_read(&prm_in, fn); 56 printf("STG 02\n"); 57 // Fourier変換 58 S_fft(x, y, N, -1); 59 60 //for (i = 0; i < Fr; i++) printf(" i=%d %f %f \n", i, x[i], y[i]); 61 62 // 計算結果をファイルに格納 63 fp = fopen("fft.txt", "w"); // ファイル名は fft.dat 64 for (i = 0; i < N; i++) { 65 if (x != NULL && y != NULL) { 66 pw = sqrt(x[i] * x[i] + y[i] * y[i]) * 10; // パワースペクトル 67 } 68 fq = i / (dt * Fr); // 周波数 69 //printf("%f = %d / (%f * %d)\n", fq, i, dt, N); 70 fprintf(fp, "%fHz %d\n", fq, pw); 71 } 72 printf("STG 03\n"); 73 fclose(fp); 74 fclose(audio); 75 return 0; 76} 77 78/********* Fourier変換および逆Fourier変換を行う副関数 ***************/ 79/* 入力: x[n]: 被解析波形(振幅) n; 離散データの数 */ 80/* ff: Fourier変換の場合は -1, 逆Fourier変換の場合は 1 */ 81/* 出力: ak[n]:cos関数の係数、 bk[n]:sin関数の係数 */ 82/**********************************************************************/ 83void S_fft(double ak[], double bk[], int n, int ff) { 84 int i, j, k, k1, num, nhalf, phi, phi0; 85 static int rot[N]; 86 double s, sc, c, a0, b0, tmp; 87 for (i = 0; i < n; i++) rot[i] = 0; 88 89 nhalf = n / 2; num = n / 2; sc = 2.0 * PI / n; 90 while (num >= 1) { 91 for (j = 0; j < n; j += 2 * num) { 92 phi = rot[j] / 2; phi0 = phi + nhalf; 93 c = cos(sc * phi); s = sin(sc * phi * ff); 94 for (k = j; k < j + num; k++) { 95 k1 = k + num; 96 a0 = ak[k1] * c - bk[k1] * s; b0 = ak[k1] * s + bk[k1] * c; 97 ak[k1] = ak[k] - a0; bk[k1] = bk[k] - b0; 98 ak[k] = ak[k] + a0; bk[k] = bk[k] + b0; 99 rot[k] = phi; rot[k1] = phi0; 100 } 101 } 102 num = num / 2; 103 } 104 if (ff < 0) { 105 for (i = 0; i < n; i++) { 106 ak[i] /= n; bk[i] /= n; 107 } 108 } 109 110 for (i = 0; i < n - 1; i++) { 111 if ((j = rot[i]) > i) { 112 tmp = ak[i]; ak[i] = ak[j]; ak[j] = tmp; 113 tmp = bk[i]; bk[i] = bk[j]; bk[j] = tmp; 114 } 115 } 116} 117 118 119 120double* audio_read(WAV_PRM* prm, char* filename) 121 122{ 123 124 //変数宣言 125 126 FILE* fp; 127 128 int n; 129 130 double* data; 131 132 char header_ID[4]; 133 134 long header_size; 135 136 char header_type[4]; 137 138 char fmt_ID[4]; 139 140 long fmt_size; 141 142 short fmt_format; 143 144 short fmt_channel; 145 146 long fmt_samples_per_sec; 147 148 long fmt_bytes_per_sec; 149 150 short fmt_block_size; 151 152 short fmt_bits_per_sample; 153 154 char data_ID[4]; 155 156 long data_size; 157 158 short data_data; 159 160 161 162 //wavファイルオープン 163 164 fp = fopen(filename, "rb"); 165 166 167 168 //wavデータ読み込み 169 170 fread(header_ID, 1, 4, fp); 171 172 fread(&header_size, 4, 1, fp); 173 174 fread(header_type, 1, 4, fp); 175 176 fread(fmt_ID, 1, 4, fp); 177 178 fread(&fmt_size, 4, 1, fp); 179 180 fread(&fmt_format, 2, 1, fp); 181 182 fread(&fmt_channel, 2, 1, fp); 183 184 fread(&fmt_samples_per_sec, 4, 1, fp); 185 186 fread(&fmt_bytes_per_sec, 4, 1, fp); 187 188 fread(&fmt_block_size, 2, 1, fp); 189 190 fread(&fmt_bits_per_sample, 2, 1, fp); 191 192 fread(data_ID, 1, 4, fp); 193 194 fread(&data_size, 4, 1, fp); 195 196 197 198 //パラメータ代入 199 200 prm->fs = fmt_samples_per_sec; 201 202 prm->bits = fmt_bits_per_sample; 203 204 prm->L = data_size / 2; 205 206 207 208 //音声データ代入 209 210 data = (double*)calloc(prm->L, sizeof(double)); 211 audiodatasize = (double*)malloc(sizeof(double) * prm->L); 212 213 for (n = 0; n < prm->L; n++) { 214 215 fread(&data_data, 2, 1, fp); 216 217 if (data != NULL) { 218 data[n] = (double)data_data / 32768.0; 219 } 220 221 } 222 223 224 225 fclose(fp); 226 227 return data; 228 229}

投稿2021/02/25 01:24

編集2021/02/25 08:08
Anfaenger

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/02/25 02:05 編集

結局、質問の問題をどう解決したか不明なままなのですが、解決したのであれば何をどう修正したのか記述してください。現状の回答のままでは解決方法と解釈できないので、低評価します。
退会済みユーザー

退会済みユーザー

2021/02/25 08:18

原因の追記を確認しましたので、低評価を取り下げました。
guest

0

「WAVE ファイルフォーマット」でぐぐると、Wavファイルのデータフォーマットの解説が出てきます
それに従い、実際の音声データのサイズと位置を割り出し、それらの値をもとに配列のエリアの確保、そしてデータの取得をおこないます

投稿2021/02/24 13:37

y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Anfaenger

2021/02/24 15:02

調べてみましたがよくわからないです… データのサイズを取得するところまではできましたが、 そのデータのサイズを使ってループ文を作ると永遠にループしてしまう?状況です。
y_waiwai

2021/02/24 16:37

C言語のコードを書くなら、デバッグできる環境を整えましょう。 Eclipseや、WindowsならVisualStudioなど。 コードの任意の場所で実行を止め、変数のナカミを見ることができます。そこから1行づつ実行して、コードの流れを見れるようになります そうすれば、アテズッポでコードを書かなくて済むようになります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問