カテゴリー
学術

自作ROMライター その1

 PCのサウンド出力を多チャンネル化し複数の信号を扱える装置をなぜ作っているかの理由ですが、8085を動かすためにはどうしてもROMが必要で、それにはROMライタがなければ何もできません。

 ROMライタを手に入れれば何のことも無いのですが、勉強がてら作成することにしました。

 マイコンボードをUSBに繋いでROMに必要な信号を送る方法が定石のようですが8085の時代にUSBや今のシングルボードコンピュータがあったわけではないのでオペアンプとジャンクに近い部品で作成しようとしています。

#include <iostream>
#include <windows.h>
#include <math.h>
#include <MMSystem.h>

#pragma comment (lib, "winmm.lib")

void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) {
    size_t wavelength = sampling / frequency;
    double d = 360.0 / wavelength;
    double pi = 3.14159265359;
    for (int i = 0; i < wavelength; i++) {
        lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi));
    }
}

int main() {

    WAVEFORMATEX wfe;
    static HWAVEOUT hWaveOut;
    static WAVEHDR whdr;
    static LPWORD lpWave;
    static LPWORD lpData;

    // 最初と最後の1sは出力しないので3以上とする
    size_t terms = 12;

    size_t i, j, k, start, end;
    size_t frequency = 400;
    size_t sampling = 192000;
    size_t wavelength = sampling / frequency;

    wavelength = sampling / frequency;
    wfe.wFormatTag = WAVE_FORMAT_PCM;
    wfe.nChannels = 2;
    wfe.wBitsPerSample = 16;
    wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8;
    wfe.nSamplesPerSec = (DWORD)sampling;
    wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign;
    waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL);
    lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);

    end = sampling * wfe.nChannels * 1;
    WORD amplitude = 32767/4;
    for (i = 0; i < end; i++) {
        lpWave[i] = 0;
    }

    // 最初の1sは出力しない
    start = sampling * wfe.nChannels * 1;
    end = wfe.nChannels * sampling * terms;
    // 最後の1sは出力しない
    end -= sampling * wfe.nChannels * 1;

    size_t valWavelength;
    size_t valFrequency;

    lpData = (LPWORD)calloc(sizeof(WORD), wavelength);
    createWave(lpData, frequency, sampling, amplitude);
    for (i = start, j = 0; i < end; i += 2) {
        lpWave[i] = lpData[j];
        ++j;
        if (j >= wavelength) { j = 0; }
    }
    free(lpData);

    valFrequency = 3200;
    valWavelength = sampling / valFrequency;
    for (i = start + 1, j = 0, k = 0; i < end; i += 2) {
        if (j == 0) {
            lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
            createWave(lpData, valFrequency, sampling, amplitude);
        }
        if (sampling/4 * 0 <= k && k < sampling/4 * 1) {
            lpWave[i] = lpData[j];
        }
        ++j;
        ++k;
        if (j >= valWavelength) {
            j = 0;
            free(lpData);
        }
        if (k >= sampling) {
            k = 0;
        }
    }

    valFrequency = 8000;
    valWavelength = sampling / valFrequency;
    for (i = start + 1, j = 0, k = 0; i < end; i += 2) {
        if (j == 0) {
            lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
            createWave(lpData, valFrequency, sampling, amplitude);
        }
        if (sampling/4 * 1 <= k && k < sampling/4 * 2) {
            lpWave[i] += lpData[j];
        }
        ++j;
        ++k;
        if (j >= valWavelength) {
            j = 0;
            free(lpData);
        }
        if (k >= sampling) {
            k = 0;
        }
    }
 
    valFrequency = 11300;
    valWavelength = sampling / valFrequency;
    for (i = start + 1, j = 0, k = 0; i < end; i += 2) {
        if (j == 0) {
            lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
            createWave(lpData, valFrequency, sampling, amplitude);
        }
        if (sampling/4 * 2 <= k && k < sampling/4 * 3) {
            lpWave[i] += lpData[j];
        }
        ++j;
        ++k;
        if (j >= valWavelength) {
            j = 0;
            free(lpData);
        }
        if (k >=  sampling) {
            k = 0;
        }
    }
 
    valFrequency = 17000;
    valWavelength = sampling / valFrequency;
    for (i = start + 1, j = 0, k = 0; i < end; i += 2) {
        if (j == 0) {
            lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
            createWave(lpData, valFrequency, sampling, amplitude);
        }
        if (sampling/4 * 3 <= k && k < sampling/4 * 4) {
            lpWave[i] += lpData[j];
        }
        ++j;
        ++k;
        if (j >= valWavelength) {
            j = 0;
            free(lpData);
        }
        if (k >= sampling) {
            k = 0;
        }
    }
    
    whdr.lpData = (LPSTR)lpWave;
    whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms;
    whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
    whdr.dwLoops = 1;
    waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR));
    waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR));

    char str[128];
    std::cout << "hello, world\n";
    std::cin >> str;

}

 4つの異なる周波数の信号を混合しPCからサウンド出力します。それぞれ別に信号が出ている時はhigh、出ていない時はlowとすれば1つのアナログ信号を4つのデジタル信号として解釈できるはずです。

ROMライターアナログ部
ROMライターアナログ部

 741Cを2個1組にして4組のフィルタで分離しそれぞれをまた741Cで増幅後、ダイオードで検波しています。各信号を復調し信号を取り出す仕組みです。

 PCからLEDを順に点灯する信号を出してみました。意図通りそれぞれ別の周波数のhighとlowの信号が4つに分離されています。

 振幅偏移変調による多重化通信装置の完成です。

カテゴリー
学術

uPC458C

クワッド低ノイズ演算増幅回路

uPC458C
uPC458C

ChatGPTに聞いてみた。

User
uPC458Cは何ですか。

