소리 추가Add sound

이 항목에서는 간단한 사운드 엔진을 만듭니다 XAudio2 Api.In this topic, we create a simple sound engine using XAudio2 APIs. 처음 사용 하는 경우 XAudio2, 아래 짧은 소개 포함 했습니다 오디오 개념합니다.If you are new to XAudio2, we have included a short intro under Audio concepts.

참고

이 샘플의 최신 게임 코드를 다운로드하지 않은 경우 Direct3D 게임 샘플로 이동합니다.If you haven't downloaded the latest game code for this sample, go to Direct3D game sample. 이 샘플은 UWP 기능 샘플의 큰 컬렉션의 일부입니다.This sample is part of a large collection of UWP feature samples. 샘플을 다운로드하는 방법에 대한 지침은 GitHub에서 UWP 샘플 가져오기를 참조하세요.For instructions on how to download the sample, see Get the UWP samples from GitHub.

목표Objective

사용 하 여 샘플 게임에 사운드를 추가 XAudio2합니다.Add sounds into the sample game using XAudio2.

오디오 엔진 정의Define the audio engine

게임 샘플에서 오디오 개체와 동작은 다음 세 개의 파일에 정의됩니다.In the game sample, the audio objects and behaviors are defined in three files:

  • Audio.h/.cpp: 정의 오디오 포함 된 개체를 XAudio2 소리 재생에 대 한 리소스입니다.Audio.h/.cpp: Defines the Audio object, which contains the XAudio2 resources for sound playback. 또한 게임이 일시 중지되거나 비활성화된 경우 오디오 재생을 일시 중단하고 다시 시작하는 메서드를 정의합니다.It also defines the method for suspending and resuming audio playback if the game is paused or deactivated.
  • MediaReader.h/.cpp: 로컬 저장소에서 오디오.wav 파일을 읽기 위한 메서드를 정의 합니다.MediaReader.h/.cpp: Defines the methods for reading audio .wav files from local storage.
  • SoundEffect.h/.cpp: 게임에서 소리 재생을 위한 개체를 정의합니다.SoundEffect.h/.cpp: Defines an object for in-game sound playback.

개요Overview

게임에 오디오 재생에 대 한 설정의 세 가지 주요 부분이 있습니다.There are three main parts in getting set up for audio playback into your game.

  1. 만들기 및 오디오 리소스를 초기화 합니다.Create and initialize the audio resources
  2. 오디오 파일 로드Load audio file
  3. 개체는 소리를 연결 합니다.Associate sound to object

모두에 정의 된 Simple3DGame::Initialize 메서드.They are all defined in the Simple3DGame::Initialize method. 그럼 먼저이 메서드를 검사 하 고 다음의 각 섹션에서 자세한 세부 정보에 자세히 알아보기.So let's first examine this method and then dive into more details in each of the sections.

를 설정한 후 재생할 소리 효과 트리거하는 방법을 설명 합니다.After setting up, we learn how to trigger the sound effects to play. 자세한 내용은 이동 소리를 재생합니다.For more info, go to Play the sound.

Simple3DGame::Initialize 메서드Simple3DGame::Initialize method

__Simple3DGame::Initialize__여기서 m_컨트롤러 하 고 m_렌더러 는 또한 초기화 오디오 엔진을 설정 하 고 가져오기 소리를 재생할 준비가 되었습니다.In Simple3DGame::Initialize, where m_controller and m_renderer are also initialized, we set up the audio engine and get it ready to play sounds.

  • 만들 __m_audioController__의 인스턴스인 합니다 오디오 클래스입니다.Create m_audioController, which is an instance of the Audio class.
  • 사용 하 여 필요한 오디오 리소스를 만들려고 합니다 Audio::CreateDeviceIndependentResources 메서드.Create the audio resources needed using the Audio::CreateDeviceIndependentResources method. 여기, 두 XAudio2 개체 — 음악 엔진 개체 및 사운드 엔진 개체 및 각각에 대해 마스터 음성 생성 되었습니다.Here, two XAudio2 objects — a music engine object and a sound engine object, and a mastering voice for each of them were created. 음악 엔진 개체 게임에 대 한 배경 음악을 재생 하는 데 사용할 수 있습니다.The music engine object can be used to play background music for your game. 사운드 엔진 게임에서 음향 효과 재생 하는 데 사용할 수 있습니다.The sound engine can be used to play sound effects in your game. 자세한 내용은 참조 하세요. 만들기 및 오디오 리소스 초기화합니다.For more info, see Create and initialize the audio resources.
  • 만들 __mediaReader__의 인스턴스인 MediaReader 클래스입니다.Create mediaReader, which is an instance of MediaReader class. MediaReader에 대 한 도우미 클래스인 합니다 SoundEffect 클래스 읽기 작은 오디오 파일 위치에서 파일을 동기적으로 및 사운드 데이터를 바이트 배열로 반환 합니다.MediaReader, which is a helper class for the SoundEffect class, reads small audio files synchronously from file location and returns sound data as a byte array.
  • 사용 하 여 MediaReader::LoadMedia 사운드 파일을 해당 위치에서 로드 한를 targetHitSound 로드할된.wav 사운드 데이터를 보유할 변수로 대체 합니다.Use MediaReader::LoadMedia to load sound files from its location and create a targetHitSound variable to hold the loaded .wav sound data. 자세한 내용은 참조 하세요. 오디오 파일 로드합니다.For more info, see Load audio file.

