音量変更のプログラム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
だんごさん
記事: 273
登録日時: 12年前

音量変更のプログラム

#1

投稿記事 by だんごさん » 11年前

下記のサンプルコードについて質問があります。
音楽の音量変更をするプログラムです。

コード:

#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
		 LPSTR lpCmdLine, int nCmdShow )
{
	int SHandle ;

	int volume = 255 ;

	ChangeWindowMode( TRUE );

	SetAlwaysRunFlag( TRUE );

	if( DxLib_Init() == -1 )	// DXライブラリ初期化処理
	{
		 return -1;	// エラーが起きたら直ちに終了
	}

	// test.wavのメモリへの読み込みサウンドハンドルをSHandleに保存します
	SHandle = LoadSoundMem( "test.mp3" ) ;

		//音量変更
	ChangeVolumeSoundMem( volume , SHandle );

	// 読みこんだ音をバックグラウンド再生します(『PlaySoundMem』関数使用)
	PlaySoundMem( SHandle , DX_PLAYTYPE_BACK ) ;

	//裏画面
	SetDrawScreen( DX_SCREEN_BACK );


	// Aキー押されるまでループ
	while(CheckHitKey(KEY_INPUT_A)==0 && ClearDrawScreen()==0)
	{	
		// メッセージ処理
		if( ProcessMessage() == -1 )
		{
			break ;	// エラーが起きたらループを抜ける
		}

//
//リアルタイムで音量変更するときはコメントアウトしてください
//      ↓     ↓      ↓      ↓

		//if(CheckHitKey(KEY_INPUT_DOWN) == 1 ){
		//	volume--;
		//}
		//if(volume < 0)
		//	volume = 0;

		//if(CheckHitKey(KEY_INPUT_UP) == 1 ){
		//	volume++;
		//}
		//if(volume > 255)
		//	volume = 255;

		//ChangeVolumeSoundMem( volume , SHandle );


//   ↑     ↑      ↑      ↑


		DrawFormatString( 0, 0, GetColor(255,255,255) , "volume = %d    %d/10000" , volume , GetVolumeSoundMem( SHandle )); 
		
		ScreenFlip();
	}

	DxLib_End() ;		// DXライブラリ使用の終了処理

	return 0 ;		// ソフトの終了
}

えーと、まずコードは正しいでしょうか?デバッグというわけではなく、ループでChangeVolumeSoundMemを呼び出している点など中身の問題です。(デバッグはもちろんしております)

コードは正常という前提で本題です。
リアルタイムで音量を変更していると、0~255の0に近くなるほど急激に音量が下がります。このようなことが前にもおこり、ここで質問させていただきましたがその時は変数を割って求めていたことが原因でした。
しかし今回は数値を割ってもいないし、ただ数値を上下しているだけなのに音量に異常が起きています。
もしかしたらコードが問題なのかもしれませんがなぜなのかわからない状態です。

私の場合、volumeが1のときGetVolumeSoundMem(音量を取得する)は7594/10000、volumeが30で9071/10000、volumeが200のとき9895/10000となります。

VC++2008
Windows7 HP
DxLib 3.10a
 Dango San

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 音量変更のプログラム

#2

投稿記事 by softya(ソフト屋) » 11年前

当方では、ちゃんと音量が下がるように思います。
すごく感覚的なものなので「急激に音量が下がります。」が感覚の違いという可能性もあります。
あと考えられのは、PCの音声出力系の特性やスピーカー内蔵アンプの特性なども考えられますね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

だんごさん
記事: 273
登録日時: 12年前

Re: 音量変更のプログラム

#3

投稿記事 by だんごさん » 11年前

softya(ソフト屋) さんが書きました:すごく感覚的なものなので「急激に音量が下がります。」が感覚の違いという可能性もあります。
>>私の場合、volumeが1のときGetVolumeSoundMem(音量を取得する)は7594/10000、volumeが30で9071/10000、volumeが200のとき9895/10000となります。
初っ端から音量が7594でvolumeが上がるごとに少しずつしか音量が上がらないことが分かるので、確実だと思います。
逆に言えばvolumeが下がるごとに段々音量の変化が大きくなるということです。