ChatGPT
uPC458Cは、オペアンプ(Operational Amplifier)IC(集積回路)の1つです。このICは、高利得、高入力インピーダンス、高CMRR(共通モード抑制比)、低歪みなどの特性を持っており、アナログ回路における信号増幅やフィルタリング、波形整形などに使用されます。

uPC458Cは、デュアルインラインパッケージ(DIP)で提供され、8ピンのパッケージングを採用しています。このICには、2つのオペアンプがあり、それぞれのオペアンプには、非反転入力ピン、反転入力ピン、出力ピン、電源ピンがあります。

uPC458Cは、高速な信号増幅やフィルタリング、低歪みなどの特性を持っており、音響機器、計測機器、通信機器、制御機器などのアプリケーションに広く使用されています。

カテゴリー
学術

アクティブバンドパスフィルタ4

 オペアンプ二段増幅型バンドパスフィルタが思いのほか上手く出来たので4個並べてみました。

4チャンネルバンドパスフィルタ
3,148Hz付近
7,680Hz付近
11,294Hz付近
17,455Hz付近
上部 -6, +6両電源(LM386)
下部 4チャンネル化するためのフィルター
#include <iostream>
#include <windows.h>
#include <math.h>
#include <MMSystem.h>

#pragma comment (lib, "winmm.lib")

void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) {
    size_t wavelength = sampling / frequency;
    double d = 360.0 / wavelength;
    double pi = 3.14159265359;
    for (int i = 0; i < wavelength; i++) {
        lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi));
    }
}

int main() {

    WAVEFORMATEX wfe;
    static HWAVEOUT hWaveOut;
    static WAVEHDR whdr;
    static LPWORD lpWave;
    static LPWORD lpData;

    // 最初と最後の1sは出力しないので3以上とする
    size_t terms = 7;

    size_t i, j, start, end;
    size_t frequency = 400;
    size_t sampling = 192000;
    size_t wavelength = sampling / frequency;

    wavelength = sampling / frequency;
    wfe.wFormatTag = WAVE_FORMAT_PCM;
    wfe.nChannels = 2;
    wfe.wBitsPerSample = 16;
    wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8;
    wfe.nSamplesPerSec = (DWORD)sampling;
    wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign;
    waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL);
    lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);

    end = sampling * wfe.nChannels * 1;
    WORD amplitude = 32767;
    for (i = 0; i < end; i++) {
        lpWave[i] = 0;
    }

    // 最初の1sは出力しない
    start = sampling * wfe.nChannels * 1;
    end = wfe.nChannels * sampling * terms;
    // 最後の1sは出力しない
    end -= sampling * wfe.nChannels * 1;

    size_t valWavelength;
    size_t valFrequency;

    lpData = (LPWORD)calloc(sizeof(WORD), wavelength);
    createWave(lpData, frequency, sampling, amplitude);
    for (i = start, j = 0; i < end; i += 2) {
        lpWave[i] = lpData[j];
        ++j;
        if (j >= wavelength) { j = 0; }
    }
    free(lpData);

    for (i = start + 1, j = 0; i < end; i += 2) {
        if (j == 1) {
            valFrequency = frequency + ((i - start) * (20000.0 - frequency)) / (sampling * wfe.nChannels * (terms - 2));
            valWavelength = sampling / valFrequency;
            lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
            createWave(lpData, valFrequency, sampling, amplitude);
        }
        lpWave[i] = lpData[j];
        ++j;
        if (j >= valWavelength) {
            j = 0;
            free(lpData);
        }
    }

    whdr.lpData = (LPSTR)lpWave;
    whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms;
    whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
    whdr.dwLoops = 1;
    waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR));
    waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR));

    char str[128];
    std::cout << "hello, world\n";
    std::cin >> str;

}

 可聴範囲を4分割し多チャンネル化できました。普通のPCであればステレオサウンド出力は付いているので左右に適用すれば8チャンネル、フィルタをもっと丁寧に作ればそれ以上も可能と思います。

カテゴリー
学術

相対性理論 運動学の部

相対性理論
相対性理論

 文庫本として読んでみましたが理解できませんでした。前半が論文で後半が解説になっており一般の人でも解る構成だそうですが、光速が不変であることぐらいしか読み取ることができませんでした。これで終わってはもったいないので数式を解るところまで勉強してみます。

運動学の部

$$t_B-t_A=t’_A-t_B$$

$$\frac{2\overline{AB}}{t’_A-t_A}=c$$

$$t_B-t_A=\frac{r_{AB}}{c-v’}$$

$$t’_A-t_B=\frac{r_{AB}}{c+v’}$$

$$\frac{1}{2}(\tau_0+\tau_2)=\tau_1$$

$$\frac{1}{2}\left\{\tau(0,0,0,t)+\\\tau\left(0,0,0,t+\frac{l’}{c-v}+\frac{l’}{c+v}\right)\right\}\\=\tau\left(l’,0,0,t+\frac{l’}{c-v}\right).$$

$$\frac{\partial \tau}{\partial x’}+\frac{v}{c^2-v^2}\frac{\partial \tau}{\partial t}=0$$

$$\frac{\partial \tau}{\partial y}=0, \frac{\partial \tau}{\partial z}=0$$

$$\tau=a\left(t-\frac{v}{c^2-v^2}x’\right)$$

$$\xi=c\tau$$

$$\xi=ac\left(t-\frac{v}{c^2-v^2}x’\right)$$

$$\frac{x’}{c-v}=t.$$

$$\xi=a\frac{c^2}{c^2-v^2}x’.$$

$$\eta=c\tau=ac\left(t-\frac{v}{c^2-v^2}x’\right).$$

$$\frac{y}{\sqrt{c^2-v^2}}=t,\space x’=0$$

$$\eta=a\frac{c}{\sqrt{c^2-v^2}}y.$$

$$\xi=a\frac{c}{\sqrt{c^2-v^2}}z.$$

$$x’=x-vt$$

$$\tau=\varphi(v)\beta\left(t-\frac{v}{c^2}x\right),$$

