int wmain(int argc, wchar_t *argv[])
{
    // _CrtSetBreakAlloc(35);
    // COM leak cannot be detected by debug heap manager ...
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

    HRESULT hr = S_OK;
    bool bCoInitialize = false;
    FILE *fpr = NULL;
    FILE *fpw = NULL;
    errno_t ercd;
    BYTE *buff = NULL;
    DWORD buffBytes = 0;
    DWORD readBytes = 0;
    DWORD remainBytes = 0;
    DWORD expectedOutputDataBytes = 0;
    DWORD result = 0;
    DWORD writeDataTotalBytes = 0;
    int conversionQuality = 60;
    WWMFResampler resampler;
    WWMFPcmFormat inputFormat;
    WWMFPcmFormat outputFormat;
    WWMFSampleData sampleData;

    if (argc != 6) {
        PrintUsage(argv[0]);
        return 1;
    }

    HRG(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE));
    bCoInitialize = true;

    ercd = _wfopen_s(&fpr, argv[1], L"rb");
    if (0 != ercd) {
        printf("file open error %S\n", argv[1]);
        PrintUsage(argv[0]);
        hr = E_FAIL;
        goto end;
    }

    ercd = _wfopen_s(&fpw, argv[2], L"wb");
    if (0 != ercd) {
        printf("file open error %S\n", argv[2]);
        PrintUsage(argv[0]);
        hr = E_FAIL;
        goto end;
    }

    HRG(ReadWavHeader(fpr, &inputFormat, &remainBytes));

    outputFormat = inputFormat;
    outputFormat.sampleRate = _wtoi(argv[3]);
    outputFormat.bits = (short)_wtoi(argv[4]);

    conversionQuality = _wtoi(argv[5]);

    if (0 == outputFormat.sampleRate ||
        0 == conversionQuality) {
        PrintUsage(argv[0]);
        hr = E_FAIL;
        goto end;
    }

    outputFormat.validBitsPerSample = outputFormat.bits;

    switch (outputFormat.bits) {
    case 16:
    case 24:
        outputFormat.sampleFormat = WWMFBitFormatInt;
        break;
    case 32:
        outputFormat.sampleFormat = WWMFBitFormatFloat;
        break;
    default:
        PrintUsage(argv[0]);
        hr = E_FAIL;
        goto end;
    }

    expectedOutputDataBytes = (int64_t)remainBytes
        * outputFormat.BytesPerSec()
        / inputFormat .BytesPerSec();

    HRG(WriteWavHeader(fpw, outputFormat, expectedOutputDataBytes));

    HRG(resampler.Initialize(inputFormat, outputFormat, conversionQuality));

    buffBytes = 128 * 1024 * inputFormat.FrameBytes();
    buff = new BYTE[buffBytes];

    for (;;) {
        // read PCM data from file
        readBytes = buffBytes;
        if (remainBytes < readBytes) {
            readBytes = remainBytes;
        }
        remainBytes -= readBytes;

        result = fread(buff, 1, readBytes, fpr);
        if (result != readBytes) {
            printf("file read error\n");
            hr = E_FAIL;
            goto end;
        }

        // convert
        HRG(resampler.Resample(buff, readBytes, &sampleData));

        // write to file
        result = fwrite(sampleData.data, 1, sampleData.bytes, fpw);
        if (result != sampleData.bytes) {
            printf("file write error\n");
            hr = E_FAIL;
            goto end;
        }
        writeDataTotalBytes += sampleData.bytes;
        sampleData.Release();

        if (remainBytes == 0) {
            // end
            HRG(resampler.Drain(buffBytes, &sampleData));

            // write remaining PCM data to file
            result = fwrite(sampleData.data, 1, sampleData.bytes, fpw);
            if (result != sampleData.bytes) {
                printf("file write error\n");
                hr = E_FAIL;
                goto end;
            }
            writeDataTotalBytes += sampleData.bytes;
            sampleData.Release();
            break;
        }
    }

    // data chunk align is 2 bytes
    if (writeDataTotalBytes & 1) {
        if (0 != fputc(0, fpw)) {
            printf("file write error\n");
            hr = E_FAIL;
            goto end;
        }
        ++writeDataTotalBytes;
    }
    HRG(FixWavHeader(fpw, writeDataTotalBytes));

    hr = S_OK;