음향 효과 게임 개체와 연결 됩니다.Sound effects are associated with the game object. 따라서 해당 게임 개체를 사용 하 여 충돌이 발생 하면 재생할 소리 효과를 트리거합니다.So when a collision occurs with that game object, it triggers the sound effect to be played. 이 게임 샘플에서는 음향 효과 (어떤를 사용 하 여 대상을 사용 하 여 문제를 해결) 탄약 및 대상 했습니다.In this game sample, we have sound effects for the ammo (what we use to shoot targets with) and for the target.

  • GameObject 클래스, 즉를 HitSound 소리 효과 개체에 연결 하는 데 사용 되는 속성입니다.In the GameObject class, there's a HitSound property that is used to associate the sound effect to the object.
  • 새 인스턴스를 만들고 합니다 SoundEffect 클래스 및 초기화 합니다.Create a new instance of the SoundEffect class and initialize it. 초기화 하는 동안 소리 효과 대 한 원본 음성을 생성 됩니다.During initialization, a source voice for the sound effect is created.
  • 이 클래스에서 제공 하는 마스터 음성을 사용 하 여 소리를 재생 합니다 오디오 클래스입니다.This class plays a sound using a mastering voice provided from the Audio class. 사운드 데이터를 사용 하 여 파일 위치에서 읽기를 MediaReader 클래스입니다.Sound data is read from file location using the MediaReader class. 자세한 내용은 참조 하세요. 개체는 소리 연결합니다.For more info, see Associate sound to object.

참고

소리를 재생 하려면 실제 트리거 이동 및 이러한 게임 개체의 충돌에 의해 결정 됩니다.The actual trigger to play the sound is determined by the movement and collision of these game objects. 따라서 실제로 이러한 소리를 재생에 대 한 호출에 정의 된 Simple3DGame::UpdateDynamics 메서드.Hence, the call to actually play these sounds are defined in the Simple3DGame::UpdateDynamics method. 자세한 내용은 이동 소리를 재생합니다.For more info, go to Play the sound.

void Simple3DGame::Initialize(
    _In_ MoveLookController^ controller,
    _In_ GameRenderer^ renderer
    )
{
    // ...
    // Create a new Audio class object.
    m_audioController = ref new Audio;

    // Create the audio resources needed.
    // Two XAudio2 objects are created - one for music engine,
    // the other for sound engine. A mastering voice is also
    // created for each of the objects.
    m_audioController->CreateDeviceIndependentResources();

    m_ammo = std::vector<Sphere^>(GameConstants::MaxAmmo);

    // ..
    // Create a media reader which is used to read audio files from its file location.
    MediaReader^ mediaReader = ref new MediaReader;
    auto targetHitSound = mediaReader->LoadMedia("Assets\\hit.wav");

    // Instantiate the targets for use in the game.
    // Each target has a different initial position, size, and orientation.
    // But share a common set of material properties.
    for (int a = 1; a < GameConstants::MaxTargets; a++)
    {
        // ...
        // Create a new sound effect object and associate it
        // with the game object's (target) HitSound property.
        target->HitSound(ref new SoundEffect());

        // Initialize the sound effect object with
        // the sound effect engine, format of the audio wave, and audio data
        // During initialization, source voice of this sound effect is also created.
        target->HitSound()->Initialize(
            m_audioController->SoundEffectEngine(),
            mediaReader->GetOutputWaveFormatEx(),
            targetHitSound
            );
        // ...
    }

    // Instantiate a set of spheres to be used as ammunition for the game
    // and set the material properties of the spheres.
    auto ammoHitSound = mediaReader->LoadMedia("Assets\\bounce.wav");

    for (int a = 0; a < GameConstants::MaxAmmo; a++)
    {
        m_ammo[a] = ref new Sphere;
        m_ammo[a]->Radius(GameConstants::AmmoRadius);
        m_ammo[a]->HitSound(ref new SoundEffect());
        m_ammo[a]->HitSound()->Initialize(
            m_audioController->SoundEffectEngine(),
            mediaReader->GetOutputWaveFormatEx(),
            ammoHitSound
            );
        m_ammo[a]->Active(false);
        m_renderObjects.push_back(m_ammo[a]);
    }
    // ...
}

