HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
0817
みゃあマイク入力を再生する6解決


みゃあ

リンク

2021/8/17(Tue) 15:10:09|NO.93607

マイク入力を再生し、必要に応じて停止して他のサウンド(mp3)を再生するプログラムを作りたいと思っています。

マイク入力を録音する方法は見つかったのですが、マイク入力をそのまま遅延なく再生する方法がわかりません。

ご存じの方おられましたら、よろしくお願いいたします。



この記事に返信する


まる

リンク

2021/8/18(Wed) 17:59:52|NO.93613

プログラムの具体的な流れを伝えたいのは何となく分かりますが、具体的に何をすることを目的としたプログラムなのかよく分からなかったので説明していただけると回答しやすいです。
マイクから録音した音声を再生した後の、必要に応じて再生する音源とはどのようなもので、再生することが必要とされる条件は何でしょうか



みゃあ

リンク

2021/8/18(Wed) 18:49:02|NO.93615

>>93613
作ろうと思っているのは、放送用のプログラムです。
ボタン操作によって、マイク入力の再生とMP3音源の再生を切り替える(同時に再生しない)ものを考えています。



usagi

リンク

2021/8/19(Thu) 05:29:18|NO.93622

こんにちわ

>マイク入力を録音する方法は見つかったのですが、マイク入力をそのまま遅延なく再生する方法がわかりません。
マイク入力が出来たのであれば、出力も同じような感じでできます。(winmmを使われている想定でInをOutにすればよい)

遅延に関してはどこまでを許容とするかにもよりますが(パソコン通す以上絶対遅延するので)
小さめのバッファサイズで再生すると遅延が少なくなりますが、処理が重いと音飛びしてしまいます。

一例ですがどおぞ(命令すくないので、必要あれば増やしてみてください)


