【C言語】第10章第13回:音声信号処理プログラムの実装
本記事では、C言語を用いて基本的な音声信号処理プログラムを構築します。オーディオデータの読み込み、処理、保存方法を学びます。
0. 記事の概要
この記事を読むメリット
- 信号処理の基礎理解:音声データの操作や編集方法を学べます。
- 実践的なプログラム作成:フィルタリングや増幅など、オーディオデータの加工スキルを身につけられます。
- 応用力の向上:音声処理の技術を活かして、音響効果や音声認識システムの構築に挑戦できます。
この記事で学べること
- WAVファイルの基本構造
- オーディオデータの操作方法
- 音量増幅の実装
1. 音声信号処理プログラムの基本設計
1.1 WAVファイルの基本構造
WAVファイルは以下の部分で構成されています。
- RIFFヘッダー(ファイルの識別情報)
- フォーマットチャンク(音声のサンプルレートやチャネル数を記録)
- データチャンク(音声データの実際の波形情報)
1.2 プログラムの機能
このプログラムでは以下の基本機能を実装します。
- WAVファイルの読み込み
- 音量増幅の実装
- 加工済みデータの保存
2. コード例と詳細解説
2.1 基本コード例
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char chunkID[4];
unsigned int chunkSize;
char format[4];
} RIFFHeader;
typedef struct {
char subchunk1ID[4];
unsigned int subchunk1Size;
unsigned short audioFormat;
unsigned short numChannels;
unsigned int sampleRate;
unsigned int byteRate;
unsigned short blockAlign;
unsigned short bitsPerSample;
} FormatChunk;
typedef struct {
char subchunk2ID[4];
unsigned int subchunk2Size;
} DataChunk;
void amplifyAudio(short *data, unsigned int dataSize, float factor) {
for (unsigned int i = 0; i < dataSize; i++) {
int amplified = data[i] * factor;
if (amplified > 32767) amplified = 32767;
if (amplified < -32768) amplified = -32768;
data[i] = amplified;
}
}
int main() {
FILE *input = fopen("input.wav", "rb");
if (!input) {
perror("ファイルを開けませんでした");
return 1;
}
RIFFHeader riffHeader;
FormatChunk formatChunk;
DataChunk dataChunk;
fread(&riffHeader, sizeof(RIFFHeader), 1, input);
fread(&formatChunk, sizeof(FormatChunk), 1, input);
fread(&dataChunk, sizeof(DataChunk), 1, input);
short *audioData = malloc(dataChunk.subchunk2Size);
fread(audioData, dataChunk.subchunk2Size, 1, input);
fclose(input);
amplifyAudio(audioData, dataChunk.subchunk2Size / sizeof(short), 1.5f);
FILE *output = fopen("output.wav", "wb");
if (!output) {
perror("出力ファイルを作成できませんでした");
free(audioData);
return 1;
}
fwrite(&riffHeader, sizeof(RIFFHeader), 1, output);
fwrite(&formatChunk, sizeof(FormatChunk), 1, output);
fwrite(&dataChunk, sizeof(DataChunk), 1, output);
fwrite(audioData, dataChunk.subchunk2Size, 1, output);
fclose(output);
free(audioData);
printf("音声信号の増幅が完了しました!\\n");
return 0;
}
動作解説
- データ読み込み:WAVファイルのヘッダー情報と音声データを読み取ります。
- 音量増幅:`amplifyAudio`関数で各サンプル値を指定した倍率で増幅します。
- 結果の保存:加工済みデータを新しいWAVファイルに保存します。
3. 練習問題
以下の課題に挑戦して、音声信号処理プログラムを拡張してみましょう。
- 音声データの逆再生機能を追加してください。
- 高音域を強調するフィルタリング機能を実装してください。
- データをリアルタイムで可視化する機能を追加してください。
4. 練習問題の解答と解説
問1の解答例
// 音声データの逆再生
void reverseAudio(short *data, unsigned int dataSize) {
for (unsigned int i = 0; i < dataSize / 2; i++) {
short temp = data[i];
data[i] = data[dataSize - 1 - i];
data[dataSize - 1 - i] = temp;
}
}
この関数を使用して、音声データを逆順に並べ替えます。
5. まとめ
本記事では、C言語を用いてWAVファイルの読み込み、編集、保存を行う音声信号処理プログラムを作成しました。さらに高度な機能を追加して、実用的な音声処理ツールを開発してみましょう。