만들기 및 오디오 리소스를 초기화 합니다.Create and initialize the audio resources

  • 사용 하 여 XAudio2Create, XAudio2 API 음악 및 소리 효과 엔진을 정의 하는 두 새 XAudio2 개체를 만듭니다.Use XAudio2Create, an XAudio2 API, to create two new XAudio2 objects which define the music and sound effect engines. 이 메서드는 개체에 대 한 포인터를 반환 IXAudio2 모든 오디오 엔진을 관리 하는 인터페이스 상태, 오디오, 스레드, 음성 그래프 등을 처리 합니다.This method returns a pointer to the object's IXAudio2 interface that manages all audio engine states, the audio processing thread, the voice graph, and more.
  • 엔진에서 인스턴스화된 후 사용 하 여 IXAudio2::CreateMasteringVoice 각 사운드 엔진 개체에 대 한 마스터 음성을 만들려고 합니다.After the engines have been instantiated, use IXAudio2::CreateMasteringVoice to create a mastering voice for each of the sound engine objects.

자세한 내용은 이동 방법: XAudio2 초기화합니다.For more info, go to How to: Initialize XAudio2.

Audio::CreateDeviceIndependentResources 메서드Audio::CreateDeviceIndependentResources method


void Audio::CreateDeviceIndependentResources()
{
    UINT32 flags = 0;

    DX::ThrowIfFailed(
        XAudio2Create(&m_musicEngine, flags)
        );

    HRESULT hr = m_musicEngine->CreateMasteringVoice(&m_musicMasteringVoice);
    if (FAILED(hr))
    {
        // Unable to create an audio device
        m_audioAvailable = false;
        return;
    }

    DX::ThrowIfFailed(
        XAudio2Create(&m_soundEffectEngine, flags)
        );

    DX::ThrowIfFailed(
        m_soundEffectEngine->CreateMasteringVoice(&m_soundEffectMasteringVoice)
        );

    m_audioAvailable = true;
}

오디오 파일 로드Load audio file

게임 샘플에 오디오 형식 파일을 읽기 위한 코드 정의 MediaReader.h/cpp__ 합니다.In the game sample, the code for reading audio format files is defined in MediaReader.h/cpp__. 호출로 인코딩된.wav 오디오 파일을 읽으려면 MediaReader::LoadMedia의 입력된 매개 변수로.wav 파일 이름을 전달 합니다.To read an encoded .wav audio file, call MediaReader::LoadMedia, passing in the filename of the .wav as the input parameter.

MediaReader::LoadMedia 메서드MediaReader::LoadMedia method

이 메서드는 Media Foundation API를 사용하여 .wav 오디오 파일을 PCM(Pulse Code Modulation) 버퍼로 읽습니다.This method uses the Media Foundation APIs to read in the .wav audio file as a Pulse Code Modulation (PCM) buffer.

