トップページ > 記事閲覧
ChangeVolumeSoundMemの
名前:CEF 日時: 2019/05/26 14:45

はじめまして、CEFと申します。二週間前にDxLibのAndroid版をダウンロードさせていただき実機でデバッグして楽しんでいる者ですが、 どうしても解決できない問題が生じたので相談させていただきたいです。 いま、0.1秒から0.8秒程度の短く単純な音波データを生成し、PlaySoundMem関数のDX_PLAYTYPE_LOOPで再生し、決められた式によって時間とともにボリュームを 下げる、ということをやっております。Androidに簡単な演奏をさせるアプリのため、要は音が減衰していって消えるのを再現したいわけです。 ボリュームの設定にはChangeVolumeSoundMem関数を用い、LOOPモードは音の切れ目がなくなめらかにつながり、基本的にはうまくいっています。 (ボリュームがゼロになったらStopSoundMemでとめ、次に再生される時のためにChangeVolumeSoundMemでまたボリュームを上げておきます) ところが音波データによっては 「ボリュームを下げてゆくと途中で一瞬、ボリュームが増す」という問題が発生し、悩まされています。 ここで言う「ボリュームが増す」とはChangeVolumeSoundMemにおける"int VolumePal"にあたる数値が増えるということではなく、 実機から聴こえる音量のことです。 実際に聴いていただければ一発で伝わるのですが、簡単に言うと、小さくなっていった音が一瞬復活してから消える、という状況です。 トゥー――――――・・・・・ン が本来の減衰としますと、 トゥー――― ・・トゥー・・ン と鳴ってしまいます。ひどいケースになると、 トゥー・トゥー―――・・・・ン と言う具合に、音が連続で鳴らされてるかのようになります。 以下にこの一週間の「後鳴り現象」との格闘を少々詳しく報告いたします。問題のご理解と解決のヒントにしていただければと思いまして↓ 当初、PC(ウィンドウズ)の自作プログラムで生成した「10000と-10000をあらかじめ設定した周波数で繰り返す矩形波データの.wavファイル」をassetsから読み込んで 鳴らしていた時にはこの問題は発生しませんでした(あるいは、鳴らすのに夢中で気づかなかった可能性もありますが、少なくともその頃に録音したデモを 聞きなおしてみても後鳴り現象は確認できません)。 しかし次に、読み込むファイルを「32767と-32767を繰り返す矩形波データの.wavファイル」に変えた(つまり振幅を最大にした)ところ、 この現象が発生するようになりました。 私のプログラムのミスかと思いじっくり検討しましたが、音の減衰に使う一次式も二次式もともに問題ありませんでした。 そこで、printfDxで現在の設定ボリュームを表示しつつ、255から一つずつ下げていって実験しましたところ、設定ボリュームが115から114をまたぐ時に、 実際の音量が一瞬増加することが分かりました。114から始めるとその先はきれいに減衰し、逆に115から始めると鳴らし始めた直後に増加します。 (なお、ここまで音波データは16ビット、2チャンネル、44100Hzでやっております) となるとこれはChangeVolumeSoundMem関数の側の問題ではないか、振幅が大きすぎたのかなと思い、「最大10000、最小-10000」に戻しました。 すると後鳴り現象はなくなり(厳密には、アプリを起動させた直後にはかすかに生じることがあります)、ひとまず安心しました。 ところがその後、MakeSoftSoundCustomからLoadSoundMemFromSoftSoundの流れで新たな音波データの生成と再生を行いますと、やはり後鳴りが発生して しまいます。SoftSoundに書き込む音波データでも、振幅は「最大10000、最小-10000」で統一していますが後鳴り現象はおさえられません。しかも、 新たな音波データの再生―減衰のプロセスで後鳴りが始まると、それまで問題なかった最初の音(10000と-10000を繰り返す矩形波)まで、後鳴りする ようになってしまいます。 (なお、MakeSoftSoundCustomの活用で音波データの生成、取得をプログラム内で完結できるようになってからは、.wavファイルの事前読み込みは 行っていません。また、音波データのサンプリング周波数を88200Hzにしております) まだ試していないことと言えば、生成する音波データを例えば5秒くらいの長尺にして、LOOPではなくBACKモードで再生し、一度の再生中にChangeVolumeSoundMem で減衰させる、というアプローチくらいです。もしかしたらそれで解消されるのかもしれませんが、多くの音波データを扱うプログラムなので、 あまり各データを大きくしたくありません。そこで思い切って相談させていただきました。 これが解決できないと、アプリ全体の方針を見直すことになります。お忙しいところ恐縮ですが、どうかお助け下さい。よろしくお願いします。 長文になり失礼いたしました。末筆ながら、素人でもAndroidアプリの開発を楽しめる環境をつくって下さり本当にありがとうございます!
メンテ

