質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.46%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

2回答

1617閲覧

WaveOut関数を用いて、作成した波形を再生したいが、振幅を変えても音量が変わらない。

P0ngCh4ng

総合スコア1

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2021/08/01 02:58

編集2021/08/01 04:26

起こっている問題

やさしい音と音楽のプログラミング
こちらの書籍を参考にしているのですが、waveOutWrite関数に入力する波形をサンプルのソースコードで作成しています。
試しに実行するととんでもない音量で再生されました。

調べてみると、だいぶ古い記事ですが、これによると、

WAVEFORMATEX は再生したい Hz、ビットレート、チャンネル数を設定するものです。音量というデータは .wav ファイルには存在しません。

というように、音量を調整する時は通常、入力する波形の振幅で調整するようです。
ですが、ソースコードの振幅を変更しても、音量が変わっているように感じません。
あるいは、振幅を小さくしても、私の設定が悪いのか音量が大きすぎてその差を感じられないのか、わかりません。

書籍は、VisualStudioを使うことを推奨していますが、その設定等に関する記述がなく、どこを変えると最終的な音量が変わるのかわかりません。
今は、Windowsの音量ミキサーの場所から音量を下げていますが、1/100にしても音量は大きいし、プロジェクトを変えるたびにこの操作をするのが億劫であるため、コードかVisualStudioの設定、あるいはWindowsの設定を変更して、適切な音量に設定したいです。
ソースコードだけの問題ではないかもしれないのですが、知見のある方がいらっしゃいましたら、どうぞご教授お願い致します。
必要そうな情報はできるだけ詳細に記載するようにしていますが、不明なことがあれば、おっしゃっていただければ追記します。

該当のソースコード

書籍に記載されている内容ですが、WebページからDL出来るため、引用という形で記載します。

c

1#include "stdafx.h" 2#include <stdio.h> 3#include <windows.h> 4#include <mmsystem.h> 5#include <math.h> 6#pragma comment( lib, "winmm.lib" ) 7#define SRATE 44100 // サンプリングレート 44.1kHz 8#define PI 3.14159286 // π 9 10int main() 11{ 12 // wave関係変数 13 static HWAVEOUT hWave; 14 static WAVEHDR whdr; 15 WAVEFORMATEX wfe; 16 static char *bWave; 17 unsigned int count = 0; 18 float b_time = 1.0; // 鳴らす時間(秒)の設定 19 float f0 = 440.0; // ラ(A4)440Hz 20 int amplitude = 2; // 振幅 21 int data_len = (int)SRATE * b_time; // データの長さ 22 bWave = (char *)malloc(data_len); // 波形データのメモリ確保 23 char tmp; 24 // 1秒分のデータを配列に設定する 25 for (count = 0; count < data_len; count++ ) { 26 tmp = (char)(amplitude * sin(2 * PI * f0 * count / SRATE)); 27 printf("%d", tmp); 28 if (bWave != NULL) { 29 bWave[count] = tmp; 30 } 31 } 32 33 wfe.wFormatTag = WAVE_FORMAT_PCM; 34 wfe.nChannels = 1; 35 wfe.nSamplesPerSec = SRATE; 36 wfe.nAvgBytesPerSec = SRATE; 37 wfe.wBitsPerSample = 8; 38 wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; 39 40 // デバイスのオープン 41 waveOutOpen(&hWave, WAVE_MAPPER, &wfe, 0, 0, CALLBACK_NULL); 42 43 whdr.lpData = bWave; 44 whdr.dwBufferLength = data_len; 45 whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; 46 whdr.dwLoops = 1; 47 48 // ヘッダーの準備 49 waveOutPrepareHeader(hWave, &whdr, sizeof(WAVEHDR)); 50 // 波形データの書き出し(再生) 51 waveOutWrite(hWave, &whdr, sizeof(WAVEHDR)); 52 53 printf("press any key !"); 54 getchar(); // キー入力待ち 55 return 0; 56} 57 58

引用元

試したこと

4行目にある通り、波形を数値で出力したところ、振幅の値に応じて変化していることが確認できています。

補足情報(FW/ツールのバージョンなど)

Windows 10 バージョン 2004

Microsoft Visual Studio Community 2019 Version 16.10.4

Visual C++ 2019

###解決後のソースコード
原因は、回答していただいたお二方の回答を見ていただくとして、簡素ですが修正したコードを記載しておきます。
同じように困っている方に助けになれば幸いです。

c

1 for (count = 0; count < data_len; count++ ) { 2 tmp = (unsigned char)(amplitude * sin(2 * PI * f0 * count / SRATE)); 3 tmp = tmp + 128; //追加した1行 4 printf(" %x", tmp); 5 if (bWave != NULL) { 6 bWave[count] = tmp; 7 } 8 } 9

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/08/01 03:44 編集

完全なフォーマットが判らないので、WAVEFORMATEXの初期化部を提示した方がいいです。 サンプリングレートだけじゃ判りません。 森北出版のサイトでソースがDL出来るので、多分引用元を記述すれば引用しても問題ないと思いますが。 https://www.morikita.co.jp/books/mid/085441
P0ngCh4ng

2021/08/01 03:49

ありがとうございます。質問にソースコードをすべて記載しました。
guest

回答2

0

まずPCMフォーマットの基本を理解する必要があります。
WAVEデータの作成と再生

量子化ビット数が8ビットの場合は、0~255 の範囲で振幅値を表現します。128 が中心(振幅なし)です。
16ビットの場合は、-32768~32767 の範囲で振幅値を表現します。0 が中心(振幅なし)です。

8bitなら128が波形のグラフの中心(無音)になるので、ikadzuchiさんの言う128を足す、というのはそういうことです。charだと127までなので、unsigned charの配列にしましょう。

投稿2021/08/01 03:58

編集2021/08/01 04:10
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

P0ngCh4ng

2021/08/01 04:23

教えていただいたページ、非常に参考になりました。 ベストアンサーをお一人にしか送れないのは非常に残念ですが、このお返事をもって第2のベストアンサーとさせていただきたいです。ありがとうございます。
退会済みユーザー

退会済みユーザー

2021/08/01 04:25

8bitだと何故か0が原点じゃないのがモヤっとするへんな規格なんですよね。昔無音状態作ろうとして0書き込んでやらかした記憶があります。
guest

0

ベストアンサー

具体的な出力データが分かりませんが、
char型を使っているということは8bit/サンプルなのでしょうが、8bit/サンプルのWavは値を符号なしの0~255で扱います。
見たところsinで出た正負のある値をそのまま突っ込んでいますので、音量をどう変えようとも最小値と最大値を行き来する波形になります。
128を足してください。

投稿2021/08/01 03:31

ikadzuchi

総合スコア3047

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

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

P0ngCh4ng

2021/08/01 04:20

ソースコードをすべて載せていなかったのにも関わらず、ありがとうございます。 解決しました。 書籍のサンプルコードをそのまま使ってもこういうことは起こるんですね... なにはともあれこれで耳は無事そうです。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問