원본 판독기 설정Set up the Source Reader

  1. 사용 하 여 MFCreateSourceReaderFromURL 미디어 원본 판독기를 만들려면 (IMFSourceReader).Use MFCreateSourceReaderFromURL to create a media source reader (IMFSourceReader).
  2. 사용 하 여 MFCreateMediaType 미디어 형식을 만들려면 (IMFMediaType) 개체 (mediaType).Use MFCreateMediaType to create a media type (IMFMediaType) object (mediaType). 미디어 형식에 대 한 설명을 나타냅니다.It represents a description of a media format.
  3. 지정 합니다 _mediaType_의 디코딩된 출력은 오디오 PCM 오디오를 입력 하는 XAudio2 사용할 수 있습니다.Specify that the mediaType's decoded output is PCM audio, which is an audio type that XAudio2 can use.
  4. 호출 하 여 원본 판독기에 대 한 디코딩된 출력 미디어 유형 집합 IMFSourceReader::SetCurrentMediaType합니다.Sets the decoded output media type for the source reader by calling IMFSourceReader::SetCurrentMediaType.

에 대 한 자세한 내용은 원본 판독기를 사용 하는 이유,로 이동 원본 판독기합니다.For more info on why we use the Source Reader, go to Source Reader.

데이터 형식의 오디오 스트림 설명Describe the data format of the audio stream

  1. 사용 하 여 IMFSourceReader::GetCurrentMediaType 스트림에 대 한 현재 미디어 형식을 가져오려고 합니다.Use IMFSourceReader::GetCurrentMediaType to get the current media type for the stream.
  2. 사용 하 여 IMFMediaType::MFCreateWaveFormatExFromMFMediaType 변환할 현재 오디오 미디어 유형입니다는 WAVEFORMATEX 버퍼를 입력으로 이전 작업의 결과 사용 합니다.Use IMFMediaType::MFCreateWaveFormatExFromMFMediaType to convert the current audio media type to a WAVEFORMATEX buffer, using the results of the earlier operation as input. 이 구조는 웨이브 오디오 스트림을 오디오 로드 된 후에 사용 되는 데이터 형식을 지정 합니다.This structure specifies the data format of the wave audio stream that is used after audio is loaded.

합니다 WAVEFORMATEX 형식은 PCM 버퍼를 설명 하기 위해 사용할 수 있습니다.The WAVEFORMATEX format can be used to describe the PCM buffer. 비교 했을 때를 WAVEFORMATEXTENSIBLE 구조를 사용할 수 있습니다만 오디오 wave 형식의 하위 집합을 설명 합니다.As compared to the WAVEFORMATEXTENSIBLE structure, it can only be used to describe a subset of audio wave formats. 간의 차이점에 대 한 자세한 내용은 WAVEFORMATEX 및 __WAVEFORMATEXTENSIBLE__를 참조 하십시오 확장할 수 있는 웨이브 형식 설명자합니다.For more info about the differences between WAVEFORMATEX and WAVEFORMATEXTENSIBLE, see Extensible Wave-Format Descriptors.

오디오 스트림에서 읽기Read the audio stream

  1. 가져오기는 기간 (초)를 호출 하 여 오디오 스트림의 IMFSourceReader::GetPresentationAttribute 바이트를 지속 시간을 변환 합니다.Get the duration, in seconds, of the audio stream by calling IMFSourceReader::GetPresentationAttribute and then converts the duration to bytes.
  2. 오디오 파일을 호출 하 여 스트림으로 읽는 IMFSourceReader::ReadSample합니다.Read the audio file in as a stream by calling IMFSourceReader::ReadSample. ReadSample 미디어 소스에서 다음 샘플을 읽습니다.ReadSample reads the next sample from the media source.
  3. 사용 하 여 IMFSample::ConvertToContiguousBuffer 오디오 샘플 버퍼의 내용을 복사할 (샘플)을 배열로 (mediaBuffer).Use IMFSample::ConvertToContiguousBuffer to copy contents of the audio sample buffer (sample) into an array (mediaBuffer).
