C#に関しての質問なのでこちらでいいのかわからないのですが、タイトル通りwavファイルの再生についてです。
環境は .NET2003 です。
現在、学校の卒業制作としてC#でゲームの開発を行っているのですが、音楽ファイルの再生の仕方で困っています。
検索してみたところ、playsoundを使用したループ再生には非同期とループを指定すればいい、とありましたが
うまく動きませんでした。
そこでThreadを使用しsleepを使うことで擬似的にループ再生をさせているのですが、それだと都合の悪いことが多く別の方法を探しています。
お力になっていただける方がいれば、宜しくお願いします。
↓は現在のソースから抜き出したものです。
[DllImport("winmm.dll")]
private static extern bool PlaySound(string pszSound, int hmod, uint fdwSound);
static void Main(){
Thread t1 = new Thread(new ThreadStart(play));
t1.Start();
Thread.Sleep(1000000000);
}
public static void play(){
PlaySound("daichi.wav", 0, 0x00001 | 0x00008 );
}
No.3ベストアンサー
- 回答日時:
#2です。
Thread.Sleepについて誤解があるようですね。
Thread.Sleepを使ったのは、ループ再生が確認できるだけの時間、Main()から戻りたくなかったからです。ゲームはいきなり終了する事はないわけですから、Thread.Sleepを入れる必要はありません。ボタンが押された時や、その他なんらかの条件でPlaySoundを呼び出しやればいいだけです。
PlaySoundを非同期指定で呼び出すと、内部でスレッドを作成しバックグラウンドで動作しますが、その事とThread.Sleepを使う事とは全く関係ありません。ファイルを読み続けていても、画面を更新しつづけていても、その結果に大きな違いはありません。
スレッドというのは、CPUを割り当てる単位です。
CPUは1つだと仮定しますが、スレッドはOSを起動した直後でも数百くらいは存在しています。そしてOSは実行する必要があるスレッドの1つにCPUを割り当てて実行するか、実行すべきスレッドが無ければCPUをスタンバイ状態にします。
Ctrl+Alt+Delteでタスクマネージャーを起動し、パフォーマンスで確認すれば、スレッドの数もわかりますし、CPU使用率もわかります。
CPU使用率が0%であるという事は、全てのスレッドが、Thread.Sleepを呼び出したのと同じような状態になっていて、何もしていない事を意味します。
プログラムを起動するという事は、システム内に1つのプロセス(プログラムを実行する為の4GBのメモリ空間などを指す)を作成し、プロセスに実行ファイルを読み込み、プロセス内に最初に実行されるスレッドが作成される事を意味します。Main()を実行するのは、その最初のスレッドであり、Thread.Sleepを呼び出す事は自分自身を実行しているスレッドを暫くの間停止させるという事を意味します。
例えば
while (true)
;
を実行すると、CPU使用率は100%になりますが、Thread.Sleepでスレッドを眠らせている間は、そのスレッドのCPU使用率は0%になります。
Thread.Sleepを呼び出すのは、できるだけ省電力の状態で待つという事と、他のスレッドがCPUをより多く使えるようにするという意味しかありません。
わけのわからない説明になってしまったかもしれませんが、何かあれば補足下さい。
もっとも、C#は入門書を読んで実験的に3時間くらいしか使った事がないので、C#の事を聞かれても答えられないかもしれません(笑
非常に詳細な説明をしていただきありがとうございます。
おっしゃる通りThread.Sleepについて誤解をしていました。
Threadの実行時間の調整のようなものだと思いこんでしまい、よく調べずに使用していました・・・
見当違い・勘違いな質問に丁寧な説明を頂き、気持ちよく解決できました。
今度からはしっかり調べた上で関数サマ達を使いたいと思います;
本当にありがとうございました!
No.2
- 回答日時:
#1です。
試してみましたが、ループしてますね。
何か別の理由があるのかもしれませんが、得られている情報だけでは、なんとも言えません。
using System;
using System.Runtime.InteropServices;
using System.Threading;
class Sound
{
[DllImport("Winmm.dll")]
private static extern bool PlaySound(string pszSound, int hmod, uint fdwSound);
public static void Play() {
PlaySound("C:\\Windows\\media\\chimes.wav", 0, 0x00001 | 0x00008 | 0x20000);
}
public static void Stop() {
PlaySound(null, 0, 0);
}
}
class Test
{
public static void Main() {
Sound.Play();
Thread.Sleep(5000);
Sound.Stop();
Thread.Sleep(2000);
Sound.Play();
Thread.Sleep(3000);
Sound.Stop();
}
}
お礼が大変遅くなり申し訳ありませんでした。
わざわざソースを組んでいただきありがとうございます。
恐らく私の説明不足のせいなのですが、Thread.Sleep()を使わずに音楽を永久ループ再生させる方法を探していました。
音楽再生については今回初めて取り扱った為、まだ知識に乏しく
Thread.Sleep()を使う以外に方法があるのかどうかもわかりません。
VBではPlaySoundのみでループ再生が出来るようなので、
C#でもそのままサポートされているかと思ったのですが・・・。
もしまたお時間いただけるようでしたら、御教授願えれば幸いです。
もちろん自分でも解決方法を探してみます。
No.1
- 回答日時:
>うまく動きませんでした。
本格的に勉強しているなら、こんな説明の仕方をしてはいけません。何がうまくて、何がまずいかは、本人にしかわからないです。
ちなみに、"daichi.wav"がファイル名だとしたら、fdwSoundには、SND_FILENAMEを指定する必要があります。加えて、ファイル名はフルパスで指定した方が安全です。
ありがとうございます。
実務に携わっている方からのアドバイスとても為になります。
>>こんな説明の仕方をしてはいけません
よく肝に命じておきます。
うまく動かないというのは、ループ再生がされず1度の再生でストップしてしまう、という事です。
daichi.wavおっしゃる通りファイル名です。
Debugに格納してあるので、あのような表記になっていますが、フルパスで指定できるよう修正したいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- C言語・C++・C# Windows Formアプリからコンソールを呼び出して文字を出力させたい 8 2023/05/09 10:53
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- C言語・C++・C# 大量のデータを読み込んで表示する速度を改善したい 8 2023/05/07 13:29
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- C言語・C++・C# プログラム内から、MIDIファイルの一部分だけを再生する方法 1 2023/02/15 11:08
- Java java final 1 2022/06/10 22:49
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
.NetのBackgroundWorkerクラス...
-
[Windowsプログラミング] スレ...
-
一定時間ごとにメッセージを表...
-
スレッドの終了を知りたい(Wind...
-
sleep関数とは?
-
Windows上で、シグナル(SIGTERM...
-
C言語である関数への同時アクセ...
-
Macターミナルで実行中のプログ...
-
緯度、経度の 10進法と 60進法...
-
マイコンからプログラムを読み...
-
DoEvents関数って何?
-
forkについて
-
誤ってプロセスの終了をしてし...
-
WindowsAPIのCreateFile関数ま...
-
4分木の探索プログラミングにつ...
-
C言語primeについて
-
C言語における再帰呼び出しの...
-
ExcelのVBAでX=0〜1の定積分を...
-
【C言語】再帰が時間がかかる...
-
MACで動く実行ファイルをWindow...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VC++スレッドの正しい終了のさ...
-
WaitForSingleObjectの使い方に...
-
マイクロソフトedge で5チャン...
-
スレッドの安全な終了のさせ方
-
スレッドの終了はどうやるんで...
-
スレッドにて同一メモリの書き...
-
スレッドの監視方法について
-
マルチスレッドについて
-
スレッドの終了の仕方
-
Linuxでスレッド優先度って変え...
-
Windows上で、シグナル(SIGTERM...
-
LinuxでDoEvents()同等機能
-
VB2005 シリアル通信のClose処理
-
待機関数(WaitForMultipleObjec...
-
マルチスレッドプログラミング...
-
_beginthreadexで生成したスレ...
-
別スレッドからメインダイアロ...
-
msec単位のWait Timerが作れない!
-
マルチスレッドのスレッド数を...
-
.NetのBackgroundWorkerクラス...
おすすめ情報