C/C++で音声出力
最近C#を使って音声処理系のアプリケーションが書けるようになったが、 実はwindowsの音声出力が良く分からない
そこらへんは便利なラッパーライブラリを使って見ないフリをしていた
改めてC/C++でwin32apiから勉強してみる
参考ページ
C言語/C++ - Sample is best! - アットウィキ
C言語/C++/wave - Sample is best! - アットウィキ
C++によるオーディオ信号処理(1) ---環境構築とサンプルプログラム動作確認--- : 工作と競馬
#pragma comment(lib, "winmm.lib") #define _USE_MATH_DEFINES #include <math.h> #include <stdio.h> #include <Windows.h> #include <locale.h> // LC_CTYPE #include <stdio.h> #include <stdlib.h> #include <tchar.h> #define VOLUME 64 #define FREQ 440 #define SAMPLE_RATE 11025 #define TONE_MSEC 1000 #define DATA_LEN (SAMPLE_RATE * TONE_MSEC / 1000) int main() { WAVEFORMATEX waveformatx; MMRESULT mmresult; HWAVEOUT handle_wave_out; WAVEHDR wave_header; char acData[DATA_LEN]; // MAX 256 (8bit = 1Byte) double dWave; int i; // 波形データの生成 Generate Waveform for (i = 0; i < DATA_LEN; i++) { dWave = sin(i * FREQ * 2 * M_PI / SAMPLE_RATE); acData[i] = (char)(dWave * VOLUME) + 128; //acData[i] = rand() * 2 * VOLUME / RAND_MAX + 128 - VOLUME; // ホワイトノイズ } // Play waveformatx.wFormatTag = WAVE_FORMAT_PCM; waveformatx.nChannels = 1; waveformatx.nSamplesPerSec = SAMPLE_RATE; waveformatx.nAvgBytesPerSec = SAMPLE_RATE; waveformatx.nBlockAlign = 1; waveformatx.wBitsPerSample = 8; // 8bit waveformatx.cbSize = 0; const UINT device_nomber = waveOutGetNumDevs(); printf("Device no : %d\n", device_nomber); // USER Inputs printf("Please Input Device ID\n"); UINT deviceid = 0; scanf_s("%d", &deviceid); printf("%d\n", deviceid); // Check Device Open mmresult = waveOutOpen(&handle_wave_out, deviceid, &waveformatx, 0, 0, CALLBACK_NULL); if (mmresult != MMSYSERR_NOERROR) { printf("error: waveOutOpen\n"); switch (mmresult) { case MMSYSERR_ALLOCATED: printf("error: MMSYSERR_ALLOCATED\n"); break; case MMSYSERR_BADDEVICEID: printf("error: MMSYSERR_BADDEVICEID\n"); break; case MMSYSERR_NODRIVER: printf("error: MMSYSERR_NODRIVER\n"); break; case MMSYSERR_NOMEM: printf("error: MMSYSERR_NOMEM\n"); break; case WAVERR_BADFORMAT: printf("error: WAVERR_BADFORMAT\n"); break; case WAVERR_SYNC: printf("error: WAVERR_SYNC\n"); break; default: break; } system("pause"); return 1; } // waveOutPrepareHeader ZeroMemory(&wave_header, sizeof wave_header); wave_header.lpData = acData; wave_header.dwBufferLength = DATA_LEN; mmresult = waveOutPrepareHeader(handle_wave_out, &wave_header, sizeof wave_header); if (mmresult != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutPrepareHeader\n"); switch (mmresult) { case MMSYSERR_INVALHANDLE: printf("error: MMSYSERR_INVALHANDLE\n"); break; case MMSYSERR_NODRIVER: printf("error: MMSYSERR_NODRIVER\n"); break; case MMSYSERR_NOMEM: printf("error: MMSYSERR_NOMEM\n"); break; default: break; } system("pause"); return 1; } // waveOutWrite mmresult = waveOutWrite(handle_wave_out, &wave_header, sizeof wave_header); if (mmresult != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutWrite\n"); switch (mmresult) { case MMSYSERR_INVALHANDLE: printf("error: MMSYSERR_INVALHANDLE\n"); break; case MMSYSERR_NODRIVER: printf("error: MMSYSERR_NODRIVER\n"); break; case MMSYSERR_NOMEM: printf("error: MMSYSERR_NOMEM\n"); break; default: break; } system("pause"); return 1; } // wait Sleep(TONE_MSEC); // Stop // waveOutReset mmresult = waveOutReset(handle_wave_out); if (mmresult != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutReset\n"); switch (mmresult) { case MMSYSERR_INVALHANDLE: printf("error: MMSYSERR_INVALHANDLE\n"); break; case MMSYSERR_NODRIVER: printf("error: MMSYSERR_NODRIVER\n"); break; case MMSYSERR_NOMEM: printf("error: MMSYSERR_NOMEM\n"); break; case MMSYSERR_NOTSUPPORTED: printf("error: MMSYSERR_NOTSUPPORTED\n"); break; default: break; } system("pause"); return 1; } // waveOutUnprepareHeader mmresult = waveOutUnprepareHeader(handle_wave_out, &wave_header, sizeof wave_header); if (mmresult != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutUnprepareHeader\n"); switch (mmresult) { case MMSYSERR_INVALHANDLE: printf("error: MMSYSERR_INVALHANDLE\n"); break; case MMSYSERR_NODRIVER: printf("error: MMSYSERR_NODRIVER\n"); break; case MMSYSERR_NOMEM: printf("error: MMSYSERR_NOMEM\n"); break; case MMSYSERR_NOTSUPPORTED: printf("error: MMSYSERR_NOTSUPPORTED\n"); break; default: break; } system("pause"); return 1; } // waveOutClose mmresult = waveOutClose(handle_wave_out); if (mmresult != MMSYSERR_NOERROR) { fprintf(stderr, "error: waveOutClose\n"); switch (mmresult) { case MMSYSERR_INVALHANDLE: printf("error: MMSYSERR_INVALHANDLE\n"); break; case MMSYSERR_NODRIVER: printf("error: MMSYSERR_NODRIVER\n"); break; case MMSYSERR_NOMEM: printf("error: MMSYSERR_NOMEM\n"); break; case WAVERR_STILLPLAYING: printf("error: WAVERR_STILLPLAYING\n"); break; default: break; } system("pause"); return 1; } system("pause"); return 0; }
いやーややこしい。
改訂新版 C/C++によるディジタル信号処理入門 (ディジタル信号処理シリーズ)
- 作者: 三上直樹
- 出版社/メーカー: CQ出版
- 発売日: 2009/02/01
- メディア: 単行本
- クリック: 9回
- この商品を含むブログ (1件) を見る
実践ディジタル・フィルタ設計入門―JavaアプレットとC++プログラムを使った (ディジタル信号処理シリーズ)
- 作者: 岩田利王
- 出版社/メーカー: CQ出版
- 発売日: 2004/10
- メディア: 単行本
- クリック: 6回
- この商品を含むブログ (3件) を見る
スピーカエンクロージャー製作 その1
スピーカを作る
スピーカエンクロージャを作る
とあるイベント用にスピーカ製作の依頼を受けました。
2wayのスピーカを4セット分を一つのオブジェクトにまとめる仕様ということで。
イベント自体は8/19とまだ一ヶ月あるのですが、スピーカ駆動用のアンプや、マイク入力+ボイスエフェクト等の回路もオーダーで受けているのでそれぞれの準備を一月前から始めようと思っています
## 依頼内容
+ スピーカ x 8発 (+ ネットワーク)
+ アンプ 各100W程度
+ マイクアンプ
+ 電源回路
せっかくですのでスピーカのエージングもかねてエンクロージャーを設計します.
目的は8発スピーカのエージングと、ネットワークの音質セッティング、木材加工の外注も初めてなので試しでもあります。
イメージは以下のようになりました。
4面全てに2Wayスピーカを配置します.
あまり何も考えずに箱を作るように、板をはめ合う場合は、板厚の分シンメトリーになりません。ただ、せっかくなので4面シンメトリーにしたかったので、顔面の両端に板厚と等しい太さの支柱を設けてシンメトリにしました。材質変えて色を変える予定です。
### スピーカユニット
コイズミ無線を除くとちょうど2Wayのセット販売をしていましたのでそれを採用します。
メインのユニットはできるだけ大きい方が男らしいのですが、製作物の都合もあり16cmとしておきます。まぁワンルームの中でみるとソコソコ存在感あります。
プラスツイータのセットで15千円程度でした。(ネッワーク用コイル、コンデンサ)もこみです
16cmウーファー2Wayセット(ペア) 2WSET1602-2 - コイズミ無線NET
### エンクロージャ設計
Fusion360を使って設計します。まずは地道にスピーカを作って生きます
#### Faital Pro 16cm 定価 5,934円(内税)
まずはFaital Pro 16cmから。
コイズミ無線は図面等が準備されていてとても親切です。
せっせと作りました
ほとんどは断面でスケッチ描いて回転させての繰り返しです。
大事なのはネジ穴の位置と、開口径なので細かい部分は適当です。
今回の場合は狭いエンクロージャに閉じ込めるので、ボイスコイル同士が干渉する事態がおきました。ので、ボイスコイルの寸法はきっちりとします。
2D図面化したのはこちら。
### HiVi ドームツイーター K1 定価 2,031円(内税)
結構それっぽく出来たと思います。いい感じ。
次回はエンクロージャー部分を作ります
TEDxTitech 聴講
こんにちはフィフィです。
今日は東工大にTEDxを聴講しに行ってきました。
TEDはランチ後のお昼寝の前によく見させて貰っていましたが、参加は初めて。
やっぱり映像とは全然違いました。
生の声から受けるパッションと緊張はYoutubeではまだ代替できないみたいです。
テーマは学際。複数の学術分野にまたがるテーマの追求。
例えば、メディカルイラストレーター = 医学 + アート
tokco - MEMBERS ~ LAIMAN | サイエンス&メディカルイラストレーションの株式会社レーマン
例えば、ギャル電 = ギャル + Lチカ以上Iot未満
などなど
多種のスピーカーが参加されとても有意義な時間でした。
vivaldiのエンジニアも講演されていました。
Vivaldiは公開当初から応援していることもあり大変刺激になりました。
Vivaldi Browser | Fast & Flexible Web Browser
宣伝しておきますので皆さん一度ダウンロードを
ご観覧ありがとうございました。
フィ