Platform::Array<byte>^ MediaReader::LoadMedia(_In_ Platform::String^ filename)
{
    DX::ThrowIfFailed(
        MFStartup(MF_VERSION)
        );

    // Creates a media source reader.
    ComPtr<IMFSourceReader> reader;
    DX::ThrowIfFailed(
        MFCreateSourceReaderFromURL(
            Platform::String::Concat(m_installedLocationPath, filename)->Data(),
            nullptr,
            &reader
            )
        );

    // Set the decoded output format as PCM.
    // XAudio2 on Windows can process PCM and ADPCM-encoded buffers.
    // When using MediaFoundation, this sample always decodes into PCM.
    Microsoft::WRL::ComPtr<IMFMediaType> mediaType;
    DX::ThrowIfFailed(
        MFCreateMediaType(&mediaType)
        );

    // Define the major category of the media as audio. For more info about major media types,
    // go to: https://msdn.microsoft.com/library/windows/desktop/aa367377.aspx
    DX::ThrowIfFailed(
        mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio)
        );

    // Define the sub-type of the media as uncompressed PCM audio. For more info about audio sub-types,
    // go to: https://msdn.microsoft.com/library/windows/desktop/aa372553.aspx
    DX::ThrowIfFailed(
        mediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM)
        );
    
    // Sets the media type for a stream. This media type defines that format that the Source Reader 
    // produces as output. It can differ from the native format provided by the media source.
    // For more info, go to https://msdn.microsoft.com/library/windows/desktop/dd374667.aspx
    DX::ThrowIfFailed(
        reader->SetCurrentMediaType(static_cast<uint32>(MF_SOURCE_READER_FIRST_AUDIO_STREAM), 0, mediaType.Get())
        );

    // Get the current media type for the stream.
    // For more info, go to:
    // https://msdn.microsoft.com/library/windows/desktop/dd374660.aspx
        Microsoft::WRL::ComPtr<IMFMediaType> outputMediaType;
    DX::ThrowIfFailed(
        reader->GetCurrentMediaType(static_cast<uint32>(MF_SOURCE_READER_FIRST_AUDIO_STREAM), &outputMediaType)
        );

    // Converts the current media type into the WaveFormatEx buffer structure.
    UINT32 size = 0;
    WAVEFORMATEX* waveFormat;
    DX::ThrowIfFailed(
        MFCreateWaveFormatExFromMFMediaType(outputMediaType.Get(), &waveFormat, &size)
        );

    // Copies the waveFormat's block of memory to the starting address of the m_waveFormat variable in MediaReader.
    // Then free the waveFormat memory block.
    // For more info, go to https://msdn.microsoft.com/library/windows/desktop/aa366535.aspx and
    // https://msdn.microsoft.com/library/windows/desktop/ms680722.aspx
    CopyMemory(&m_waveFormat, waveFormat, sizeof(m_waveFormat));
    CoTaskMemFree(waveFormat);

    PROPVARIANT propVariant;
    DX::ThrowIfFailed(
        reader->GetPresentationAttribute(static_cast<uint32>(MF_SOURCE_READER_MEDIASOURCE), MF_PD_DURATION, &propVariant)
        );

    // 'duration' is in 100ns units; convert to seconds, and round up
    // to the nearest whole byte.
    LONGLONG duration = propVariant.uhVal.QuadPart;
    unsigned int maxStreamLengthInBytes =
        static_cast<unsigned int>(
            ((duration * static_cast<ULONGLONG>(m_waveFormat.nAvgBytesPerSec)) + 10000000) /
            10000000
            );

    Platform::Array<byte>^ fileData = ref new Platform::Array<byte>(maxStreamLengthInBytes);

    ComPtr<IMFSample> sample;
    ComPtr<IMFMediaBuffer> mediaBuffer;
    DWORD flags = 0;

    int positionInData = 0;
    bool done = false;
    while (!done)
    {
        //...
        // Read audio data.
    }

    return fileData;
}

개체는 소리를 연결 합니다.Associate sound to object

게임 초기화 때 발생 하는 개체에 소리를 연결 합니다 Simple3DGame::Initialize 메서드.Associating sounds to the object takes place when the game initializes, in the Simple3DGame::Initialize method.

요약:Recap:

  • GameObject 클래스, 즉를 HitSound 소리 효과 개체에 연결 하는 데 사용 되는 속성입니다.In the GameObject class, there's a HitSound property that is used to associate the sound effect to the object.
  • 새 인스턴스를 만들고 합니다 SoundEffect 개체 클래스 및 게임 개체와 연결 합니다.Create a new instance of the SoundEffect class object and associate it with the game object. 이 클래스를 사용 하는 사운드 재생 XAudio2 Api.This class plays a sound using XAudio2 APIs. 제공한 마스터 음성을 사용 합니다 오디오 클래스입니다.It uses a mastering voice provided by the Audio class. 사운드 데이터를 사용 하 여 파일 위치에서 읽을 수 있습니다 합니다 MediaReader 클래스입니다.The sound data can be read from file location using the MediaReader class.

