Изучение манипуляций со звуком в C++: подробное руководство

В этой статье блога мы углубимся в мир манипуляций со звуком с помощью C++. Мы рассмотрим различные методы и приемы работы со звуком, включая воспроизведение, запись, анализ и применение эффектов. К концу этого руководства вы получите четкое представление о том, как управлять звуком в проектах C++.

  1. Воспроизведение аудио:
    Для воспроизведения аудиофайлов на C++ вы можете использовать Windows API и функцию PlaySound из библиотеки MMSystem:
#include <Windows.h>
#include "MMSystem.h"
int main() {
    // Play a WAV file
    PlaySound(TEXT("sound.wav"), NULL, SND_FILENAME);

    return 0;
}
  1. Запись звука.
    Для записи звука на C++ вы можете использовать внешние библиотеки, такие как PortAudio или Windows API. Вот пример использования Windows API:
#include <Windows.h>
#include <iostream>
#include <fstream>
int main() {
    HWAVEIN hWaveIn;
    WAVEFORMATEX wfx;
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    wfx.nChannels = 2;
    wfx.nSamplesPerSec = 44100;
    wfx.nAvgBytesPerSec = 44100 * 2 * 16 / 8;
    wfx.nBlockAlign = 2 * 16 / 8;
    wfx.wBitsPerSample = 16;
    wfx.cbSize = 0;
    MMRESULT result = waveInOpen(&hWaveIn, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL);
    if (result != MMSYSERR_NOERROR) {
        std::cout << "Failed to open audio device." << std::endl;
        return -1;
    }
    const int bufferSize = 44100 * 2 * 16 / 8 * 5; // 5 seconds buffer
    char* buffer = new char[bufferSize];
    WAVEHDR waveHdr;
    waveHdr.lpData = buffer;
    waveHdr.dwBufferLength = bufferSize;
    waveHdr.dwBytesRecorded = 0;
    waveHdr.dwUser = 0;
    waveHdr.dwFlags = 0;
    waveHdr.dwLoops = 0;
    result = waveInPrepareHeader(hWaveIn, &waveHdr, sizeof(WAVEHDR));
    if (result != MMSYSERR_NOERROR) {
        std::cout << "Failed to prepare audio header." << std::endl;
        waveInClose(hWaveIn);
        return -1;
    }
    result = waveInAddBuffer(hWaveIn, &waveHdr, sizeof(WAVEHDR));
    if (result != MMSYSERR_NOERROR) {
        std::cout << "Failed to add audio buffer." << std::endl;
        waveInUnprepareHeader(hWaveIn, &waveHdr, sizeof(WAVEHDR));
        waveInClose(hWaveIn);
        return -1;
    }
    result = waveInStart(hWaveIn);
    if (result != MMSYSERR_NOERROR) {
        std::cout << "Failed to start audio recording." << std::endl;
        waveInUnprepareHeader(hWaveIn, &waveHdr, sizeof(WAVEHDR));
        waveInClose(hWaveIn);
        return -1;
    }
// Wait for recording to finish
    while (waveHdr.dwFlags & WHDR_STILLPLAYING) {
        Sleep(100);
    }
// Save recorded audio to file
    std::ofstream outputFile("recorded.wav", std::ios::binary);
    outputFile.write(buffer, waveHdr.dwBytesRecorded);
    outputFile.close();
    // Cleanup
    delete[] buffer;
    waveInUnprepareHeader(hWaveIn, &waveHdr, sizeof(WAVEHDR));
    waveInClose(hWaveIn);
    return 0;
}
  1. Применение аудиоэффектов.
    Вы можете применять различные аудиоэффекты, такие как эхо или реверберация, используя внешние библиотеки, такие как PortAudio, или манипулируя аудиосэмплами вручную. Вот пример применения простого эффекта эха:
#include <vector>
void applyEcho(std::vector<short>& samples, int delay, float decay) {
    std::vector<short> delayedSamples(samples.size() + delay);

    for (int i = 0; i < samples.size(); i++) {
        delayedSamples[i + delay] += samples[i];
        samples[i] += delayedSamples[i] * decay;
    }
}
int main() {
    // Load audio samples
    std::vector<short> samples;
    // Load samples from file or generate programmatically

    // Apply echo effect
applyEcho(samples, 44100, 0.5);
    // Play modified samples or save to file

    return 0;
}
4. Audio Analysis:
You can analyze audio data for various purposes, such as detecting beats or extracting audio features. Here's an example of calculating the average amplitude of an audio signal:
```cpp
#include <vector>
#include <cmath>

float calculateAverageAmplitude(const std::vector<short>& samples) {
    float sum = 0.0f;

    for (const auto& sample : samples) {
        sum += std::abs(sample);
    }

    return sum / samples.size();
}

int main() {
    // Load audio samples
    std::vector<short> samples;
    // Load samples from file or record

    // Calculate average amplitude
    float averageAmplitude = calculateAverageAmplitude(samples);

    // Use the average amplitude for further analysis or processing

    return 0;
}

В этой статье мы рассмотрели различные методы манипулирования звуком в C++. Мы рассмотрели воспроизведение и запись звука, применение эффектов и анализ аудиоданных. Используя эти методы, вы можете создавать мощные аудиоприложения и улучшать свои проекты с помощью звука. Экспериментируйте с различными подходами и библиотеками, чтобы открыть новые возможности в области манипуляции звуком с помощью C++.