$$\xi=\varphi(v)\beta(x-vt),$$

$$\eta=\varphi(v)y,$$

$$\zeta=\varphi(v)z.$$

$$\beta=\frac{1}{\sqrt{1-(v/c)^2}},$$

$$\varphi(v)=\frac{a(v)}{\sqrt{1-(v/c)^2}}$$

$$x^2+y^2+z^2=c^2 t^2$$

$$\xi^2+\eta^2+\zeta^2=c^2 \tau^2$$

$$t’=\varphi(-v)\cdot\beta(-v)\left(\tau+\frac{v}{c^2}\xi\right)=\\\varphi(v)\cdot\varphi(-v)t,$$

$$x’=\varphi(-v)\cdot\beta(-v)(\xi+vt)=\\ \varphi(v)\cdot\varphi(-v)x,$$

$$y’=\varphi(-v)\eta=\varphi(v)\cdot\varphi(-v)y,$$

$$z’=\varphi(-v)\zeta=\varphi(v)\cdot\varphi(-v)z.$$

$$\varphi(v)\cdot\varphi(-v)=1$$

$$x_1=vt,\space y_1=\frac{l}{\varphi(v)’},\space z_1=0.$$

$$x_2=vt,\space y_2=0,\space z_2=0.$$

$$\frac{l}{\varphi(v)}=\frac{l}{\varphi(-v)},$$

$$\varphi(v)=\varphi(-v)$$

$$\tau=\beta\cdot\left(t-\frac{v}{c^2}x\right),$$

$$\xi=\beta\cdot(x-vt),$$

$$\eta=y,\space \zeta=z.$$

$$\beta=\frac{1}{\sqrt{1-(v/c)^2}}$$

$$\xi^2+\eta^2+\zeta^2=R^2.$$

$$\left\{\frac{x}{\sqrt{1-(v/c)^2}}\right\}^2+y^2+z^2=R^2.$$

$$R\sqrt{1-(v/c)^2},\space R,\space R$$

$$1:\sqrt{1-(v/c)^2}$$

$$\tau=\left. \left(t-\frac{v}{c^2}x\right)\middle/\sqrt{1-\left(\frac{v}{c}\right)^2}.\right.$$

$$x=vt$$

$$\tau=t\sqrt{1-\left(\frac{v}{c}\right)^2}=\\t-\left\{1-\sqrt{1-\left(\frac{v}{c}\right)^2}\right\}t$$

$$\left\{1-\sqrt{1-(v/c)^2}\right\}$$

$$\xi=w_{\xi}\tau,\space \eta=w_{\eta}\tau,\space \zeta=0$$

$$x=\frac{w_{\xi}+v}{1+(vw_{\xi}/c^2)}t,$$

$$y=\frac{\sqrt{1-(v/c)^2}}{1+(vw_{\xi}/c^2)}w_{\eta}t,$$

$$z=0.$$

$$U^2=\left(\frac{dx}{dt}\right)^2+\left(\frac{dy}{dt}\right)^2,$$

$$w^2=(w_{\xi})^2+(w_{\eta})^2,$$

$$\alpha=arctan(w_{\eta}/w_{\xi})$$

$$U=\frac{\sqrt{(v^2+w^2+2vw\space cos\space \alpha)-(vw\space sin\space\alpha/c)^2}}{1+(vw\space cos \space\alpha/c^2)}.$$

$$U=\frac{v+w}{1+(vw/c^2)}.$$

$$U=c\frac{2c-\kappa-\lambda}{2c-\kappa-\lambda+\frac{\kappa\lambda}{c}}<c.$$

$$U=\frac{c+w}{1+(w/c)}=c.$$

$$\frac{v+w}{1+(vw/c^2)}$$

 相対性理論の前までは速度は一つの物理量として自由に加減できたのですが、光速が不変とわかったとき、速度に関わる法則を見直さなければならなくなり、それまで不変としてきた時間や空間を可変にすることで法則の維持を図ったのだと思います。それを実証する為に今でも観測や実験が繰り返されているのでしょう。

カテゴリー
学術

集合知

カテゴリー
学術

アクティブバンドパスフィルタ3

 流石にアクティブバンドフィルターは期待通りの性能を出せました。低周波領域でもオペアンプを使えば部品点数も少なく理想的なフィルタが作れそうです。続いて信号の分離性を高めるためQの高いフィルタで実験してみました。

R1=220200Ω
R2=4771Ω
R3=4630Ω
C1=2677pF
IC=UPC741C
Q=46.851
f0=12649.593Hz

二段増幅型バンドパスフィルタで400Hzから20kHzをスイープしている様子

 このくらいのQであれば信号の分離ができそうです。

400Hz付近
12kHz付近
20kHz付近
オペアンプ二段増幅型バンドパスフィルタ
オペアンプ二段増幅型バンドパスフィルタ

 部品点数も少なくQが高いバンドフィルタを作ることができました。これであればPCのサウンドライン出力に複数の信号を混合し受け側で分離すればライン1チャンネルを複数チャンネルにすることができそうです。1つのプログラム、1つのチャンネル、1つの受け側となるので波形単位の制御が必要なデジタル信号処理にも耐えられると思います。

#include <iostream>
#include <windows.h>
#include <math.h>
#include <MMSystem.h>

#pragma comment (lib, "winmm.lib")

void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) {
    size_t wavelength = sampling / frequency;
    double d = 360.0 / wavelength;
    double pi = 3.14159265359;
    for (int i = 0; i < wavelength; i++) {
        lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi));
    }
}