SoundEffect::Initialize 초기화 하는 데 사용 되는 SoundEffect 다음 입력된 매개 변수를 사용 하 여 인스턴스: 사운드 엔진 개체에 대 한 포인터 (IXAudio2 개체에서 만든는 오디오: CreateDeviceIndependentResources 메서드), 형식에 대 한 포인터 사용 하 여.wav 파일 __MediaReader::GetOutputWaveFormatEx__를 사용 하 여 사운드 데이터 로드 및 MediaReader::LoadMedia 메서드.SoundEffect::Initialize is used to initalize the SoundEffect instance with the following input parameters: pointer to sound engine object (IXAudio2 objects created in the Audio::CreateDeviceIndependentResources method), pointer to format of the .wav file using MediaReader::GetOutputWaveFormatEx, and the sound data loaded using MediaReader::LoadMedia method. 초기화 하는 동안 소리 효과 대 한 원본 음성도 생성 됩니다.During initialization, the source voice for the sound effect is also created.

SoundEffect::Initialize 메서드SoundEffect::Initialize method

void SoundEffect::Initialize(
    _In_ IXAudio2 *masteringEngine,
    _In_ WAVEFORMATEX *sourceFormat,
    _In_ Platform::Array<byte>^ soundData)
{
    m_soundData = soundData;

    if (masteringEngine == nullptr)
    {
        // Audio is not available so just return.
        m_audioAvailable = false;
        return;
    }

    // Create a source voice for this sound effect.
    DX::ThrowIfFailed(
        masteringEngine->CreateSourceVoice(
            &m_sourceVoice,
            sourceFormat
            )
        );
    m_audioAvailable = true;
}

소리 재생Play the sound

에 음향 효과 재생 하려면 트리거가 정의 Simple3DGame::UpdateDynamics 메서드는 개체의 이동 업데이트 되 고 개체 간의 충돌 이기 때문에 결정 됩니다.Triggers to play sound effects are defined in Simple3DGame::UpdateDynamics method because this is where movement of the objects are updated and collision between objects is determined.

게임을 따라 크게 달라 집니다 개체 간의 상호 작용 하므로 여기 게임 개체의 동적 특성을 설명 하지 않습니다.Since interaction of between objects differs greatly, depending on the game, we are not going to discuss the dynamics of the game objects here. 로 이동 하는 구현 방식을 이해 하려면 싶다면 Simple3DGame::UpdateDynamics 메서드.If you're interested to understand its implementation, go to Simple3DGame::UpdateDynamics method.

원칙적으로 충돌이 발생 하는 경우 해당 트리거를 호출 하 여 재생할 소리 효과 SoundEffect::PlaySound합니다.In principle, when a collision occurs, it triggers the sound effect to play by calling SoundEffect::PlaySound. 이 메서드는 현재 재생 중인 소리 원하는 데이터를 사용 하 여 메모리 내 버퍼를 큐에 모든 음향 효과 중지 합니다.This method stops any sound effects that's currently playing and queues the in-memory buffer with the desired sound data. 원본 음성 사용 하 여 볼륨 설정, 사운드 데이터 전송 및 재생을 시작 합니다.It uses source voice to set the volume, submit sound data, and start the playback.

SoundEffect::PlaySound 메서드SoundEffect::PlaySound method

  • 원본 음성 개체를 사용 하 여 m_sourceVoice 사운드 데이터 버퍼의 재생을 시작 하 m_soundDataUses the source voice object m_sourceVoice to start the playback of the sound data buffer m_soundData
  • 만듭니다는 XAUDIO2_버퍼하는 사운드 데이터 버퍼에 대 한 참조를 제공 하 고 다음에 대 한 호출을 사용 하 여 전송 IXAudio2SourceVoice::SubmitSourceBuffer합니다.Creates an XAUDIO2_BUFFER, to which it provides a reference to the sound data buffer, and then submits it with a call to IXAudio2SourceVoice::SubmitSourceBuffer.
  • 사운드 데이터로 대기 SoundEffect::PlaySound 시작 호출 하 여 재생 IXAudio2SourceVoice::Start합니다.With the sound data queued up, SoundEffect::PlaySound starts play back by calling IXAudio2SourceVoice::Start.
