Перенаправление stdio "не удается" при вызове waveInOpen, почему? - PullRequest
0 голосов
/ 17 января 2019

Вот моя основная программа, она должна довольно легко компилироваться с VisualStudio (даже экспресс).

// ConsoleApplication1.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <mmsystem.h>
#include <stdint.h>

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

HWAVEIN hWaveIn;
WAVEFORMATEX WaveFormat;
WAVEHDR WaveHeader;

typedef union
{
    uint32_t u32;
    struct 
    {
        int16_t iLeft;
        int16_t iRight;
    };
}   audiosample16_t;

#define AUDIORATE (44100*4)
#define SECONDS   (13)

audiosample16_t MyBuffer[AUDIORATE*SECONDS];

int _tmain(int argc, _TCHAR* argv[])
{
    std::cout << "Hello World!\n"; 

    UINT WaveId = 0;
    WaveFormat.wFormatTag = WAVE_FORMAT_PCM; // simple, uncompressed format
    WaveFormat.nChannels = 2; // 1=mono, 2=stereo
    WaveFormat.nSamplesPerSec = 44100; 
    WaveFormat.wBitsPerSample = 16; // 16 for high quality, 8 for telephone-grade
    WaveFormat.nBlockAlign = WaveFormat.nChannels*WaveFormat.wBitsPerSample/8; 
    WaveFormat.nAvgBytesPerSec = (WaveFormat.nSamplesPerSec)*(WaveFormat.nChannels)*(WaveFormat.wBitsPerSample)/8; 
    WaveFormat.cbSize=0;

    WaveHeader.lpData = (LPSTR)MyBuffer;
    WaveHeader.dwBufferLength = sizeof(MyBuffer);
    WaveHeader.dwFlags = 0;

    std::cout << "Hello World!\n"; 
    //std::cout << std::flush;
    HRESULT hr;
    if(argc>1)
        hr= waveInOpen(&hWaveIn,WaveId,&WaveFormat,0,0,CALLBACK_NULL);
    std::cout << "Hello World!\n"; 
    std::cout << "Hello World!\n"; 
    //std::cout << std::flush;
    return 0;
}

Если вы вызываете его из командной строки без аргументов, все выводится нормально (несколько «Hello World!»). Если вы перенаправите это в файл (myprog.exe > blah.txt), снова все будет работать нормально и несколько строк «Hello World!» в конечном итоге в файле, как ожидалось.

ОДНАКО, если у вас есть аргумент (так что вызывается waveInOpen), он ничего не будет перенаправлять в файл. Файл пуст. Если вы не перенаправите вывод, он будет просто распечатан в командную строку.

Если вы не раскомментируете строки std :: flush, тогда файл не пуст и все работает нормально.

Что, черт возьми, происходит под капотом, что вызывает это? Разве stdout не должен быть очищен при выходе и передан в файл, несмотря ни на что? Что за вызов waveInOpen() делает так, чтобы буферизовать stdio таким образом?

FWIW, это выяснилось, потому что мы вызываем эту программу из TCL и Python для измерения качества звука на подключенном продукте, и ничего не читалось обратно, даже если он будет распечатываться нормально при запуске из командной строки ( и не перенаправляется).

...