int main() {

    WAVEFORMATEX wfe;
    static HWAVEOUT hWaveOut;
    static WAVEHDR whdr;
    static LPWORD lpWave;
    static LPWORD lpData;

    // 最初と最後の1sは出力しないので3以上とする
    size_t terms = 7;

    size_t i, j, start, end;
    size_t frequency = 400;
    size_t sampling = 384000;
    size_t wavelength = sampling / frequency;

    wavelength = sampling / frequency;
    wfe.wFormatTag = WAVE_FORMAT_PCM;
    wfe.nChannels = 2;
    wfe.wBitsPerSample = 16;
    wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8;
    wfe.nSamplesPerSec = (DWORD)sampling;
    wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign;
    waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL);
    lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);

    end = sampling * wfe.nChannels * 1;
    WORD amplitude = 32767;
    for (i = 0; i < end; i++) {
        lpWave[i] = 0;
    }

    // 最初の1sは出力しない
    start = sampling * wfe.nChannels * 1;
    end = wfe.nChannels * sampling * terms;
    // 最後の1sは出力しない
    end -= sampling * wfe.nChannels * 1;

    size_t valWavelength;
    size_t valFrequency;
    for (i = start, j = 0; i < end; i += 2) {
        if (j == 0) {
            valFrequency = frequency + ((i - start) * (20000.0- frequency)) / (sampling * wfe.nChannels * (terms - 2));
            valWavelength = sampling / valFrequency;
            lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
            createWave(lpData, valFrequency, sampling, amplitude);
        }
        lpWave[i] = lpData[j];
        ++j;
        if (j >= valWavelength) {
            j = 0;
            free(lpData);
        }
    }

    lpData = (LPWORD)calloc(sizeof(WORD), wavelength);
    createWave(lpData, frequency, sampling, amplitude);
    for (i = start+1, j = 0; i < end; i += 2) {
        lpWave[i] = lpData[j];
        ++j;
        if (j >= wavelength) { j = 0; }
    }
    free(lpData);

    whdr.lpData = (LPSTR)lpWave;
    whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms;
    whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
    whdr.dwLoops = 1;
    waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR));
    waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR));
    
    char str[128];
    std::cout << "hello, world\n";
    std::cin >> str;

}
カテゴリー
学術

アクティブバンドパスフィルタ2

 パッシブバンドフィルタが上手くいかなかったのでオペアンプを使用してアクティブバンドフィルタの実験を行いました。

Multiple Feedback Band Pass Filter
Multiple Feedback Band Pass Filter

R1=4649Ω
R2=4763Ω
R3=477.8kΩ
C1=287pF
C2=295pF
IC=UPC741C
Q=7.125
f0=16314.28Hz

パッシブバンドフィルタ

 可聴周波数をスイープして出力しフィルタを通した様子です。フィルタが機能しているのが判ります。しかし、複数の信号を狭い帯域に載せるにはもっとQが高くないと分離が上手くいかないような気がします。

400Hz付近
11kHz付近、コンデンサの容量が小さいのでブレッドボードの影響を受けている模様
20kHz付近
オペアンプ多重帰還型バンドパスフィルタ
オペアンプ多重帰還型バンドパスフィルタ
#include <iostream>
#include <windows.h>
#include <math.h>
#include <MMSystem.h>

#pragma comment (lib, "winmm.lib")

void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) {
    size_t wavelength = sampling / frequency;
    double d = 360.0 / wavelength;
    double pi = 3.14159265359;
    for (int i = 0; i < wavelength; i++) {
        lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi));
    }
}

int main() {

    WAVEFORMATEX wfe;
    static HWAVEOUT hWaveOut;
    static WAVEHDR whdr;
    static LPWORD lpWave;
    static LPWORD lpData;

    // 最初と最後の1sは出力しないので3以上とする
    size_t terms = 7;

    size_t i, j, start, end;
    size_t frequency = 400;
    size_t sampling = 384000;
    size_t wavelength = sampling / frequency;

    wavelength = sampling / frequency;
    wfe.wFormatTag = WAVE_FORMAT_PCM;
    wfe.nChannels = 2;
    wfe.wBitsPerSample = 16;
    wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8;
    wfe.nSamplesPerSec = (DWORD)sampling;
    wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign;
    waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL);
    lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);

    end = sampling * wfe.nChannels * 1;
    WORD amplitude = 32767;
    for (i = 0; i < end; i++) {
        lpWave[i] = 0;
    }

    // 最初の1sは出力しない
    start = sampling * wfe.nChannels * 1;
    end = wfe.nChannels * sampling * terms;
    // 最後の1sは出力しない
    end -= sampling * wfe.nChannels * 1;

    size_t valWavelength;
    size_t valFrequency;
    for (i = start, j = 0; i < end; i += 2) {
        if (j == 0) {
            valFrequency = frequency + ((i - start) * (20000.0- frequency)) / (sampling * wfe.nChannels * (terms - 2));
            valWavelength = sampling / valFrequency;
            lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
            createWave(lpData, valFrequency, sampling, amplitude);
        }
        lpWave[i] = lpData[j];
        ++j;
        if (j >= valWavelength) {
            j = 0;
            free(lpData);
        }
    }

    lpData = (LPWORD)calloc(sizeof(WORD), wavelength);
    createWave(lpData, frequency, sampling, amplitude);
    for (i = start+1, j = 0; i < end; i += 2) {
        lpWave[i] = lpData[j];
        ++j;
        if (j >= wavelength) { j = 0; }
    }
    free(lpData);

    whdr.lpData = (LPSTR)lpWave;
    whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms;
    whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
    whdr.dwLoops = 1;
    waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR));
    waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR));
    
    char str[128];
    std::cout << "hello, world\n";
    std::cin >> str;

}
カテゴリー
学術

パッシブバンドフィルター

 PCのサウンドラインに複数の信号を混合して出力し受け側で利用するためにはフィルタで分離する必要があります。早速簡単なLCフィルターで実験してみました。手持ちに丁度良いコイルが無かったので小信号トランスで代用しました。

Passive Band Pass Filter
Passive Band Pass Filter

R=1305Ω
L=494mH
C=4633pF
Q=7.912
f0=3326.791Hz