#ifndef __WaveInOut__ #define __WaveInOut__ #module WaveInOut #include "winmm.as" // 定数 #define WAVE_MAPPER 0xFFFFFFFF // WAVE_MAPPER #define WAVE_FORMAT_PCM 0x00000001 // PCM #define CALLBACK_WINDOW 0x00010000 // コールバック #define MM_WIM_DATA 0x000003C0 // コールバックメッセージ #define WHDR_DONE 0x00000001 // 再生完了 #define BUFFER_NUM 3 // マルチバッファリングする state = 0 #deffunc openWaveInOut array pbuff, int nSamplesPerSec if state == 1 : return state = 1 dup dbuff,pbuff // 入力 --------------------------------------------------------- wBytesPerSample = 2 // 16bit // WAVEFORMATEX 構造体 wFormatTag = WAVE_FORMAT_PCM // フォーマット nChannels = 1 // チャンネル // nSamplesPerSec = 48000 // サンプルレート (引数で指定) wBitsPerSample = wBytesPerSample * 8 // 量子化バイト数 nBlockAlign = nChannels * wBytesPerSample // ブロックアライメント nAvgBytesPerSec = nSamplesPerSec * nBlockAlign // 平均ビットレート cbSize = 0 // 追加フォーマット wfx = wFormatTag | (nChannels << 16), nSamplesPerSec, nAvgBytesPerSec, nBlockAlign | (wBitsPerSample << 16), cbSize // オープン : waveInOpen 関数 hwi = 0 // Device識別ハンドル uDeviceID = WAVE_MAPPER // Device識別子 //pwfx // WAVEFORMATEX 構造体 dwCallBack = hwnd // Callback Message対象 /*ウインドウハンドル*/ oncmd gosub *ON_MM_WIM_DATA, MM_WIM_DATA dwCallbackInstance = 0 // Callbackへ渡すデータ /*なし*/ fdwOpen = CALLBACK_WINDOW // Deviceフラグ $00010000/*CALLBACK_WINDOW*/ waveInOpen varptr(hwi), uDeviceID, varptr(wfx), dwCallBack, dwCallbackInstance, fdwOpen if stat { dialog "ERROR: waveInOpne("+stat+")" : end } // バッファ作成 bufferLength = length(dbuff) * wBytesPerSample sdim inbuff, bufferLength, BUFFER_NUM //WAVEHDR構造体 (一部) dim in_wh, 8, BUFFER_NUM // 32byte用意 cbwh = 32 // WAVWHDR 構造体のサイズ (32) repeat BUFFER_NUM in_wh(0,cnt) = varptr(inbuff.cnt) // lpData ウェーブフォームバッファへのポインタ in_wh(1,cnt) = varsize(inbuff.cnt) // dwBufferLength バッファのサイズ(バイト) waveInPrepareHeader hwi, varptr(in_wh(0,cnt)), cbwh // 入力バッファ準備 waveInAddBuffer hwi, varptr(in_wh(0,cnt)), cbwh // デバイスにバッファーの追加 loop // 出力 --------------------------------------------------------- hwo = 0 waveOutOpen varptr(hwo), uDeviceID, varptr(wfx), dwCallBack, dwCallbackInstance, fdwOpen if stat { dialog "ERROR: waveOutOpne("+stat+")" : end } // バッファ作成 sdim outbuff, bufferLength, BUFFER_NUM dim out_wh, 8, BUFFER_NUM repeat BUFFER_NUM out_wh(0,cnt) = varptr(outbuff.cnt) out_wh(1,cnt) = varsize(outbuff.cnt) waveOutPrepareHeader hwo, varptr(out_wh(0,cnt)), cbwh waveOutWrite hwo, varptr(out_wh.0.cnt), cbwh loop // 入力のスタート waveInStart hwi if stat { dialog "ERROR: waveInStart("+stat+")" : end } return #deffunc closeWaveInOut if state == 0 : return state = 0 _exit return #deffunc local _exit onexit waveInReset hwi waveOutReset hwo repeat BUFFER_NUM waveInUnprepareHeader hwi, varptr(in_wh), cbwh waveOutUnprepareHeader hwo, varptr(out_pwh), cbwh loop waveInClose hwi waveOutClose hwo return *ON_MM_WIM_DATA // wparam: 入力終了した デバイスのハンドル // lparam: 入力終了した WAVEHDR構造体のポインタ dupptr pwh, lparam, 32 dupptr pbuff, pwh.0, bufferLength, 2 // 入力を表示用バッファにコピー repeat length(dbuff) t = wpeek(pbuff, cnt*2) if t & 0x8000 : t |= 0xffff0000 dbuff.cnt = double(t)/32768.0 loop // 出力書き込み repeat BUFFER_NUM if out_wh.4.cnt & WHDR_DONE { memcpy outbuff.cnt, pbuff, bufferLength waveOutWrite hwo, varptr(out_wh.0.cnt), cbwh break } loop // 終了した入力を追加 waveInAddBuffer wparam, lparam, cbwh return #global #endif // サンプル screen 0, 512, 400 ddim buff, 1024 button gosub "オープン", *MIC_OPEN button gosub "クローズ", *MIC_CLOSE while redraw 0 color : boxf color 255,255,255 : pos 0,200 repeat length(buff) line cnt, -buff.cnt*200.0+200 loop redraw 1 await 32 wend *MIC_OPEN openWaveInOut buff, 32000 return *MIC_CLOSE closeWaveInOut return



usagi

リンク

2021/8/19(Thu) 05:32:15|NO.93623

あっ、イヤホン挿すかWindowsのオーディオの既定のサウンドデバイスを
マイクと干渉しないうように変更しないと物的にハウリングしますので気を付けてください。



みゃあ

リンク

2021/8/23(Mon) 17:24:13|NO.93662

>>93622
私ができたのはmciでちょちょっとするだけだったので、winmmは難しいですね。数日間ソースコードとにらめっこしてるのですが、なかなか理解できそうにありません。でも少しづつ調べて、頑張って理解してみようと思います。

ありがとうございました。



usagi

リンク

2021/8/23(Mon) 19:30:43|NO.93667

なるほどmciなのですね。
マイク入力を直接出力に流し込んだり、遅延の無い再生となるとどうてしてもmciのような抽象化された高レベルの命令ではなくて、
winmmの用なパソコンの中身にもっと近い低レベルな命令を使う必要が出てきてしまいますね。
(オーディオの知識が必要になってしまうので難しいかも)
簡単なライブラリを作ってる人もいるかもしれませんので、私のはHSPの標準機能を使う一例ということで。。。

■余談
Windos10であればマイクの設定を[このデバイスを聴く]にすると信号がスルーされますので、
mciで音量だけコントロールしてみるのもありかもですね。
ツールと言うよりwindowsのデバイス設定と組み合わせた使い方って感じかもしれませんが



ONION software Copyright 1997-2023(c) All rights reserved.