ですが、いろんなDxLibソフトでもこのような症状がみられるので
softya(ソフト屋) さんが書きました:あと考えられのは、PCの音声出力系の特性やスピーカー内蔵アンプの特性なども考えられますね。
上記が原因かと思います。
が、手始めに何を調べていけばよいのかわかりません…。
 Dango San

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 音量変更のプログラム

#4

投稿記事 by softya(ソフト屋) » 11年前

数値に関しては同じです。なので内部的な数値が関係有るとは思えません。

>上記が原因かと思います。
>が、手始めに何を調べていけばよいのかわかりません…。

デバッグの基本ですが問題が何処にあるのか切り分けることです。
関連する要素をできるだけ書き出してみましょう。
勉強のため、書きだしてみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

だんごさん
記事: 273
登録日時: 12年前

Re: 音量変更のプログラム

#5

投稿記事 by だんごさん » 11年前

>数値に関しては同じです。なので内部的な数値が関係有るとは思えません。
というのは、
>>私の場合、volumeが1のときGetVolumeSoundMem(音量を取得する)は7594/10000、volumeが30で9071/10000、volumeが200のとき9895/10000となります。
これと同じ数値が出るということでしょうか?

softya(ソフト屋) さんが書きました:デバッグの基本ですが問題が何処にあるのか切り分けることです。関連する要素をできるだけ書き出してみましょう。勉強のため、書きだしてみてください。
・音量を変更するChangeVolumeSoundMem
・スピーカー(の設定など)
・サウンドデータをロードするかしないか
・サウンド形式

んー?こんな感じですか??
 Dango San

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 音量変更のプログラム

#6

投稿記事 by softya(ソフト屋) » 11年前

私も同じ数値が出ます。 この場合は、どんな意味があるかは非公開関数なので不明です。

さて問題の洗い出しですが。

a)音量を変更するChangeVolumeSoundMem
b)スピーカー(の設定など)
c)サウンドデータをロードするかしないか
d)サウンド形式

a)に関してはChangeVolumeSoundMem以外の方法を考えてみてください。
b)c)d)は試せると思うので確認をしてみてください。

比較検討なので、私の考えるデータの流れから考えてみます。
1) mp3データが原因
2) DXライブラリが原因
3) DirectSoundが原因
4) サウンドドライバが原因
5) PCのサウンド部分が原因
6) スピーカアンプが原因

で、テスト内容です。
1)は既に出てますね。
2)が原因ならDXライブラリ以外のDirectXゲームなどで確認できると思います。
3)が原因ならDirectSoundを使う他のmp3プレーヤーなどで確認できると思います。
4)が原因ならマスターボリュームでも同じ事が起こるはずです。あるいはDirectSoundを使わないmp3プレーヤーでも同じ事が起こるでしょう。
5)が原因ならこれは他のPCが必要です。
6)が原因ならヘッドフォンなどをつないでみましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

だんごさん
記事: 273
登録日時: 12年前

Re: 音量変更のプログラム

#7

投稿記事 by だんごさん » 11年前

すみません、まだテストは行っていないものもありますが、気づいた点だけ書かせていただきます。

・AerobeatPlusなどのソフトでは正常に音量変更が行われています。明らかに音量が違うので確実です。
・Windowsの音量ミキサーについてですが、音量は変更可能ですが音量レベル?現在の音量が緑のバーで表示されるのがありません。音量変更は正常です。
・音楽再生ソフトの音量変更は正常です。DirectSoundは使用していないと思われます。高確率で…
・ヘッドフォンに変更しても変わりません。
・モニターのオーディオ設定は特に変わりはありません。

何かと問題点が絞られた感じなので色々試してみます。
 Dango San

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 音量変更のプログラム

#8

投稿記事 by softya(ソフト屋) » 11年前

ChangeVolumeSoundMem()は隠し関数じゃなかったですね。失礼しました。
ところで、PlayMusic()してSetVolumeMusic()ではどうでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
qwea
記事: 14
登録日時: 13年前

Re: 音量変更のプログラム

#9

投稿記事 by qwea » 11年前