パッシブフィルターの性能

 400Hzから20kHzまでスイープして信号を出力してみましたが、実用にできるほどの分離性はみられませんでした。

パッシブバンドフィルタ
RLC パッシブバンドフィルタ

 扱っているのが低周波なので性能の良いコイルを小さく作らないと使い物にならないことがわかりました。

#include <iostream>
#include <windows.h>
#include <math.h>
#include <MMSystem.h>

#pragma comment (lib, "winmm.lib")

void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) {
    size_t wavelength = sampling / frequency;
    double d = 360.0 / wavelength;
    double pi = 3.14159265359;
    for (int i = 0; i < wavelength; i++) {
        lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi));
    }
}

int main() {

    WAVEFORMATEX wfe;
    static HWAVEOUT hWaveOut;
    static WAVEHDR whdr;
    static LPWORD lpWave;
    static LPWORD lpData;

    // 最初と最後の1sは出力しないので3以上とする
    size_t terms = 7;

    size_t i, j, start, end;
    size_t frequency = 400;
    size_t sampling = 384000;
    size_t wavelength = sampling / frequency;

    wavelength = sampling / frequency;
    wfe.wFormatTag = WAVE_FORMAT_PCM;
    wfe.nChannels = 2;
    wfe.wBitsPerSample = 16;
    wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8;
    wfe.nSamplesPerSec = (DWORD)sampling;
    wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign;
    waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL);
    lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);

    end = sampling * wfe.nChannels * 1;
    WORD amplitude = 32767;
    for (i = 0; i < end; i++) {
        lpWave[i] = 0;
    }

    // 最初の1sは出力しない
    start = sampling * wfe.nChannels * 1;
    end = wfe.nChannels * sampling * terms;
    // 最後の1sは出力しない
    end -= sampling * wfe.nChannels * 1;

    size_t valWavelength;
    size_t valFrequency;
    for (i = start, j = 0; i < end; i += 2) {
        if (j == 0) {
            valFrequency = frequency + ((i - start) * (20000.0- frequency)) / (sampling * wfe.nChannels * (terms - 2));
            valWavelength = sampling / valFrequency;
            lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
            createWave(lpData, valFrequency, sampling, amplitude);
        }
        lpWave[i] = lpData[j];
        ++j;
        if (j >= valWavelength) {
            j = 0;
            free(lpData);
        }
    }

    lpData = (LPWORD)calloc(sizeof(WORD), wavelength);
    createWave(lpData, frequency, sampling, amplitude);
    for (i = start+1, j = 0; i < end; i += 2) {
        lpWave[i] = lpData[j];
        ++j;
        if (j >= wavelength) { j = 0; }
    }
    free(lpData);

    whdr.lpData = (LPSTR)lpWave;
    whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms;
    whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
    whdr.dwLoops = 1;
    waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR));
    waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR));
    
    char str[128];
    std::cout << "hello, world\n";
    std::cin >> str;

}
カテゴリー
学術

Fixed action pattern

カテゴリー
学術

アクティブバンドパスフィルタ1

 PCのサウンドライン出力に複数の周波数の信号を混合して出力し受け側で分離すれば1ラインを多重化できそうです。

二段増幅型バンドパスフィルター

1kHz
f0 = 1002.582Hz
Q = 20.788
R1 = 330kΩ
R2 = 15kΩ
R3 = 10kΩ + 6.8kΩ
R4, R5 = 10kΩ
C1, C2 = 0.01μF

6kHz
f0 = 5967.749Hz
Q = 20.788
R1 = 330kΩ
R2 = 15kΩ
R3 = 10kΩ + 6.8kΩ
R4, R5 = 10kΩ
C1, C2 = 1000pF + 680pF

11kHz
f0 = 11022.17Hz
Q = 22.854
R1 = 330kΩ
R2 = 15kΩ
R3 = 10kΩ + 3.9kΩ
R4, R5 = 10kΩ
C1, C2 = 1000pF

16kHz
f0 = 15921.863Hz
Q = 22.449
R1 = 330kΩ
R2, R3 = 10kΩ + 4.7kΩ
R4, R5 = 10kΩ
C1, C2 = 680pF

カテゴリー
学術

ジェネレーター5

 複数の周波数が混在した信号を利用する時にはフィルタで分離する必要があります。そのフィルタを評価するために指定範囲の周波数をスイープするジェネレーターを作りました。

上がスイープしている波形、下が開始周波数(400Hz)の波形
開始時は上下同じ400Hz
終了時は上は約20kHz、下は開始時のまま400Hz
#include <iostream>
#include <windows.h>
#include <math.h>
#include <MMSystem.h>

#pragma comment (lib, "winmm.lib")

void createWave(LPWORD lpData, size_t frequency, size_t sampling, WORD amplitude) {
    size_t wavelength = sampling / frequency;
    double d = 360.0 / wavelength;
    double pi = 3.14159265359;
    for (int i = 0; i < wavelength; i++) {
        lpData[i] = (WORD)(amplitude * sin(d * (i % wavelength) / 180.0 * pi));
    }
}