end:
    resampler.Finalize();

    if (bCoInitialize) {
        CoUninitialize();
        bCoInitialize = false;
    }

    delete[] buff;
    buff = NULL;

    if (fpw != NULL) {
        fclose(fpw);
        fpw = NULL;
    }
    if (fpr != NULL) {
        fclose(fpr);
        fpr = NULL;
    }

    return SUCCEEDED(hr) ? 0 : 1;
}
Beispiel #2
0
int
main(int argc, char *argv[])
{
    HRESULT hr;

    if (argc != 2) {
        printf("Usage: %s readWavFile\n", argv[0]);
        return 1;
    }

    FILE *fpr = fopen(argv[1], "rb");
    if (NULL == fpr) {
        printf("read error %s\n", argv[1]);
        return 1;
    }

    WWMFPcmFormat fmt;
    DWORD remainBytes = 0;
    unsigned char *pUC = NULL;
    unsigned short *pUS = NULL;
    int readBytes = 0;
    int prevValue = INT_MAX;
    int prevPosition = INT_MAX;
    int *histogram16 = NULL;
    int *histogram24 = NULL;

    HRG(ReadWavHeader(fpr, &fmt, &remainBytes));
    pUC = new unsigned char[remainBytes];
    pUS = (unsigned short *)pUC;

    readBytes = fread(pUC, 1, remainBytes, fpr);
    if (readBytes != remainBytes) {
        printf("read error\n");
        hr = E_FAIL;
        goto end;
    }
    int totalSamples = readBytes/(fmt.bits/8);

    switch (fmt.bits) {
    case 16:
        histogram16 = new int[65536];
        memset(histogram16, 0, 65536*4);
        for (int i=0; i<remainBytes/2; ++i) {
            ++histogram16[pUS[i]];
        }
        prevPosition = 32767;
        for (int i=32768; i<65536; ++i) {
            if (prevValue == histogram16[i]) {
                continue;
            }
            if (prevPosition != i-1) {
                printf("%d %d %f\n", i-1-65536, prevValue, (double)prevValue / totalSamples);
            }
            prevValue = histogram16[i];
            prevPosition = i;
            printf("%d %d %f\n", i-65536, histogram16[i], (double)histogram16[i] / totalSamples);
        }
        prevPosition -= 65536;
        for (int i=0; i<32768; ++i) {
            if (prevValue == histogram16[i]) {
                continue;
            }
            if (prevPosition != i-1) {
                printf("%d %d %f\n", i-1, prevValue, (double)prevValue / totalSamples);
            }
            prevValue = histogram16[i];
            prevPosition = i;
            printf("%d %d %f\n", i, histogram16[i], (double)histogram16[i] / totalSamples);
        }
        break;
    case 24:
        histogram24 = new int[16777216];
        memset(histogram24, 0, 16777216*4);
        for (int i=0; i<remainBytes/3; ++i) {
            unsigned int v = pUC[i*3] + 256*pUC[i*3+1] + 65536*pUC[i*3+2];
            ++histogram24[v];
        }
        prevPosition = 8388607;
        for (int i=8388608; i<16777216; ++i) {
            if (abs(prevValue - histogram24[i]) < 1) {
                continue;
            }
            if (prevPosition != i-1) {
                printf("%12d %12d %f\n", i-1-16777216, prevValue, (double)prevValue / totalSamples);
            }
            prevValue = histogram24[i];
            prevPosition = i;
            printf("%12d %12d %f\n", i-16777216, histogram24[i], (double)histogram24[i] / totalSamples);
        }
        for (int i=0; i<8388608; ++i) {
            if (abs(prevValue - histogram24[i]) < 1) {
                continue;
            }
            if (prevPosition != i-1) {
                printf("%12d %12d %f\n", i-1, prevValue, (double)prevValue / totalSamples);
            }
            prevValue = histogram24[i];
            prevPosition = i;
            printf("%12d %12d %f\n", i, histogram24[i], (double)histogram24[i] / totalSamples);
        }
        break;
    default:
        printf("fmt.bits is not 16 nor 24\n");
        break;
    }

end:
    fclose(fpr);
    fpr = NULL;

    delete [] histogram16;
    histogram16 = NULL;

    delete [] histogram24;
    histogram24 = NULL;

    delete [] pUC;
    pUC = NULL;

    pUS = NULL;

    return hr == S_OK ? 0 : 1;
}