void SoundEffect::PlaySound(_In_ float volume)
{
    XAUDIO2_BUFFER buffer = {0};
    XAUDIO2_VOICE_STATE state = {0};

    if (!m_audioAvailable)
    {
        // Audio is not available, so just return.
        return;
    }

    // Interrupt sound effect if currently playing.
    DX::ThrowIfFailed(
        m_sourceVoice->Stop()
        );
    DX::ThrowIfFailed(
        m_sourceVoice->FlushSourceBuffers()
        );

    // Queue in-memory buffer for playback and start the voice.
    buffer.AudioBytes = m_soundData->Length;
    buffer.pAudioData = m_soundData->Data;
    buffer.Flags = XAUDIO2_END_OF_STREAM;

    m_sourceVoice->SetVolume(volume);
    DX::ThrowIfFailed(
        m_sourceVoice->SubmitSourceBuffer(&buffer)
        );
    DX::ThrowIfFailed(
        m_sourceVoice->Start()
        );
}

Simple3DGame::UpdateDynamics 메서드Simple3DGame::UpdateDynamics method

합니다 Simple3DGame::UpdateDynamics 메서드는 상호 작용 및 게임 개체 간의 충돌 담당 합니다.The Simple3DGame::UpdateDynamics method takes care the interaction and collision between game objects. 개체 충돌, 교차 하는 경우 재생 하려면 연결 된 소리 효과를 트리거합니다.When objects collide (or intersect), it triggers the associated sound effect to play.

void Simple3DGame::UpdateDynamics()
{
    // ...
    // Check for collisions between ammo.
#pragma region inter-ammo collision detection
    if (m_ammoCount > 1)
    {
       // ...
       // Check collision between instances One and Two.
       // ...
       if (distanceSquared < (GameConstants::AmmoSize * GameConstants::AmmoSize))
       {
           // The two ammo are intersecting.
           // ...
           // Start playing the sounds for the impact between the two balls.
              m_ammo[one]->PlaySound(impact, m_player->Position());
              m_ammo[two]->PlaySound(impact, m_player->Position());

       }
    }
#pragma endregion

#pragma region Ammo-Object intersections
    // Check for intersections between the ammo and the other objects in the scene.
    // ...
    // Ball is in contact with Object.
    // ...

    // Make sure that the ball is actually headed towards the object. At grazing angles there
    // could appear to be an impact when the ball is actually already hit and moving away.
    if (impact > 0.0f)
    {
        // ...
        // Play the sound associated with the Ammo hitting something.
           m_ammo[one]->PlaySound(impact, m_player->Position());

        if (m_objects[i]->Target() && !m_objects[i]->Hit())
        {
            // The object is a target and isn't currently hit, so mark it as hit and
            // play the sound associated with the impact.
             m_objects[i]->Hit(true);
             m_objects[i]->HitTime(timeTotal);
             m_totalHits++;

             m_objects[i]->PlaySound(impact, m_player->Position());
        }
        // ...
    }
#pragma endregion

#pragma region Apply Gravity and world intersection
    // Apply gravity and check for collision against enclosing volume.
    // ...
    if (position.z < limit)
    {
        // The ammo instance hit the a wall in the min Z direction.
        // Align the ammo instance to the wall, invert the Z component of the velocity and
        // play the impact sound.
           position.z = limit;
           m_ammo[i]->PlaySound(-velocity.z, m_player->Position());
           velocity.z = -velocity.z * GameConstants::Physics::GroundRestitution;
    }
    // ...
#pragma endregion
}

다음 단계Next steps

UWP 프레임 워크, 그래픽, 컨트롤, 사용자 인터페이스 및 Windows 10 게임의 오디오 설명 했습니다.We have covered the UWP framework, graphics, controls, user interface, and audio of a Windows 10 game. 이 자습서의 다음 부분 게임 샘플 확장, 게임을 개발할 때 사용할 수 있는 다른 옵션을 설명 합니다.The next part of this tutorial, Extending the game sample, explains other options that can be used when developing a game.

오디오 개념Audio concepts

Windows 10 게임 개발을 위한 XAudio2 버전 2.9를 사용 합니다.For Windows 10 games development, use XAudio2 version 2.9. 이 버전은 Windows 10과 함께 제공 됩니다.This version is shipped with Windows 10. 자세한 내용은 이동 XAudio2 버전합니다.For more info, go to XAudio2 Versions.

AudioX2 는 신호 처리 및 foundation 혼합 제공 하는 하위 수준 API.AudioX2 is a low-level API that provides signal processing and mixing foundation. 자세한 내용은 참조 하세요. XAudio2 주요 개념합니다.For more info, see XAudio2 Key Concepts.

