Repository: microsoft/terminal
File: src/audio/midi/MidiAudio.cpp (C++)

Code before:
        _initialize(windowHandle);
    }

    const auto& buffer = _buffers.at(_activeBufferIndex);
    if (velocity && buffer)
    {
        // The formula for frequency is 2^(n/12) * 440Hz, where n is zero for
        // the A above middle C (A4). In MIDI terms, A4 is note number 69,
        // which is why we subtract 69. We also need to multiply by the size
        // of the wave form to determine the frequency that the sound buffer
        // has to be played to achieve the equivalent note frequency.
        const auto frequency = std::pow(2.0, (noteNumber - 69.0) / 12.0) * 440.0 * WAVE_SIZE;
        buffer->SetFrequency(gsl::narrow_cast<DWORD>(frequency));
        // For the volume, we're using the formula defined in the General
        // MIDI Level 2 specification: Gain in dB = 40 * log10(v/127). We need
        // to multiply by 4000, though, because the SetVolume method expects
        // the volume to be in hundredths of a decibel.
        const auto volume = 4000.0 * std::log10(velocity / 127.0);
        buffer->SetVolume(gsl::narrow_cast<LONG>(volume));
        // Resetting the buffer to a position that is slightly off from the
        // last position will help to produce a clearer separation between
        // tones when repeating sequences of the same note.
        buffer->SetCurrentPosition((_lastBufferPosition + 12) % WAVE_SIZE);
    }

    // By waiting on the shutdown future with the duration of the note, we'll
    // either be paused for the appropriate amount of time, or we'll break out
    // of the wait early if we've been shutdown.
    _skip.wait(::base::saturated_cast<DWORD>(duration.count()));

    if (velocity && buffer)
    {
        // When the note ends, we just turn the volume down instead of stopping
        // the sound buffer. This helps reduce unwanted static between notes.
        buffer->SetVolume(DSBVOLUME_MIN);
        buffer->GetCurrentPosition(&_lastBufferPosition, nullptr);
    }

    // Cycling between multiple buffers can also help reduce the static.
    _activeBufferIndex = (_activeBufferIndex + 1) % _buffers.size();
}
CATCH_LOG()

void MidiAudio::_createBuffers() noexcept
{
    auto waveFormat = WAVEFORMATEX{};
    waveFormat.wFormatTag = WAVE_FORMAT_PCM;
    waveFormat.nChannels = 1;
    waveFormat.nSamplesPerSec = 8000;
    waveFormat.wBitsPerSample = 8;
    waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;

Review comment (suggestion):
Since we aren't using this exception anymore, we should get rid of the definition in [`statemachine.hpp`](https://github.com/microsoft/terminal/blob/f2b361c1463371ac2be681235470343ae48c23b5/src/terminal/parser/stateMachine.hpp#L71-L76), and the other bits of code associated with it that were added in PR #13208. There was a `catch` that was added to [`ControlCore::_connectionOutputHandler`](https://github.com/microsoft/terminal/blob/07201d6cd12870755efa7bb52e220b0b10102730/src/cascadia/TerminalControl/ControlCore.cpp#L1717-L1721) and another in  [`StateMachine::_SafeExecute`](https://github.com/microsoft/terminal/blob/f2b361c1463371ac2be681235470343ae48c23b5/src/terminal/parser/stateMachine.cpp#L2041-L2044). You may also need to add back a bunch of noexcepts in the `StateMachine` class if the audit complains.

Code after:
        _initialize(windowHandle);
    }

    const auto& buffer = _buffers.at(_activeBufferIndex);
    if (velocity && buffer)
    {
        // The formula for frequency is 2^(n/12) * 440Hz, where n is zero for
        // the A above middle C (A4). In MIDI terms, A4 is note number 69,
        // which is why we subtract 69. We also need to multiply by the size
        // of the wave form to determine the frequency that the sound buffer
        // has to be played to achieve the equivalent note frequency.
        const auto frequency = std::pow(2.0, (noteNumber - 69.0) / 12.0) * 440.0 * WAVE_SIZE;
        buffer->SetFrequency(gsl::narrow_cast<DWORD>(frequency));
        // For the volume, we're using the formula defined in the General
        // MIDI Level 2 specification: Gain in dB = 40 * log10(v/127). We need
        // to multiply by 4000, though, because the SetVolume method expects
        // the volume to be in hundredths of a decibel.
        const auto volume = 4000.0 * std::log10(velocity / 127.0);
        buffer->SetVolume(gsl::narrow_cast<LONG>(volume));
        // Resetting the buffer to a position that is slightly off from the
        // last position will help to produce a clearer separation between
        // tones when repeating sequences of the same note.
        buffer->SetCurrentPosition((_lastBufferPosition + 12) % WAVE_SIZE);
    }

    // By waiting on the skip event with a maximum duration of the note, we'll
    // either be paused for the appropriate amount of time, or we'll break out early
    // because BeginSkip() was called. This happens for Ctrl+C or during shutdown.
    _skip.wait(::base::saturated_cast<DWORD>(duration.count()));

    if (velocity && buffer)
    {
        // When the note ends, we just turn the volume down instead of stopping
        // the sound buffer. This helps reduce unwanted static between notes.
        buffer->SetVolume(DSBVOLUME_MIN);
        buffer->GetCurrentPosition(&_lastBufferPosition, nullptr);
    }

    // Cycling between multiple buffers can also help reduce the static.
    _activeBufferIndex = (_activeBufferIndex + 1) % _buffers.size();
}
CATCH_LOG()

void MidiAudio::_createBuffers() noexcept
{
    auto waveFormat = WAVEFORMATEX{};
    waveFormat.wFormatTag = WAVE_FORMAT_PCM;
    waveFormat.nChannels = 1;
    waveFormat.nSamplesPerSec = 8000;
    waveFormat.wBitsPerSample = 8;
    waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;