Page: 1 |

Re: ChangeVolumeSoundMemの ( No.1 )
名前:CEF 日時:2019/05/26 17:16

その後のチェックで一点、私のプログラムの側にミスが見つかりました。 前の投稿に「SoftSoundに書き込む音波データでも、振幅は「最大10000、最小-10000」で統一していますが後鳴り現象はおさえられません。しかも、 新たな音波データの再生―減衰のプロセスで後鳴りが始まると、それまで問題なかった最初の音(10000と-10000を繰り返す矩形波)まで、後鳴りする ようになってしまいます。」と書きましたが、実際には32767や-32768の幅を持つデータが紛れ込んでおりました! どうりで変な音がするわけです(汗)。 そこを直し、すべてを「10000〜-10000」におさめたところ、後鳴りは発生しておりません(前述のように、アプリの起動直後は別として)。 10000〜-10000の幅があれば当初の目的には十分なので、これで進めようと思います。お騒がせしました。 ただ、振幅をあまり大きくするとChangeVolumeSoundMem関数によるなめらかなボリューム調節が不安定になるのは確かなようですので、お時間のある時にでも、 ご確認いただければと思います!
メンテ
Re: ChangeVolumeSoundMemの ( No.2 )
名前:管理人 日時:2019/05/27 23:29

はじめまして、DXライブラリの管理人です 現象を再現しようと思い、以下のようなプログラム( 44100Hz 2ch 16bit の 2000Hz、 振幅 -20000〜20000 の 正弦波をループ再生しながら ChangeVolumeSoundMem で音量を上下させる )を作成してみました #include "Dxlib.h" #include <math.h> #define SAMPLE_NUM (44100) #define ANGLE_RATE (2000.0f) #define POWER (20000) int android_main() { int SoftSoundHandle ; int SoundHandle ; int Volume ; int VolumeAdd ; // DXライブラリ初期化処理 if( DxLib_Init() == -1 ) { // エラーが起きたら直ちに終了 return -1 ; } // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // ソフトウェアサウンドハンドルを作成 SoftSoundHandle = MakeSoftSound2Ch16Bit44KHz( SAMPLE_NUM ) ; // 波形を書き込み for( int i = 0 ; i < SAMPLE_NUM ; i ++ ) { int Sample ; Sample = ( int )( sin( ANGLE_RATE * DX_PI_F * 2.0f / SAMPLE_NUM * i ) * POWER ) ; WriteSoftSoundData( SoftSoundHandle, i, Sample, Sample ) ; } // サウンドハンドルを作成 SoundHandle = LoadSoundMemFromSoftSound( SoftSoundHandle ) ; // 再生開始 PlaySoundMem( SoundHandle, DX_PLAYTYPE_LOOP ) ; // ボリュームの初期化 Volume = 255 ; VolumeAdd = -1 ; // メインループ while( ProcessMessage() == 0 ) { // 画面を初期化 ClearDrawScreen() ; // ボリューム処理 Volume += VolumeAdd ; if( Volume == 0 || Volume == 255 ) { VolumeAdd = -VolumeAdd ; } ChangeVolumeSoundMem( Volume, SoundHandle ) ; // ボリュームを描画 DrawFormatString( 0, 0, GetColor( 255,255,255 ), "Volume:%d", Volume ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // DXライブラリ使用の終了処理 DxLib_End() ; // ソフトの終了 return 0 ; } ただ、手元の実機( SO-04J と F-02H )では音量の設定が不安定になるということはありませんでした 再現テスト用のプログラムとしては上記のプログラムで問題ないでしょうか? そして、もし問題ないとのことでしたら、CEFさんの環境では上記のプログラムでも音量設定の 不安定な現象が発生するかお試しいただけないでしょうか? m(_ _)m
メンテ
Re: ChangeVolumeSoundMemの ( No.3 )
名前:CEF 日時:2019/05/31 18:37