XAudio2 음성XAudio2 voices

XAudio2 음성 개체의 세 가지 종류가 있습니다: 원본를 및 음성을 마스터 합니다.There are three types of XAudio2 voice objects: source, submix, and mastering voices. 음성은 XAudio2 개체 처리, 조작 및 오디오 데이터를 재생 하는 데 사용 됩니다.Voices are the objects XAudio2 use to process, to manipulate, and to play audio data.

  • 원본 음성은 클라이언트에서 제공한 오디오 데이터에서 작동합니다.Source voices operate on audio data provided by the client.
  • 원본 및 서브믹스 음성은 해당 출력을 하나 이상의 서브믹스 또는 마스터링 음성으로 보냅니다.Source and submix voices send their output to one or more submix or mastering voices.
  • 서브믹스 및 마스터링 음성은 해당 음성을 공급하는 모든 음성으로부터 오디오를 믹싱하고 그 결과에서 작동합니다.Submix and mastering voices mix the audio from all voices feeding them, and operate on the result.
  • 마스터 음성 원본 음성 및 믹스 음성 데이터를 수신 하 고 오디오 하드웨어에 해당 데이터를 보냅니다.Mastering voices receive data from source voices and submix voices, and sends that data to the audio hardware.

자세한 내용은 이동 XAudio2 음성합니다.For more info, go to XAudio2 voices.

오디오 그래프Audio graph

오디오 그래프의 컬렉션인 XAudio2 음성합니다.Audio graph is a collection of XAudio2 voices. 오디오 소스 음성의 오디오 그래프의 한 쪽에서 시작 하 고, 필요에 따라 하나 이상의 믹스 음성 통과, 마스터 음성에서 끝납니다.Audio starts at one side of an audio graph in source voices, optionally passes through one or more submix voices, and ends at a mastering voice. 각 현재 재생 중인 소리를 0 개 이상의 믹스 음성에 대 한 원본 음성 및 하나의 마스터 음성 오디오 그래프를 포함 됩니다.An audio graph will contain a source voice for each sound currently playing, zero or more submix voices, and one mastering voice. 가장 간단한 오디오 그래프 및 XAudio2에 노이즈를 확인 하는 데 필요한 최소 마스터 음성에 직접 출력을 단일 소스 음성입니다.The simplest audio graph, and the minimum needed to make a noise in XAudio2, is a single source voice outputting directly to a mastering voice. 자세한 내용은 이동 오디오 그래프합니다.For more info, go to Audio graphs.

추가 참조 항목Additional reading

키 오디오.h 파일Key audio .h files

Audio.hAudio.h

// Audio:
// This class uses XAudio2 to provide sound output.  It creates two
// engines - one for music and the other for sound effects - each as
// a separate mastering voice.
// The SuspendAudio and ResumeAudio methods can be used to stop
// and start all audio playback.
public:
    Audio();

    void Initialize();
    void CreateDeviceIndependentResources();
    IXAudio2* MusicEngine();
    IXAudio2* SoundEffectEngine();
    void SuspendAudio();
    void ResumeAudio();

protected:
    // ...
};

MediaReader.hMediaReader.h

// MediaReader:
// This is a helper class for the SoundEffect class.  It reads small audio files
// synchronously from the package installed folder and returns sound data as a
// byte array.

ref class MediaReader
{
internal:
    MediaReader();

    Platform::Array<byte>^          LoadMedia(_In_ Platform::String^ filename);
    WAVEFORMATEX*                   GetOutputWaveFormatEx();

protected private:
    Windows::Storage::StorageFolder^ m_installedLocation;
    Platform::String^               m_installedLocationPath;
    WAVEFORMATEX                    m_waveFormat;
};

SoundEffect.hSoundEffect.h

// SoundEffect:
// This class plays a sound using XAudio2.  It uses a mastering voice provided
// from the Audio class.  The sound data can be read from disk using the MediaReader
// class.

ref class SoundEffect
{
internal:
    SoundEffect();

    void Initialize(
        _In_ IXAudio2*              masteringEngine,
        _In_ WAVEFORMATEX*          sourceFormat,
        _In_ Platform::Array<byte>^ soundData
        );

    void PlaySound(_In_ float volume);

protected private:
    //...

};