int main() {

    WAVEFORMATEX wfe;
    static HWAVEOUT hWaveOut;
    static WAVEHDR whdr;
    static LPWORD lpWave;
    static LPWORD lpData;

    // 最初と最後の1sは出力しないので3以上とする
    size_t terms = 7;

    size_t i, j, start, end;
    size_t frequency = 400;
    size_t sampling = 384000;
    size_t wavelength = sampling / frequency;

    wavelength = sampling / frequency;
    wfe.wFormatTag = WAVE_FORMAT_PCM;
    wfe.nChannels = 2;
    wfe.wBitsPerSample = 16;
    wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8;
    wfe.nSamplesPerSec = (DWORD)sampling;
    wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign;
    waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL);
    lpWave = (LPWORD)calloc(sizeof(WORD), wfe.nChannels * sampling * terms);

    end = sampling * wfe.nChannels * 1;
    WORD amplitude = 32767;
    for (i = 0; i < end; i++) {
        lpWave[i] = 0;
    }

    // 最初の1sは出力しない
    start = sampling * wfe.nChannels * 1;
    end = wfe.nChannels * sampling * terms;
    // 最後の1sは出力しない
    end -= sampling * wfe.nChannels * 1;

    size_t valWavelength;
    size_t valFrequency;
    for (i = start, j = 0; i < end; i += 2) {
        if (j == 0) {
            valFrequency = frequency + ((i - start) * (20000.0- frequency)) / (sampling * wfe.nChannels * (terms - 2));
            valWavelength = sampling / valFrequency;
            lpData = (LPWORD)calloc(sizeof(WORD), valWavelength);
            createWave(lpData, valFrequency, sampling, amplitude);
        }
        lpWave[i] = lpData[j];
        ++j;
        if (j >= valWavelength) {
            j = 0;
            free(lpData);
        }
    }

    lpData = (LPWORD)calloc(sizeof(WORD), wavelength);
    createWave(lpData, frequency, sampling, amplitude);
    for (i = start+1, j = 0; i < end; i += 2) {
        lpWave[i] = lpData[j];
        ++j;
        if (j >= wavelength) { j = 0; }
    }
    free(lpData);

    whdr.lpData = (LPSTR)lpWave;
    whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms;
    whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
    whdr.dwLoops = 1;
    waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR));
    waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR));
    
    char str[128];
    std::cout << "hello, world\n";
    std::cin >> str;

}
カテゴリー
学術

74LS74N

Flip Flops

74LS74N
74LS74N

ChatGPTに聞いてみた。

User
DM74LS74Nは何ですか。

ChatGPT
DM74LS74Nは、デュアルDフリップフロップ(Dual D Flip-Flop)IC(集積回路)の1つです。このICは、2つのDフリップフロップを持っており、デジタル回路においてデータの格納や信号の同期などに使用されます。

DM74LS74Nは、デュアルインラインパッケージ(DIP)で提供され、14ピンのパッケージングを採用しています。このICには、2つのDフリップフロップがあり、それぞれのフリップフロップには、D入力ピン、クロック入力ピン、セット入力ピン、リセット入力ピン、Q出力ピン、Qバー出力ピンがあります。

DM74LS74Nは、高速なデータの格納や同期、信号のフィルタリングなどに適しています。また、このICは、デジタルシステムにおけるカウンティングやタイミング、シーケンシャルロジック回路の実装などに広く使用されています。

カテゴリー
学術

74HC14AP

Hex Schmitt Inverter

74HC14AP
74HC14AP

https://toshiba.semicon-storage.com/info/docget.jsp?did=9945&prodName=TC74HC14AP

ChatGPTに聞いてみた。

User
74HC14APは何ですか。

ChatGPT
74HC14APは、インバータ(Inverter)IC(集積回路)の1つです。このICは、6つのインバータを持っており、入力信号を反転し、出力信号を生成することができます。また、このICは、高速で動作し、低消費電力であるため、多くのデジタルシステムに適しています。

74HC14APは、デュアルインラインパッケージ(DIP)で提供され、14ピンのパッケージングを採用しています。このICには、6つのインバータがあり、それぞれのインバータには、入力ピンと出力ピンがあります。

74HC14APは、高速な信号反転や駆動、多くのデジタルシステムでの信号調整などのアプリケーションに適しています。また、このICは、パルスジェネレーション、クロックドライバ、バッファリングなどのために、広く使用されています。

カテゴリー
学術

74HC125N

QuadrupleBus BufferGatesWith 3-StateOutputs

74HC125N
74HC125N

http://www.ti.com/lit/ds/scls104e/scls104e.pdf?ts=1591310379048

ChatGPTに聞いてみた。

User
SN74HC125Nは何ですか。

ChatGPT
SN74HC125Nは、バッファ/ラインドライバ(Buffer/Line Driver)IC(集積回路)の1つです。このICは、4つのバッファを持っており、入力信号を増幅し、出力信号を駆動することができます。また、このICは、高速で動作し、消費電力が少ないため、多くのデジタルシステムに適しています。

SN74HC125Nは、デュアルインラインパッケージ(DIP)で提供され、14ピンのパッケージングを採用しています。このICには、4つのバッファがあり、それぞれのバッファには、入力ピンと出力ピンがあります。また、バッファは、3つのステートメントコントロール入力(G、OE、nOE)を持っています。Gは、全体のICを有効化または無効化するために使用されます。OEは、すべてのバッファの出力を有効化または無効化するために使用されます。nOEは、単一のバッファの出力を有効化または無効化するために使用されます。

SN74HC125Nは、高速な信号増幅や駆動、多くのデジタルシステムでの信号調整などのアプリケーションに適しています。また、このICは、信号増幅、バッファリング、レベル変換などのために、広く使用されています。

カテゴリー
学術

74LS245N

Octal Bus TransceiversWith 3-StateOutputs

74LS245N
74LS245N

http://www.ti.com/lit/ds/symlink/sn54ls245-sp.pdf?ts=1591310459915

ChatGPTに聞いてみた。

User
SN74LS245Nは何ですか。

ChatGPT
SN74LS245Nは、バストランシーバ(Bus Transceiver)IC(集積回路)の1つです。このICは、2つのバス間で双方向通信を実現するために使用されます。バスは、データ、アドレス、および制御信号などの複数の信号線のグループです。

SN74LS245Nは、デュアルインラインパッケージ(DIP)で提供され、20ピンのパッケージングを採用しています。このICには、8つの入力/出力(I/O)ピンがあります。それぞれのピンは、片方向の入力または出力として機能することができます。また、このICは、入力と出力を切り替えるために、DIR(方向)ピンを持っています。DIRピンがHIGHの場合、ICは1つのバスからもう一方のバスにデータを送信します。DIRピンがLOWの場合、ICは逆方向に動作します。