管理人さま お返事ありがとうございます。再現テスト用のプログラムを試したところ、私の環境でも音量は255〜0までなめらかに推移しました。 振幅をさらに大きくしても、また周波数を変えても同様にうまくいきました。 ところが、より私の状況に近づけるため以下のように再現テスト用プログラムをいじらせていただきましたところ、やはり先述の現象が起きてしまいます。 お手数ですがご確認いただけると幸いです。↓ #include "Dxlib.h" #include <math.h>  //CEFによる改変・・#defineはすべて削除 int android_main(void) { int SoftSoundHandle; int SoundHandle; int Volume; int VolumeAdd; // DXライブラリ初期化処理 if (DxLib_Init() == -1) { // エラーが起きたら直ちに終了 return -1; } // 描画先を裏画面にする SetDrawScreen(DX_SCREEN_BACK); // ソフトウェアサウンドハンドルを作成 SoftSoundHandle = MakeSoftSoundCustom(2,16,88200,802*88); //CEFによる改変 // 波形を書き込み  CEFによる改変・・サインカーブではなく約110Hz、振幅20000,-20000の矩形波およそ0.8秒分に for (int p = 0; p < 88; p++) { for (int i = 0; i < 401; i++) { WriteSoftSoundData(SoftSoundHandle, i + (p * 802), 20000, 20000); WriteSoftSoundData(SoftSoundHandle, (801 - i) + (p * 802), -20000, -20000); } } // サウンドハンドルを作成 SoundHandle = LoadSoundMemFromSoftSound(SoftSoundHandle); // ボリュームの初期化 Volume = 255; VolumeAdd = -1; // メインループ // 画面を初期化 // 再生開始 PlaySoundMem(SoundHandle, DX_PLAYTYPE_LOOP); while (ProcessMessage() == 0) { // 画面を初期化 ClearDrawScreen(); // ボリューム処理 Volume += VolumeAdd; if (Volume == 0 || Volume == 255) { VolumeAdd = -VolumeAdd; } ChangeVolumeSoundMem(Volume, SoundHandle); // ボリュームを描画 DrawFormatString(0, 0, GetColor(255, 255, 255), "Volume:%d", Volume); // 裏画面の内容を表画面に反映 ScreenFlip(); WaitTimer(50);//CEFによる追加・・確認しやすくするためループを少し遅らせる } // DXライブラリ使用の終了処理 DxLib_End(); // ソフトの終了 return 0; } これで実験したところ、Volumeの表示が160〜170を通過するあたりで、音量の推移が不連続になるのが聞き取れます。 音量下降時にはいわゆる後鳴り現象が、逆に音量上昇時には一瞬音量が下がるようです。管理人さまの環境ではいかがでしょうか? もし、私の波形の作り方に欠陥があるのであればご指南いただけると嬉しいです。よろしくお願いします。
メンテ
Re: ChangeVolumeSoundMemの ( No.4 )
名前:管理人 日時:2019/06/02 04:01

載せていただいたプログラムを前述と同じ環境( SO-04J と F-02H )で実行してみましたが、 160〜170を通過する辺りでも問題なく音量が推移しました CEFさんがお使いの機器固有の現象かもしれません… > もし、私の波形の作り方に欠陥があるのであればご指南いただけると嬉しいです。よろしくお願いします。 波形の作り方に問題は無いと思います
メンテ
Re: ChangeVolumeSoundMemの ( No.5 )
名前:UB 日時:2019/06/02 09:23

ちなみにFireHD10だと88.2kHzではLoadSoundMemFromSoftSound(SoftSoundHandle)がエラー(-1)になりました
メンテ
Re: ChangeVolumeSoundMemの ( No.6 )
名前:CEF(解決?) 日時:2019/06/02 14:02

スマホから失礼します。 管理人様に言われて初めて、私の使用してるAQUOSの問題なのかと疑い始め、 調べてみたところ驚くべきことが分かりました。 どうやらこの現象は、イヤホンなりミニアンプなりをスマホに繋いでる時にだけ、生じるようなのです! スマホ本体スピーカーで鳴らす限り、振幅最大で実験しても問題はありませんでした。 イヤホンをつなぐ場合、「メディアの音量」を抑えておけば滑らかにゆくようです。 おそらくスマホが音量の幅に応じて勝手に調節するようにしてあるのでしょうが、 全く余計なことしてくれたものです… ともあれ、原因は分かったのでよかったです。 ここに相談しなかったらいつまでも本体の問題には目を向けなかったかもしれません。 ありがとうございました! UB様 情報ありがとうございます。エラーになるのですか! それは怖い話を聞きました。 機種によって色々違うようで、油断できませんね。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存