dポイントプレゼントキャンペーン実施中!

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 );
}

A 回答 (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#の事を聞かれても答えられないかもしれません(笑
    • good
    • 0
この回答へのお礼

非常に詳細な説明をしていただきありがとうございます。
おっしゃる通りThread.Sleepについて誤解をしていました。
Threadの実行時間の調整のようなものだと思いこんでしまい、よく調べずに使用していました・・・
見当違い・勘違いな質問に丁寧な説明を頂き、気持ちよく解決できました。
今度からはしっかり調べた上で関数サマ達を使いたいと思います;
本当にありがとうございました!

お礼日時:2005/11/18 18:44

#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();
}
}
    • good
    • 0
この回答へのお礼

お礼が大変遅くなり申し訳ありませんでした。

わざわざソースを組んでいただきありがとうございます。
恐らく私の説明不足のせいなのですが、Thread.Sleep()を使わずに音楽を永久ループ再生させる方法を探していました。
音楽再生については今回初めて取り扱った為、まだ知識に乏しく
Thread.Sleep()を使う以外に方法があるのかどうかもわかりません。
VBではPlaySoundのみでループ再生が出来るようなので、
C#でもそのままサポートされているかと思ったのですが・・・。
もしまたお時間いただけるようでしたら、御教授願えれば幸いです。
もちろん自分でも解決方法を探してみます。

お礼日時:2005/11/14 22:18

>うまく動きませんでした。



本格的に勉強しているなら、こんな説明の仕方をしてはいけません。何がうまくて、何がまずいかは、本人にしかわからないです。

ちなみに、"daichi.wav"がファイル名だとしたら、fdwSoundには、SND_FILENAMEを指定する必要があります。加えて、ファイル名はフルパスで指定した方が安全です。
    • good
    • 0
この回答へのお礼

ありがとうございます。
実務に携わっている方からのアドバイスとても為になります。
>>こんな説明の仕方をしてはいけません
よく肝に命じておきます。
うまく動かないというのは、ループ再生がされず1度の再生でストップしてしまう、という事です。
daichi.wavおっしゃる通りファイル名です。
Debugに格納してあるので、あのような表記になっていますが、フルパスで指定できるよう修正したいと思います。

お礼日時:2005/11/07 22:19

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!