SN74LS245Nは、高速で信頼性の高いバス通信を実現するために設計されています。また、このICは、複数のデバイス間で信号を送受信するために広く使用されています。

カテゴリー
学術

74LS153N

74LS153N
74LS153N

ChatGPTに聞いてみた。

User
SN74LS153Nは何ですか。

ChatGPT
SN74LS153Nは、デジタル回路に使用される4入力マルチプレクサ(Multiplexer)IC(集積回路)の1つです。このICは、2つの2入力マルチプレクサが統合されており、入力信号の1つを選択し、1つの出力に送信することができます。また、このICは、高速で動作し、低消費電力で動作するため、多くのデジタルシステムに適しています。

SN74LS153Nは、デュアルインラインパッケージ(DIP)で提供され、16ピンのパッケージングを採用しています。このICには、4つのデータ入力、2つの選択入力、1つの出力があります。選択入力は、2つのビットで指定され、4つのデータ入力のうち1つを選択し、選択された入力信号を出力に送信します。SN74LS153Nは、高速なデータスイッチングや遅延の少ない信号伝送などのアプリケーションに適しています。

カテゴリー
学術

74HC175AP

74HC175AP
74HC175AP

ChatGPTに聞いてみた。

User
74HC175APは何ですか。

ChatGPT
74HC175APは、デジタル回路に使用される、クアッドDフリップフロップ(Quad D Flip-Flop)IC(集積回路)の1つです。このICは、高速な動作、低消費電力、静的消費電力の低減、入力と出力の保護などの特徴を持っています。また、74HC175APは、単一の電源電圧で動作し、広い動作電圧範囲を持っています。ICのパッケージングには、16ピンのデュアルインラインパッケージ(DIP)が使用されています。

74HC175APは、4つの独立したDフリップフロップを持っており、各フリップフロップには、D入力、クロック入力、セット入力、リセット入力、Q出力、およびQバー出力があります。このICは、高速で信頼性の高いデータ保持や信号同期などの様々なアプリケーションに適しています。

カテゴリー
学術

LM386N-3

LM386N-3
LM386N-3

ChatGPTに聞いてみた。

User
LM386N-3は何ですか。

ChatGPT
LM386N-3は、小型の低電力オーディオアンプリファイア(Audio Amplifier)ICです。このICは、スピーカーやイヤホンなどの低インピーダンス負荷を駆動するために設計されています。 LM386N-3は、3ピンのパッケージングを採用しており、最大3Wの出力を提供できます。また、単一の電源電圧で動作し、外部部品を最小限に抑えることができます。これらの特性から、LM386N-3は、携帯電話や携帯オーディオプレーヤーなどの携帯型電子機器でよく使用されます。

カテゴリー
学術

ジェネレーター4

 PCのラインからサウンドを出力しその信号をそのままデジタル回路で使用することができるか実験してみました。

その1 矩形波のまま使用
 信号のレベルが少し低いのでHighが5V程度になるまでトランジスタやオペアンプで増幅してみましたが次の問題が発生しました。

問題1 一波長でON・OFFの繰り返しを継続して出力する時は波形が乱れない。一波長でOFFのみが間にあると前後の波形が大きく乱れる。

問題2 一定時間だけONの信号が出せない。常に正負交互の交流信号を出力しないと信号が出てこないか前後の波形が乱れる。

問題3 出力の終わりに意図しない波形が出力されデジタル素子が誤動作をしてしまう。


 

その2 矩形波を止めて正弦波にする
 矩形波は多くの高調波を含んでいるので正弦波のみであれば状況が改善すると思い実験してみましたが問題を全て解決できませんでした。

問題1 解決できた。

問題2 波長を低くすればある程度の期間ONにできる。矩形波でも同様。

問題3 改善されない。


 

その3 常に信号を出している状態にする
 AMラジオの様に常に搬送波を出力しそれにデータである信号を乗せてみました。

問題1 再燃した。

問題2 その2と同じ解決できる。

問題3 若干改善した。


 

結論

 PCのサウンド出力はアプリから要求された信号を忠実に送出するのではなく独自の制御を行っているため振幅に意味を持たせる方法ではデジタルデータとしてそのまま使用できないことが解りました。


 

AM変調
AM変調
AM変調(拡大)
AM変調(拡大)
#include <iostream>
#include <string>
#include <windows.h>
#include <math.h>
#include <MMSystem.h>

#pragma comment (lib, "winmm.lib")

