パソコンが再生している音楽を録音
パソコンが再生している音楽を録音
タイトルにもあるとおり、あるソフトでパソコンが再生している音楽を
録音しなければならなくなったのですが、どうやればいいか分かりません。
どなたか方法を知りませんでしょうか。よければ録音品質も設定できる
ようにしたいです。教えてください。お願いします。
録音しなければならなくなったのですが、どうやればいいか分かりません。
どなたか方法を知りませんでしょうか。よければ録音品質も設定できる
ようにしたいです。教えてください。お願いします。
Re: パソコンが再生している音楽を録音
> どなたか方法を知りませんでしょうか。よければ録音品質も設定できる
> ようにしたいです。教えてください。お願いします。
コマンドボタン1が録音でコマンドボタン2が再生になっています。
説明するのは大変なので細かい部分は説明しません。
わからないことがあれば再度質問してください。
> タイトルにもあるとおり、あるソフトでパソコンが再生している音楽を
> 録音しなければならなくなったのですが、どうやればいいか分かりません。
ご存知かもしれませんが初期設定のパソコンではパソコンが再生する音を録音できません。タスクバー右下のスピーカをダブルクリックして
ボリュームコントロールを起動して表示を録音にした後、WAVE出力ミックスの項を選択する必要があります。
これをプログラムの方から操作する方法はないことは無いので、
知りたい場合は、別に質問してださい。
あと、質問自体にファイルまでの書き出しが含まれているのでしたら
そのこともまた後で質問していただければ対応します。
> ようにしたいです。教えてください。お願いします。
[ここをクリックすると内容が表示されます]
5秒間録音でき、再生もできるサンプルです。コード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
Const MM_WOM_OPEN = &H3BB
Const MM_WOM_CLOSE = &H3BC
Const MM_WOM_DONE = &H3BD
Const MM_WIM_OPEN = &H3BE
Const MM_WIM_CLOSE = &H3BF
Const MM_WIM_DATA = &H3C0
Const CALLBACK_WINDOW = &H00010000
TypeDef HWAVEIN = DWord
TypeDef HWAVEOUT = DWord
Const WAVE_MAPPER = -1
Const WAVE_FORMAT_PCM = 1
Type WAVEHDR
lpData As *Byte
dwBufferLength As DWord
dwBytesRecorded As DWord
dwUser As DWord
dwFlags As DWord
dwLoops As DWord
lpNext As VoidPtr
reserved As DWord
End Type
Type WAVEFORMATEX
wFormatTag As Word
nChannels As Word
nSamplesPerSec As DWord
nAvgBytesPerSec As DWord
nBlockAlign As Word
wBitsPerSample As Word
cbSize As Word
End Type
Declare Function waveOutOpen Lib "WINMM" (ByRef phwo As HWAVEOUT, uDeviceID As DWord, ByRef pwfx As WAVEFORMATEX, dwCallback As DWord, dwInstance As DWord, fdwOpen As DWord) As DWord
Declare Function waveOutClose Lib "WINMM" (hwo As HWAVEOUT) As DWord
Declare Function waveOutPrepareHeader Lib "WINMM" (hwo As HWAVEOUT, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveOutUnprepareHeader Lib "WINMM" (hwo As HWAVEOUT, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveOutWrite Lib "WINMM" (hwo As HWAVEOUT, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveInOpen Lib "WINMM" (ByRef phwi As HWAVEIN, uDeviceID As DWord, ByRef pwfx As WAVEFORMATEX, dwCallback As DWord, dwInstance As DWord, fdwOpen As DWord) As DWord
Declare Function waveInClose Lib "WINMM" (hwi As HWAVEIN) As DWord
Declare Function waveInPrepareHeader Lib "WINMM" (hwi As HWAVEIN, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveInUnprepareHeader Lib "WINMM" (hwi As HWAVEIN, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveInAddBuffer Lib "WINMM" (hwi As HWAVEIN, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveInStart Lib "WINMM" (hwi As HWAVEIN) As DWord
Declare Function waveInStop Lib "WINMM" (hwi As HWAVEIN) As DWord
'=================================================================================================================
Const SamplingRate = 44100 'サンプリング周波数 44100[Hz]の整数除算値が一般的
Const BitsRate = 16 '量子化ビット数 8 16のどちらか
Const NumOfChanels = 2 'チャンネル数 1 モノラル 2 ステレオ
Const BufferTime = 5 'バッファ時間 このサンプルでは5[sec]
Dim hWaveIn As HWAVEIN
Dim hWaveOut As HWAVEOUT
Dim WaveHdr As WAVEHDR
Dim WaveFormatEx As WAVEFORMATEX
Dim WaveData As *Byte
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
Select Case dwMsg
Case MM_WOM_OPEN
waveOutPrepareHeader(hWaveOut,WaveHdr,SizeOf(WAVEHDR))
waveOutWrite(hWaveOut,WaveHdr,SizeOf(WAVEHDR))
EnableWindow(GetDlgItem(hMainWnd,CommandButton1),FALSE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton2),FALSE)
Case MM_WOM_CLOSE
waveOutUnprepareHeader(hWaveOut,WaveHdr,SizeOf(WAVEHDR))
EnableWindow(GetDlgItem(hMainWnd,CommandButton1),TRUE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton2),TRUE)
Case MM_WOM_DONE
waveOutClose(hWaveOut)
Case MM_WIM_OPEN
waveInPrepareHeader(hWaveIn,WaveHdr,SizeOf(WAVEHDR))
waveInAddBuffer(hWaveIn,WaveHdr,SizeOf(WAVEHDR))
waveInStart(hWaveIn)
EnableWindow(GetDlgItem(hMainWnd,CommandButton1),FALSE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton2),FALSE)
Case MM_WIM_CLOSE
waveInUnprepareHeader(hWaveIn,WaveHdr,SizeOf(WAVEHDR))
EnableWindow(GetDlgItem(hMainWnd,CommandButton1),TRUE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton2),TRUE)
Case MM_WIM_DATA
waveInStop(hWaveIn)
waveInClose(hWaveIn)
End Select
' イベントプロシージャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
Sub MainWnd_Destroy()
free(WaveData) 'バッファの破棄
wave_DestroyObjects()
PostQuitMessage(0)
End Sub
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
With WaveFormatEx
.cbSize = SizeOf(WAVEFORMATEX)
.nSamplesPerSec = SamplingRate
.wBitsPerSample = BitsRate
.nChannels = NumOfChanels
.nAvgBytesPerSec = .nSamplesPerSec*.wBitsPerSample*.nChannels/8
.nBlockAlign = .wBitsPerSample*.nChannels/8
.wFormatTag = WAVE_FORMAT_PCM
End With
WaveData = malloc(SamplingRate*NumOfChanels*BitsRate/8*5) 'バッファを作成
With WaveHdr
.lpData = WaveData
.dwBufferLength = SamplingRate*NumOfChanels*BitsRate/8*5
End With
End Sub
Sub MainWnd_CommandButton1_Click()
waveInOpen(hWaveIn,WAVE_MAPPER,WaveFormatEx,hMainWnd,0,CALLBACK_WINDOW)
End Sub
Sub MainWnd_CommandButton2_Click()
waveOutOpen(hWaveOut,WAVE_MAPPER,WaveFormatEx,hMainWnd,0,CALLBACK_WINDOW)
End Sub
コマンドボタン1が録音でコマンドボタン2が再生になっています。
説明するのは大変なので細かい部分は説明しません。
わからないことがあれば再度質問してください。
> タイトルにもあるとおり、あるソフトでパソコンが再生している音楽を
> 録音しなければならなくなったのですが、どうやればいいか分かりません。
ご存知かもしれませんが初期設定のパソコンではパソコンが再生する音を録音できません。タスクバー右下のスピーカをダブルクリックして
ボリュームコントロールを起動して表示を録音にした後、WAVE出力ミックスの項を選択する必要があります。
これをプログラムの方から操作する方法はないことは無いので、
知りたい場合は、別に質問してださい。
あと、質問自体にファイルまでの書き出しが含まれているのでしたら
そのこともまた後で質問していただければ対応します。
最後に編集したユーザー NoWest [ 2005年12月09日(金) 13:18 ], 累計 1 回
僕のプログラム作成にも役立ちます^^
NoWestさん、僕にも役立ちました。
わからなかったのが、WAVEFORMATEX(後、WAVE_FORMAT_PCM)だったのでOggVorbis再生に一歩近づきました。ありがとうございます
わからなかったのが、WAVEFORMATEX(後、WAVE_FORMAT_PCM)だったのでOggVorbis再生に一歩近づきました。ありがとうございます
Re: 返信@yu0627
> NoWestさんありがとうございます。
> こういうものを作れるなんて脱帽です。
>
> 僕が考えているのはMicrosoft サウンド マッパーを使って録音し、
> それをWavファイルに書き出すということにしたいと思います。
> しかし録音だけにかなりのAPI、構造体、定数が必要なんですね^^;
mciSendString関数を使えばもっと使用する定数や構造体を減らせます。
何といてもmciSendStringで使用するのは文字列だけなので、、、
waveaudioデバイスをオープンした後
saveコマンドを送信すれば録音でき
saveコマンドを送信すればファイルに保存できます。
ただ、任意のタイミングで録音を開始したりするのが苦手なので
簡単ですが本格的なWave操作に向きません。
> こういうものを作れるなんて脱帽です。
>
> 僕が考えているのはMicrosoft サウンド マッパーを使って録音し、
> それをWavファイルに書き出すということにしたいと思います。
> しかし録音だけにかなりのAPI、構造体、定数が必要なんですね^^;
mciSendString関数を使えばもっと使用する定数や構造体を減らせます。
何といてもmciSendStringで使用するのは文字列だけなので、、、
waveaudioデバイスをオープンした後
saveコマンドを送信すれば録音でき
saveコマンドを送信すればファイルに保存できます。
ただ、任意のタイミングで録音を開始したりするのが苦手なので
簡単ですが本格的なWave操作に向きません。
返信@yu0627
> mciSendString関数を使えばもっと使用する定数や構造体を減らせます。
> 何といてもmciSendStringで使用するのは文字列だけなので、、、
> waveaudioデバイスをオープンした後
> saveコマンドを送信すれば録音でき
> saveコマンドを送信すればファイルに保存できます。
> ただ、任意のタイミングで録音を開始したりするのが苦手なので
> 簡単ですが本格的なWave操作に向きません。
僕が考えているのはステレオorモノラルやビットレートが選べタイミングが
しっかり合わないとおかしくなるプログラムを考えています。
ですので、本格的な操作が必要だと思います。
その方法を教えてくれませんか。
> 何といてもmciSendStringで使用するのは文字列だけなので、、、
> waveaudioデバイスをオープンした後
> saveコマンドを送信すれば録音でき
> saveコマンドを送信すればファイルに保存できます。
> ただ、任意のタイミングで録音を開始したりするのが苦手なので
> 簡単ですが本格的なWave操作に向きません。
僕が考えているのはステレオorモノラルやビットレートが選べタイミングが
しっかり合わないとおかしくなるプログラムを考えています。
ですので、本格的な操作が必要だと思います。
その方法を教えてくれませんか。
Re: 返信@yu0627
>
> 僕が考えているのはステレオorモノラルやビットレートが選べタイミングが
> しっかり合わないとおかしくなるプログラムを考えています。
> ですので、本格的な操作が必要だと思います。
> その方法を教えてくれませんか。
・どの程度のアプリケーションが作りたいのか具体的に分からないので
お教えしようがないです。
そりゃぁ何となくイメージで作ろうと思えば作れますが、
私が作っても仕方ないですし
具体的にどの辺りが分からないのか書いていただかないと、、、
例えば
「5秒以上録音したいときは?」とか
「録音の音質を途中で変えるには?」とか、
・ひとまず、私の掲載したサンプルがどういった動作をしているのか
よく理解してください。
ここから入らないと録音したデータを保存したりできませんし、
マルチバッファリングの説明も難しいので。。。
P.S.
WAVE操作(処理・制御)は
D-A変換、A-D変換、振動といった知識が必要になるので
ある程度、基礎知識がないと難しいです。
関連サイトとかをググってみてください。
> 僕が考えているのはステレオorモノラルやビットレートが選べタイミングが
> しっかり合わないとおかしくなるプログラムを考えています。
> ですので、本格的な操作が必要だと思います。
> その方法を教えてくれませんか。
・どの程度のアプリケーションが作りたいのか具体的に分からないので
お教えしようがないです。
そりゃぁ何となくイメージで作ろうと思えば作れますが、
私が作っても仕方ないですし
具体的にどの辺りが分からないのか書いていただかないと、、、
例えば
「5秒以上録音したいときは?」とか
「録音の音質を途中で変えるには?」とか、
・ひとまず、私の掲載したサンプルがどういった動作をしているのか
よく理解してください。
ここから入らないと録音したデータを保存したりできませんし、
マルチバッファリングの説明も難しいので。。。
P.S.
WAVE操作(処理・制御)は
D-A変換、A-D変換、振動といった知識が必要になるので
ある程度、基礎知識がないと難しいです。
関連サイトとかをググってみてください。
Re: 返信@yu0627
> ・どの程度のアプリケーションが作りたいのか具体的に分からないので
> お教えしようがないです。
> 具体的にどの辺りが分からないのか書いていただかないと、、、
ある音楽ファイルをwavに変換するソフトを考えています。
その音楽ファイルの再生部分はどうやればいいのか分かります。
ただ、それを録音するのがどうやればいいのか分からなかったからです。
> ・ひとまず、私の掲載したサンプルがどういった動作をしているのか
> よく理解してください。
> ここから入らないと録音したデータを保存したりできませんし、
> マルチバッファリングの説明も難しいので。。。
一部分かります。MainWndProcをいじるのは連続的にしないといけない処理だからでしょうか。
WavのマルチバッファリングはWavのバッファを複数持つということでしょうか。
> P.S.
> WAVE操作(処理・制御)は
> D-A変換、A-D変換、振動といった知識が必要になるので
> ある程度、基礎知識がないと難しいです。
> 関連サイトとかをググってみてください。
D-A変換はデジタル→アナログ変換、
A-D変換はアナログ→デジタル変換のことですよね!?
振動は音を出すために振動する時の「Hz」とかのことですか?
> お教えしようがないです。
> 具体的にどの辺りが分からないのか書いていただかないと、、、
ある音楽ファイルをwavに変換するソフトを考えています。
その音楽ファイルの再生部分はどうやればいいのか分かります。
ただ、それを録音するのがどうやればいいのか分からなかったからです。
> ・ひとまず、私の掲載したサンプルがどういった動作をしているのか
> よく理解してください。
> ここから入らないと録音したデータを保存したりできませんし、
> マルチバッファリングの説明も難しいので。。。
一部分かります。MainWndProcをいじるのは連続的にしないといけない処理だからでしょうか。
WavのマルチバッファリングはWavのバッファを複数持つということでしょうか。
> P.S.
> WAVE操作(処理・制御)は
> D-A変換、A-D変換、振動といった知識が必要になるので
> ある程度、基礎知識がないと難しいです。
> 関連サイトとかをググってみてください。
D-A変換はデジタル→アナログ変換、
A-D変換はアナログ→デジタル変換のことですよね!?
振動は音を出すために振動する時の「Hz」とかのことですか?
Re: 返信@yu0627
なるほど、ある音楽ファイルというのは(こちらから詮索はしませんが)> ある音楽ファイルをwavに変換するソフトを考えています。
> その音楽ファイルの再生部分はどうやればいいのか分かります。
> ただ、それを録音するのがどうやればいいのか分からなかったからです。
何なのか分かりませんが
例えばmp3とかであれば変換アルゴリズムがありますのでそれを使えば
簡単に変換できますよ。著作の問題が付きまといますが。。。
と、まぁそんなことは置いといて
そうではないとして話を進めます。
例えば音楽CDとかの場合(そうだろ!、と決め付けてはいません)、
データ形式は16bit、44100HzのPCMである.cdaなどとなります。
これを直接CDイメージから読み取ってWaveに変換するとなると
やはりかなり高等な技術が必要となり正直アマチュアやビギナーでは
手が届きません。
ですのでパソコンが出している音をそのまま内部で録音すればよい
ということですよね。(やっぱり音質は劣化しますが・・・)
となると、やっぱりミキサー関連にも触れないといけないみたいですね。
昔作ったサンプルとか引っ張り出してきますので
少々お持ちくださいね。
折角、ご質問いただいたのですから、最後までお付き合いさせていただきます。
そういうことです。> 一部分かります。MainWndProcをいじるのは連続的にしないといけない処理だからでしょうか。
> WavのマルチバッファリングはWavのバッファを複数持つということでしょうか。
録音や再生というのは勿論、再生から停止までバッファの長さ
きっかりになるのですが、実際の動作というのは再生開始時間から
終了時間までは多少ロスが入ったりと正確ではありませんし
録音では任意の長さで録音ができないと意味がありませんよね。
最初にのっけたサンプルでは最初からデータの長さは5秒と
決めていたので簡単なのですが、不定長のものを録音するとなると
やはりマルチバッファリングが必要となります。
マルチバッファリングというのは複数の小さいバッファを
順番に録音に使用して、1つのバッファが録音中である間に
他のバッファがファイルへの書き出しをおこなうというものです。
そういえばファイルへの書き出しもしないといけませんね。
こちらも少々お待ちください。
ついでにMCIでのやり方もご紹介しておきましょう。
もしかしたら、これで十分ということもあるかもしれませんし、
http://homepage1.nifty.com/MADIA/delphi ... I_Wave.htm
http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/mci/
返信@yu0627
> なるほど、ある音楽ファイルというのは(こちらから詮索はしませんが)
> 何なのか分かりませんが
> 例えばmp3とかであれば変換アルゴリズムがありますのでそれを使えば
> 簡単に変換できますよ。著作の問題が付きまといますが。。。
いえ。変換もとの音楽ファイルがwavのように音自体を変換するものじゃなくて音階を記録する形式なので普通には変換できませんので。
> ですのでパソコンが出している音をそのまま内部で録音すればよい
> ということですよね。(やっぱり音質は劣化しますが・・・)
内部でA-D、D-A変換だからノイズ拾っちゃうからですよね。
> となると、やっぱりミキサー関連にも触れないといけないみたいですね。
>
> 昔作ったサンプルとか引っ張り出してきますので
> 少々お持ちくださいね。
>
> 折角、ご質問いただいたのですから、最後までお付き合いさせていただきます。
ありがとうございます。
> ついでにMCIでのやり方もご紹介しておきましょう。
> もしかしたら、これで十分ということもあるかもしれませんし、
> http://homepage1.nifty.com/MADIA/delphi ... I_Wave.htm
> http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/mci/
見ました。Delphi(Object Pascal)でのソースですが大体分かります。
作ろうと思ったらmciSendStringがapi_mmsys.sbpに宣言がなくて自作関数の宣言も分からない...(⌒_⌒; タラタラ
あ、これは(mciSendString)は教えていただかなくて結構です。
> 何なのか分かりませんが
> 例えばmp3とかであれば変換アルゴリズムがありますのでそれを使えば
> 簡単に変換できますよ。著作の問題が付きまといますが。。。
いえ。変換もとの音楽ファイルがwavのように音自体を変換するものじゃなくて音階を記録する形式なので普通には変換できませんので。
> ですのでパソコンが出している音をそのまま内部で録音すればよい
> ということですよね。(やっぱり音質は劣化しますが・・・)
内部でA-D、D-A変換だからノイズ拾っちゃうからですよね。
> となると、やっぱりミキサー関連にも触れないといけないみたいですね。
>
> 昔作ったサンプルとか引っ張り出してきますので
> 少々お持ちくださいね。
>
> 折角、ご質問いただいたのですから、最後までお付き合いさせていただきます。
ありがとうございます。
> ついでにMCIでのやり方もご紹介しておきましょう。
> もしかしたら、これで十分ということもあるかもしれませんし、
> http://homepage1.nifty.com/MADIA/delphi ... I_Wave.htm
> http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/mci/
見ました。Delphi(Object Pascal)でのソースですが大体分かります。
作ろうと思ったらmciSendStringがapi_mmsys.sbpに宣言がなくて自作関数の宣言も分からない...(⌒_⌒; タラタラ
あ、これは(mciSendString)は教えていただかなくて結構です。
Re: 返信@yu0627
ということはMIDIとかを変換するんですね。いえ。変換もとの音楽ファイルがwavのように音自体を変換するものじゃなくて音階を記録する形式なので普通には変換できませんので。
そうはいっても最近のサウンドチップは圧縮なんかよりは音質はいいです。> > ですのでパソコンが出している音をそのまま内部で録音すればよい
> > ということですよね。(やっぱり音質は劣化しますが・・・)
> 内部でA-D、D-A変換だからノイズ拾っちゃうからですよね。
他の作業をしているとクリック音とか警告音とかがいつの間にかはいってたり
しますけど。。。
それはうちのサイトに来ていただければapi_mmsysPro4をダウンロードする> 作ろうと思ったらmciSendStringがapi_mmsys.sbpに宣言がなくて自作関数の宣言も分からない...(⌒_⌒; タラタラ
だけで解決です。
と、いうことでWAVE録音と再生のサンプル乗っけます。
録音と再生は可変長であると考えてマルチバッファリングを使っています。
かなりデカいですが引かないでくださいね。
[ここをクリックすると内容が表示されます]
コード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
Const MAXPNAMELEN = 32
Const MAXERRORLENGTH = 256
Const MAX_JOYSTICKOEMVXDNAME = 260
Const MMSYSERR_NOERROR = 0
Const MM_WOM_OPEN = &H3BB
Const MM_WOM_CLOSE = &H3BC
Const MM_WOM_DONE = &H3BD
Const MM_WIM_OPEN = &H3BE
Const MM_WIM_CLOSE = &H3BF
Const MM_WIM_DATA = &H3C0
Const CALLBACK_WINDOW = &H00010000
TypeDef HWAVEIN = DWord
TypeDef HWAVEOUT = DWord
Const WAVE_MAPPER = -1
Type WAVEINCAPS
wMid As Word
wPid As Word
vDriverVersion As DWord
szPname[ELM(MAXPNAMELEN)] As Byte
dwFormats As DWord
wChannels As Word
wReserved1 As Word
End Type
Const WAVE_INVALIDFORMAT = &H00000000
Const WAVE_FORMAT_1M08 = &H00000001
Const WAVE_FORMAT_1S08 = &H00000002
Const WAVE_FORMAT_1M16 = &H00000004
Const WAVE_FORMAT_1S16 = &H00000008
Const WAVE_FORMAT_2M08 = &H00000010
Const WAVE_FORMAT_2S08 = &H00000020
Const WAVE_FORMAT_2M16 = &H00000040
Const WAVE_FORMAT_2S16 = &H00000080
Const WAVE_FORMAT_4M08 = &H00000100
Const WAVE_FORMAT_4S08 = &H00000200
Const WAVE_FORMAT_4M16 = &H00000400
Const WAVE_FORMAT_4S16 = &H00000800
Const WAVE_FORMAT_PCM = 1
Type WAVEHDR
lpData As *Byte
dwBufferLength As DWord
dwBytesRecorded As DWord
dwUser As DWord
dwFlags As DWord
dwLoops As DWord
lpNext As VoidPtr
reserved As DWord
End Type
Type WAVEFORMAT
wFormatTag As Word
nChannels As Word
nSamplesPerSec As DWord
nAvgBytesPerSec As DWord
nBlockAlign As Word
End Type
Type PCMWAVEFORMAT
wf As WAVEFORMAT
wBitsPerSample As Word
End Type
Type WAVEFORMATEX
wFormatTag As Word
nChannels As Word
nSamplesPerSec As DWord
nAvgBytesPerSec As DWord
nBlockAlign As Word
wBitsPerSample As Word
cbSize As Word
End Type
Declare Function waveOutOpen Lib "WINMM" (ByRef phwo As HWAVEOUT, uDeviceID As DWord, ByRef pwfx As WAVEFORMATEX, dwCallback As DWord, dwInstance As DWord, fdwOpen As DWord) As DWord
Declare Function waveOutClose Lib "WINMM" (hwo As HWAVEOUT) As DWord
Declare Function waveOutPrepareHeader Lib "WINMM" (hwo As HWAVEOUT, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveOutUnprepareHeader Lib "WINMM" (hwo As HWAVEOUT, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveOutWrite Lib "WINMM" (hwo As HWAVEOUT, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveOutReset Lib "WINMM" (hwo As HWAVEOUT) As DWord
Declare Function waveInGetDevCaps Lib "WINMM" Alias "waveInGetDevCapsA" (uDeviceID As DWord, ByRef pwic As WAVEINCAPS, cbwic As DWord) As DWord
Declare Function waveInOpen Lib "WINMM" (ByRef phwi As HWAVEIN, uDeviceID As DWord, ByRef pwfx As WAVEFORMATEX, dwCallback As DWord, dwInstance As DWord, fdwOpen As DWord) As DWord
Declare Function waveInClose Lib "WINMM" (hwi As HWAVEIN) As DWord
Declare Function waveInPrepareHeader Lib "WINMM" (hwi As HWAVEIN, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveInUnprepareHeader Lib "WINMM" (hwi As HWAVEIN, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveInAddBuffer Lib "WINMM" (hwi As HWAVEIN, ByRef pwh As WAVEHDR, cbwh As DWord) As DWord
Declare Function waveInStart Lib "WINMM" (hwi As HWAVEIN) As DWord
Declare Function waveInReset Lib "WINMM" (hwi As HWAVEIN) As DWord
TypeDef HMMIO = DWord
Const MMIO_RWMODE = &H00000003
Const MMIO_SHAREMODE = &H00000070
Const MMIO_CREATE = &H00001000
Const MMIO_PARSE = &H00000100
Const MMIO_DELETE = &H00000200
Const MMIO_EXIST = &H00004000
Const MMIO_ALLOCBUF = &H00010000
Const MMIO_GETTEMP = &H00020000
Const MMIO_DIRTY = &H10000000
Const MMIO_READ = &H00000000
Const MMIO_WRITE = &H00000001
Const MMIO_READWRITE = &H00000002
Const MMIO_COMPAT = &H00000000
Const MMIO_EXCLUSIVE = &H00000010
Const MMIO_DENYWRITE = &H00000020
Const MMIO_DENYREAD = &H00000030
Const MMIO_DENYNONE = &H00000040
Const MMIO_FHOPEN = &H0010
Const MMIO_EMPTYBUF = &H0010
Const MMIO_TOUPPER = &H0010
Const MMIO_INSTALLPROC = &H00010000
Const MMIO_GLOBALPROC = &H10000000
Const MMIO_REMOVEPROC = &H00020000
Const MMIO_UNICODEPROC = &H01000000
Const MMIO_FINDPROC = &H00040000
Const MMIO_FINDCHUNK = &H0010
Const MMIO_FINDRIFF = &H0020
Const MMIO_FINDLIST = &H0040
Const MMIO_CREATERIFF = &H0020
Const MMIO_CREATELIST = &H0040
TypeDef HMMIO = DWord
TypeDef HTASK = DWord
Type MMIOINFO
dwFlags As DWord
fccIOProc As DWord
pIOProc As DWord
wErrorRet As DWord
htask As HTASK
cchBuffer As Long
pchBuffer As BytePtr
pchNext As BytePtr
pchEndRead As BytePtr
pchEndWrite As BytePtr
lBufOffset As Long
lDiskOffset As Long
adwInfo[ELM(3)] As DWord
dwReserved1 As DWord
dwReserved2 As DWord
hmmio As HMMIO
End Type
Type MMCKINFO
ckid As DWord
cksize As DWord
fccType As DWord
dwDataOffset As DWord
dwFlags As DWord
End Type
Declare Function mmioStringToFOURCC Lib "WINMM" Alias "mmioStringToFOURCCA" (sz As BytePtr, uFlags As DWord) As DWord
Declare Function mmioOpen Lib "WINMM" Alias "mmioOpenA" (pszFileName As BytePtr, ByRef pmmioinfo As MMIOINFO, fdwOpen As DWord) As HMMIO
Declare Function mmioClose Lib "WINMM" (hmmio As HMMIO, fuClose As DWord) As DWord
Declare Function mmioRead Lib "WINMM" (hmmio As HMMIO, pch As BytePtr, cch As Long) As Long
Declare Function mmioWrite Lib "WINMM" (hmmio As HMMIO, pch As BytePtr, cch As Long) As Long
Declare Function mmioDescend Lib "WINMM" (hmmio As HMMIO, ByRef pmmcki As MMCKINFO, ByRef pmmckiParent As MMCKINFO, fuDescend As DWord) As DWord
Declare Function mmioAscend Lib "WINMM" (hmmio As HMMIO, ByRef pmmcki As MMCKINFO, fuAscend As DWord) As DWord
Declare Function mmioCreateChunk Lib "WINMM" (hmmio As HMMIO, ByRef pmmcki As MMCKINFO, fuCreate As DWord) As DWord
'=================================================================================================================
Dim Play_Flag As DWord
Dim Record_Flag As DWord
Dim Stop_Flag As DWord
Const NumOfBuffers = 5 'バッファ数
Const BufferLength = 1*1024 'バッファ長
Dim hWaveIn As HWAVEIN
Dim hWaveOut As HWAVEOUT
Dim WaveHdr[ELM(NumOfBuffers)] As WAVEHDR
Dim WaveOutFormatEx As WAVEFORMATEX
Dim WaveInFormatEx As WAVEFORMATEX
Dim hMmio As HMMIO
Dim MmioInfo As MMIOINFO
Dim MmioCkInfo As MMCKINFO
Dim MmioCkInfoSub As MMCKINFO
Dim WaveData[ELM(NumOfBuffers)] As *Byte
/*************メニューID**************/
Const IDM_1M08 = 100
Const IDM_1S08 = 101
Const IDM_1M16 = 102
Const IDM_1S16 = 103
Const IDM_2M08 = 104
Const IDM_2S08 = 105
Const IDM_2M16 = 106
Const IDM_2S16 = 107
Const IDM_4M08 = 108
Const IDM_4S08 = 109
Const IDM_4M16 = 110
Const IDM_4S16 = 111
/*******WAVE入力デバイスの性能を取得する。********/
Dim WaveInCaps As WAVEINCAPS
waveInGetDevCaps(WAVE_MAPPER,WaveInCaps,SizeOf(WAVEINCAPS))
Dim hMenuSub1 As HMENU
hMenuSub1 = CreatePopupMenu()
If WaveInCaps.dwFormats And WAVE_FORMAT_4S16 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"44100Hz 16bit Stereo",IDM_4S16,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_4M16 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"44100Hz 16bit Mono",IDM_4M16,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_4S08 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"44100Hz 8bit Stereo",IDM_4S08,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_4M08 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"44100Hz 8bit Mono",IDM_4M08,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_2S16 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"22050Hz 16bit Stereo",IDM_2S16,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_2M16 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"22050Hz 16bit Mono",IDM_2M16,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_2S08 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"22050Hz 8bit Stereo",IDM_2S08,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_2M08 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"22050Hz 8bit Mono",IDM_2M08,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_1S16 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"11025Hz 16bit Stereo",IDM_1S16,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_1M16 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"11025Hz 16bit Mono",IDM_1M16,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_1S08 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"11025Hz 8bit Stereo",IDM_1S08,0,0
If WaveInCaps.dwFormats And WAVE_FORMAT_1M08 Then InsMenu hMenuSub1,0,MF_BYPOSITION,"11025Hz 8bit Mono",IDM_1M08,0,0
Dim hMenu As HMENU
hMenu = CreateMenu()
InsMenu hMenu,0,MF_BYPOSITION,"Quality(&Q)",0,hMenuSub1,0
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
Dim cnt As Long
Dim ret As Long
Dim pwh As *WAVEHDR
Select Case dwMsg
Case MM_WOM_OPEN /******WAVE出力デバイスが開かれた時に呼ばれる******/
/******dataチャンクにアクセス******/
MmioCkInfoSub.ckid = mmioStringToFOURCC("data",0)
mmioDescend(hMmio,MmioCkInfoSub,MmioCkInfo,MMIO_FINDCHUNK)
For cnt=0 To NumOfBuffers-1
ret = mmioRead(hMmio,WaveData[cnt],BufferLength)
If ret = 0 or ret = -1 Then
WaveHdr[cnt].dwBufferLength = 0
WaveHdr[cnt].dwUser = TRUE
Else
WaveHdr[cnt].dwBufferLength = ret
WaveHdr[cnt].dwUser = FALSE
End If
waveOutPrepareHeader(hWaveOut,WaveHdr[cnt],SizeOf(WAVEHDR))
Next
For cnt=0 To NumOfBuffers-1
waveOutWrite(hWaveOut,WaveHdr[cnt],SizeOf(WAVEHDR))
Next
EnableWindow(GetDlgItem(hMainWnd,CommandButton1),FALSE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton2),FALSE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton3),TRUE)
Case MM_WOM_CLOSE /******WAVE出力デバイスが閉じられる時に呼ばれる******/
For cnt=0 To NumOfBuffers-1
waveOutUnprepareHeader(hWaveOut,WaveHdr[cnt],SizeOf(WAVEHDR))
Next
EnableWindow(GetDlgItem(hMainWnd,CommandButton1),TRUE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton2),TRUE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton3),FALSE)
Play_Flag = FALSE
Case MM_WOM_DONE /******WAVE出力デバイスのバッファの再生終了時に呼ばれる******/
pwh=lParam
If pwh->dwUser = TRUE or Stop_Flag = TRUE Then
mmioAscend(hMmio,MmioCkInfoSub,0)
mmioClose(hMmio,0)
waveOutClose(hWaveOut)
Stop_Flag = FALSE
Else
/******dataデータを読み込み******/
FillMemory(pwh->lpData,BufferLength,127)
ret = mmioRead(hMmio,pwh->lpData,BufferLength)
If ret = 0 or ret = -1 Then
pwh->dwUser = TRUE
pwh->dwBufferLength = 0
Else
pwh->dwUser = FALSE
pwh->dwBufferLength = ret
End If
waveOutWrite(hWaveOut,ByVal pwh,SizeOf(WAVEHDR))
End If
Case MM_WIM_OPEN /******WAVE入力デバイスが開かれた時に呼ばれる******/
/******dataチャンクを作成******/
MmioCkInfoSub.ckid = mmioStringToFOURCC("data",0)
mmioCreateChunk(hMmio,MmioCkInfoSub,0)
For cnt=0 To NumOfBuffers-1
WaveHdr[cnt].dwUser = FALSE
WaveHdr[cnt].dwBufferLength = BufferLength
waveInPrepareHeader(hWaveIn,WaveHdr[cnt],SizeOf(WAVEHDR))
waveInAddBuffer(hWaveIn,WaveHdr[cnt],SizeOf(WAVEHDR))
Next
waveInStart(hWaveIn)
EnableWindow(GetDlgItem(hMainWnd,CommandButton1),FALSE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton2),FALSE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton3),TRUE)
Case MM_WIM_CLOSE /******WAVE入力デバイスが閉じられる時に呼ばれる******/
For cnt=0 To NumOfBuffers-1
waveInUnprepareHeader(hWaveIn,WaveHdr[cnt],SizeOf(WAVEHDR))
Next
EnableWindow(GetDlgItem(hMainWnd,CommandButton1),TRUE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton2),TRUE)
EnableWindow(GetDlgItem(hMainWnd,CommandButton3),FALSE)
Record_Flag = FALSE
Case MM_WIM_DATA /******WAVE入力デバイスのバッファが一杯になった時に呼ばれる******/
pwh=lParam
If Stop_Flag = TRUE Then
mmioWrite(hMmio,pwh->lpData,pwh->dwBytesRecorded)
mmioAscend(hMmio,MmioCkInfoSub,0)
mmioAscend(hMmio,MmioCkInfo,0)
mmioClose(hMmio,0)
waveInClose(hWaveIn)
Stop_Flag = FALSE
Else
/******dataデータを書き込み******/
mmioWrite(hMmio,pwh->lpData,pwh->dwBytesRecorded)
FillMemory(pwh->lpData,BufferLength,127)
waveInAddBuffer(hWaveIn,ByVal pwh,SizeOf(WAVEHDR))
End If
Case WM_COMMAND
Select Case LOWORD(wParam)
Case IDM_1M08
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_1M08,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 1
WaveInFormatEx.nSamplesPerSec = 11025
WaveInFormatEx.wBitsPerSample = 8
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_1S08
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_1S08,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 2
WaveInFormatEx.nSamplesPerSec = 11025
WaveInFormatEx.wBitsPerSample = 8
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_1M16
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_1M16,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 1
WaveInFormatEx.nSamplesPerSec = 11025
WaveInFormatEx.wBitsPerSample = 16
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_1S16
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_1S16,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 2
WaveInFormatEx.nSamplesPerSec = 11025
WaveInFormatEx.wBitsPerSample = 16
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_2M08
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_2M08,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 1
WaveInFormatEx.nSamplesPerSec = 22050
WaveInFormatEx.wBitsPerSample = 8
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_2S08
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_2S08,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 2
WaveInFormatEx.nSamplesPerSec = 22050
WaveInFormatEx.wBitsPerSample = 8
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_2M16
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_2M16,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 1
WaveInFormatEx.nSamplesPerSec = 22050
WaveInFormatEx.wBitsPerSample = 16
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_2S16
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_2S16,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 2
WaveInFormatEx.nSamplesPerSec = 22050
WaveInFormatEx.wBitsPerSample = 16
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_4M08
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_4M08,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 1
WaveInFormatEx.nSamplesPerSec = 44100
WaveInFormatEx.wBitsPerSample = 8
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_4S08
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_4S08,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 2
WaveInFormatEx.nSamplesPerSec = 44100
WaveInFormatEx.wBitsPerSample = 8
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_4M16
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_4M16,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 1
WaveInFormatEx.nSamplesPerSec = 44100
WaveInFormatEx.wBitsPerSample = 16
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
Case IDM_4S16
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_4S16,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 2
WaveInFormatEx.nSamplesPerSec = 44100
WaveInFormatEx.wBitsPerSample = 16
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign * WaveInFormatEx.nSamplesPerSec
End Select
End Select
' イベントプロシージャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
Sub MainWnd_Destroy()
Dim cnt As Long
If Record_Flag = TRUE Then
Stop_Flag = TRUE
waveInReset(hWaveIn)
ElseIf Play_Flag = TRUE Then
Stop_Flag = TRUE
waveOutReset(hWaveOut)
End If
Dim msg As MSG /*** 修正箇所 ***/
While 1
If PeekMessage(msg,0,0,0,PM_REMOVE) Then
TranslateMessage(msg)
DispatchMessage(msg)
If Play_Flag=FALSE Then Exit While
End If
Wend /*** ******** ***/
For cnt=0 To NumOfBuffers-1
free(WaveData[cnt])
Next
DestroyMenu(hMenu)
DestroyMenu(hMenuSub1)
wave_DestroyObjects()
PostQuitMessage(0)
End Sub
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
Dim cnt As Long
For cnt=0 To NumOfBuffers-1
WaveData[cnt] = malloc(BufferLength)
WaveHdr[cnt].lpData=WaveData[cnt]
FillMemory(WaveData[cnt],BufferLength,127)
Next
SetDlgItemText(hMainWnd,CommandButton1,"Record")
SetDlgItemText(hMainWnd,CommandButton2,"Play")
SetDlgItemText(hMainWnd,CommandButton3,"Stop")
SetMenu(hMainWnd,hMenu)
CheckMenuRadioItem(hMenu,IDM_1M08,IDM_4S16,IDM_1M08,MF_BYCOMMAND)
WaveInFormatEx.cbSize = SizeOf(WAVEFORMATEX)
WaveInFormatEx.wFormatTag = WAVE_FORMAT_PCM
WaveInFormatEx.nChannels = 1
WaveInFormatEx.nSamplesPerSec = 11025
WaveInFormatEx.wBitsPerSample = 8
WaveInFormatEx.nBlockAlign = WaveInFormatEx.nChannels*WaveInFormatEx.wBitsPerSample/8
WaveInFormatEx.nAvgBytesPerSec = WaveInFormatEx.nBlockAlign*WaveInFormatEx.nSamplesPerSec
End Sub
Sub MainWnd_CommandButton1_Click()
/******WAVEファイルを作成******/
hMmio = mmioOpen("temp.wav",ByVal 0,MMIO_CREATE or MMIO_WRITE or MMIO_EXCLUSIVE)
/******WAVEチャンクを作成******/
MmioCkInfo.fccType = mmioStringToFOURCC("WAVE",0)
mmioCreateChunk(hMmio,MmioCkInfo,MMIO_CREATERIFF)
/******fmt チャンクを作成******/
MmioCkInfoSub.ckid = mmioStringToFOURCC("fmt ",0)
mmioCreateChunk(hMmio,MmioCkInfoSub,0)
/******fmt データを書き込み******/
mmioWrite(hMmio,VarPtr(WaveInFormatEx),SizeOf(PCMWAVEFORMAT))
mmioAscend(hMmio,MmioCkInfoSub,0)
/******WAVE入力デバイスを開く******/
waveInOpen(hWaveIn,WAVE_MAPPER,WaveInFormatEx,hMainWnd,0,CALLBACK_WINDOW)
Record_Flag = TRUE
End Sub
Sub MainWnd_CommandButton2_Click()
/******WAVEファイルを開く******/
hMmio = mmioOpen("temp.wav",MmioInfo,MMIO_READ)
/******WAVEチャンクにアクセス******/
MmioCkInfo.fccType = mmioStringToFOURCC("WAVE",0)
mmioDescend(hMmio,MmioCkInfo,ByVal 0,MMIO_FINDRIFF)
/******fmt データを読み込み******/
MmioCkInfoSub.ckid = mmioStringToFOURCC("fmt ",0)
mmioDescend(hMmio,MmioCkInfoSub,MmioCkInfo,MMIO_FINDCHUNK)
mmioRead(hMmio,VarPtr(WaveOutFormatEx),MmioCkInfoSub.cksize)
mmioAscend(hMmio,MmioCkInfoSub,0)
/******WAVE出力デバイスを開く******/
waveOutOpen(hWaveOut,WAVE_MAPPER,WaveOutFormatEx,hMainWnd,0,CALLBACK_WINDOW)
Play_Flag = TRUE
End Sub
Sub MainWnd_CommandButton3_Click()
Stop_Flag = TRUE
waveInReset(hWaveIn)
waveOutReset(hWaveOut)
Play_Flag = FALSE
Record_Flag = FALSE
End Sub
サンプルはコマンドボタン3つのRAD上で動くようにしてあります。
また、例によって分からないことがあれば質問してください。
mixer関連は必要があればということで今回はご勘弁を、、、
最後に編集したユーザー NoWest [ 2005年12月09日(金) 13:22 ], 累計 2 回
Re: 返信@yu0627
>
>
> 教えてくださりありがとうございます。しかし、録音しようとすると
> 強制終了してしまうのでデバッグすると「WaveHdr[49].dwUser = TRUE」の部分でアクセス違反が起きています。
> 長すぎて解析できないので確認してみてください。
そいつはデバッグしたときのゴミですので削除してください。
> ギクッ...。ということはMIDIとかを変換するんですね。
>
> 教えてくださりありがとうございます。しかし、録音しようとすると
> 強制終了してしまうのでデバッグすると「WaveHdr[49].dwUser = TRUE」の部分でアクセス違反が起きています。
> 長すぎて解析できないので確認してみてください。
そいつはデバッグしたときのゴミですので削除してください。
Re: 返信@yu0627
> 教えてくださりありがとうございます。動作確認できました。
> これからは色々と自分で試行錯誤してみます。もし乗り越えれない壁に当たったらまた返信するかもしれません。
> ちなみに僕の環境で44100KHz 16bit Stereoで録音するとやばくなります。再生速度が遅いというか...。
たぶんバッファサイズを大きくとれば改善するでしょう。
このサンプルでは1*1024bitいわゆる1Kbyteですが
6K~8K位に増やせばCPUの遅いパソコンでも大丈夫だと思います。
> これからは色々と自分で試行錯誤してみます。もし乗り越えれない壁に当たったらまた返信するかもしれません。
> ちなみに僕の環境で44100KHz 16bit Stereoで録音するとやばくなります。再生速度が遅いというか...。
たぶんバッファサイズを大きくとれば改善するでしょう。
このサンプルでは1*1024bitいわゆる1Kbyteですが
6K~8K位に増やせばCPUの遅いパソコンでも大丈夫だと思います。