横槍で失礼なのですが、この記事が参考になりませんかね?

http://hpcgi2.nifty.com/natupaji/bbs/pa ... st&no=1486

以前自分も詰まったところなので…

だんごさん
記事: 273
登録日時: 12年前

Re: 音量変更のプログラム

#10

投稿記事 by だんごさん » 11年前

softya(ソフト屋) さんが書きました:ところで、PlayMusic()してSetVolumeMusic()ではどうでしょうか?
ロードした時と同様の結果です。症状は治っていません。

qweaさん、ご返答ありがとうございます。参考にして今からやってみます。
 Dango San

だんごさん
記事: 273
登録日時: 12年前

Re: 音量変更のプログラム

#11

投稿記事 by だんごさん » 11年前

色々実証してみようと試みたのですが、URL先を読んでもチンプンカンプンで…。申し訳ないです。
dbに変換する関数も一体何があってそういう計算になるのかわからない状態です。
言い訳にしかなりませんがまだ高校入ってやっと1年くらいなもので…。logとかはまだ習っていません。

とりあえずURL先の質問と症状が全く同じような感じですので原因は大体分かりました。
あとはどういうプログラムを書けばよいかですね。
 Dango San

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 音量変更のプログラム

#12

投稿記事 by softya(ソフト屋) » 11年前

こっちの関数を使って
extern int SetVolumeSoundMem( int VolumePal, int SoundHandle ) ; // サウンドハンドルのボリュームを設定する( 100分の1デシベル単位 )

この関数はdb単位なので、Dixq さんの質問に出てきた関数
// % 単位の値を渡し、 dB 単位に変換する
static inline long Calc_dB( int par ){
return (par == 0) ? -10000 : ((int)(log10f((float)par) * 5000.0f) - 10000);
}
この値を更に100で割るだけでしょう。
SetVolumeSoundMem( Calc_dB(par)/100,
こんな感じ?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

だんごさん
記事: 273
登録日時: 12年前

Re: 音量変更のプログラム

#13

投稿記事 by だんごさん » 11年前

softya(ソフト屋)さん、ありがとうございます!

>>上記の式は私が DirectSound を直接扱っていたときに使用していた計算関数です。
>>しかし、範囲が違う(0 ~ -10000 を返す)し、%より細かい単位を指定できないのでそのままでは使えませんが。
範囲が違うというのは大丈夫ですよね…?

それから、計算式にあるlog10fというのはなんでしょうか?実行したら綺麗にエラーが出てきました。おそらくfloat型10のlogということで合っていますか?…というのを前提としてmath.h追加してlogを計算しましたが予想通り意味不明な値が返りました・・・
 Dango San

FUNK
記事: 25
登録日時: 11年前

Re: 音量変更のプログラム

#14

投稿記事 by FUNK » 11年前

私も昔同じ様な問題を抱えまして、
上記で上がったURL先の内容を元に、関数を作成して問題を解決しました。
今も現役で使用できているのでよろしかったら参考にしてください。

コード:

// 一次関数的デシベル変換
// 引数の範囲は0~255
long CalcDB( int sound_val )
{
	int par;

	par = 100 * sound_val / 255;

    return ( par == 0 ) ? 0 : ( (int)( log10f( (float)par ) * 5000.0f ) );
}

SetVolumeSoundMem( CalcDB( 255 ), sound_handle );
Boogaloo is funk feelin'.

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 音量変更のプログラム

#15

投稿記事 by softya(ソフト屋) » 11年前

昨日は寝ぼけていたようです。SetVolumeSoundMem( Calc_dB(par)/100,だと単位が有ってない!
FUNKさんの関数を使ってみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

だんごさん
記事: 273
登録日時: 12年前

Re: 音量変更のプログラム

#16

投稿記事 by だんごさん » 11年前

私も寝ぼけていたようです。log10fっていう関数があったのに変な解釈をしてしまいました。

問題はFUNKさんの関数で無事解決しました。関数の計算は未だ理解できないですが綺麗に音量変更ができています。
ありがとうございました。
 Dango San

閉鎖

“C言語何でも質問掲示板” へ戻る