int main() {

    WAVEFORMATEX wfe1;
    static HWAVEOUT hWaveOut1;
    static WAVEHDR whdr1;
    static LPBYTE lpWave1;
    static LPBYTE lpDataA;
    static LPBYTE lpDataB;

    int i, j, len1, start, end;
    int f1;
    size_t terms = 300;
    int sampling = 192000;
    size_t size;
    double pi = 3.14159265359;

    f1 = 15000;
    len1 = sampling / f1;
    wfe1.wFormatTag = WAVE_FORMAT_PCM;
    wfe1.nChannels = 2;
    wfe1.wBitsPerSample = 8;
    wfe1.nBlockAlign = wfe1.nChannels * wfe1.wBitsPerSample / 8;
    wfe1.nSamplesPerSec = sampling;
    wfe1.nAvgBytesPerSec = wfe1.nSamplesPerSec * wfe1.nBlockAlign;
    waveOutOpen(&hWaveOut1, 0, &wfe1, 0, 0, CALLBACK_NULL);
    size = terms * wfe1.nChannels;
    lpWave1 = (LPBYTE)calloc(wfe1.nAvgBytesPerSec, size);

    for (i = 0; i < sampling * terms * wfe1.nChannels; i++) {
        lpWave1[i] = 128;
    }

    start = sampling * wfe1.nChannels * 1;
    end = start + len1 * wfe1.nChannels * f1 * terms;

    double d = 360.0 / len1;
    lpDataA = (LPBYTE)calloc(wfe1.nAvgBytesPerSec, len1);
    for (i = 0; i < len1; i++) {
        lpDataA[i] = (BYTE)(70.0 * sin(d * (i % len1) / 180.0 * pi) + 127.5);
    }

    for (i = start, j = 0; i < end; i++) {
        if ((i % 2) == 0) {
            lpWave1[i] = lpDataA[j];
            ++j;
            if (j >= len1) { j = 0; }
        }
    }

    int a = 300;
    lpDataB = (LPBYTE)calloc(wfe1.nAvgBytesPerSec, len1*a);
    for (i = 0; i < len1*a; i++) {
        lpDataB[i] = (BYTE)(50.0 * sin(d * i / 180.0 * pi / a) + 127.5);
    }

    for (i = start, j = 0; i < end; i++) {
        if ((i % 2) == 1) {
            if (((i / 2 / len1)+0) % 8 < 8 ) {
                lpWave1[i] = lpWave1[i-1] + lpDataB[j] - 128;
                ++j;
                if (j >= len1*a) { j = 0; }
            }
            else { lpWave1[i] = 128; }
        }
    }

    whdr1.lpData = (LPSTR)lpWave1;
    whdr1.dwBufferLength = wfe1.nAvgBytesPerSec * terms;
    whdr1.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
    whdr1.dwLoops = 1;
    waveOutPrepareHeader(hWaveOut1, &whdr1, sizeof(WAVEHDR));
    waveOutWrite(hWaveOut1, &whdr1, sizeof(WAVEHDR));
    
    char str[128];
    std::cout << "hello, world\n";
    std::cin >> str;

}

 

カテゴリー
学術

ジェネレーター3

矩形波をパソコンのラインから出力

 パソコンから20Hzの矩形波をライン出力してみました。LEDが8個並んでいるのはいずれシリアルパラレル変換するためです。今回は並列に接続しているので同じように動作します。下記のコードは4CH出力していますが、動画のLEDのボードに接続しているのはデバイス0のLeftです。

#include <iostream>
#include <string>
#include <windows.h>
#include <MMSystem.h>

#pragma comment (lib, "winmm.lib")

int main() {

    WAVEFORMATEX wfe;
    static HWAVEOUT hWaveOut;
    static WAVEHDR whdr;
    static LPBYTE lpWave;
    WAVEFORMATEX wfe2;
    static HWAVEOUT hWaveOut2;
    static WAVEHDR whdr2;
    static LPBYTE lpWave2;
    int i, len, start, end;
    int frequency = 20;
    int terms = 10;
    int sampling = 192000;

    wfe.wFormatTag = WAVE_FORMAT_PCM;
    wfe.nChannels = 2;
    wfe.wBitsPerSample = 8;
    wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8;
    wfe.nSamplesPerSec = sampling;
    wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nBlockAlign;
    waveOutOpen(&hWaveOut, 0, &wfe, 0, 0, CALLBACK_NULL);
    lpWave = (LPBYTE)calloc(wfe.nAvgBytesPerSec, terms * wfe.nChannels);

    wfe2.wFormatTag = WAVE_FORMAT_PCM;
    wfe2.nChannels = 2;
    wfe2.wBitsPerSample = 8;
    wfe2.nBlockAlign = wfe2.nChannels * wfe2.wBitsPerSample / 8;
    wfe2.nSamplesPerSec = sampling;
    wfe2.nAvgBytesPerSec = wfe2.nSamplesPerSec * wfe2.nBlockAlign;
    waveOutOpen(&hWaveOut2, 2, &wfe2, 0, 0, CALLBACK_NULL);
    lpWave2 = (LPBYTE)calloc(wfe2.nAvgBytesPerSec, terms * wfe2.nChannels);

    // 立ち上がりは出力を0にする
    for (i = 0; i < sampling * terms * wfe.nChannels; i++) {
        lpWave[i] = 128;
        lpWave2[i] = 128;
    }

    len = sampling / frequency; 

    // 最初の8サイクルは出力しない
    start = len * 8 * wfe.nChannels;
    start = 0;
    // 8サイクル波形を出力する
    end = start + len * 32 * wfe.nChannels;
    printf("start=%d, end=%d\n", start, end);

    for (i = start; i < end; i++) {
        if ((i % 2) == 0) {
            if ((i/2) % len < len / 2) { lpWave[i] = 228; }
            else { lpWave[i] = 28; }}}

    len /= 2;
    for (i = start; i < end; i++) {
        if ((i % 2) == 1) {
            if ((i / 2) % len < len / 2) { lpWave[i] = 228; }
            else { lpWave[i] = 28; }}}

    len *= 2;
    for (i = start; i < end; i++) {
        if ((i % 2) == 1) {
            if ((i / 2) % len < len / 2) { lpWave2[i] = 228; }
            else { lpWave2[i] = 28; }
        }
    }

    len /= 2;
    for (i = start; i < end; i++) {
        if ((i % 2) == 0) {
            if ((i / 2) % len < len / 2) { lpWave2[i] = 228; }
            else { lpWave2[i] = 28; }
        }
    }

    whdr.lpData = (LPSTR)lpWave;
    whdr.dwBufferLength = wfe.nAvgBytesPerSec * terms;
    whdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
    whdr.dwLoops = 1;
    waveOutPrepareHeader(hWaveOut, &whdr, sizeof(WAVEHDR));
    waveOutWrite(hWaveOut, &whdr, sizeof(WAVEHDR));

    whdr2.lpData = (LPSTR)lpWave2;
    whdr2.dwBufferLength = wfe.nAvgBytesPerSec * terms;
    whdr2.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
    whdr2.dwLoops = 1;
    waveOutPrepareHeader(hWaveOut2, &whdr2, sizeof(WAVEHDR));
    waveOutWrite(hWaveOut2, &whdr2, sizeof(WAVEHDR));

    char str[128];
    std::cout << "hello, world\n";
    std::cin >> str;

 

デバイス0の出力