Agregar sonidoAdd sound

Nota

Este tema forma parte de la serie de tutoriales de creación de una plataforma universal de Windows sencilla (UWP) con DirectX .This topic is part of the Create a simple Universal Windows Platform (UWP) game with DirectX tutorial series. El tema de ese vínculo establece el contexto de la serie.The topic at that link sets the context for the series.

En este tema, se creará un motor de sonido sencillo con las API de XAudio2 .In this topic, we create a simple sound engine using XAudio2 APIs. Si no está familiarizado con XAudio2, hemos incluido una breve introducción en conceptos de audio.If you are new to XAudio2, we have included a short intro under Audio concepts.

Nota

Si no ha descargado el código de juego más reciente para este ejemplo, vaya a juego de ejemplo de Direct3D.If you haven't downloaded the latest game code for this sample, go to Direct3D sample game. Este ejemplo forma parte de una gran colección de ejemplos de características de UWP.This sample is part of a large collection of UWP feature samples. Para obtener instrucciones sobre cómo descargar el ejemplo, consulte obtener los ejemplos de UWP en github.For instructions on how to download the sample, see Get the UWP samples from GitHub.

ObjetivoObjective

Agregue sonidos al Juego de ejemplo con XAudio2.Add sounds into the sample game using XAudio2.

Definir el motor de audioDefine the audio engine

En el juego de ejemplo, los objetos de audio y los comportamientos se definen en tres archivos:In the sample game, the audio objects and behaviors are defined in three files:

  • Audio. h/.cpp: define el objeto de audio , que contiene los recursos de XAudio2 para la reproducción de sonido.Audio.h/.cpp: Defines the Audio object, which contains the XAudio2 resources for sound playback. También define el método para suspender y reanudar la reproducción de audio si el juego se pausa o desactiva.It also defines the method for suspending and resuming audio playback if the game is paused or deactivated.
  • __ MediaReader. h/.cpp__: define los métodos para leer archivos. wav de audio desde el almacenamiento local.MediaReader.h/.cpp: Defines the methods for reading audio .wav files from local storage.
  • __ SoundEffect. h/.cpp__: define un objeto para la reproducción de sonido en el juego.SoundEffect.h/.cpp: Defines an object for in-game sound playback.

Información generalOverview

Hay tres partes principales en la configuración para la reproducción de audio en el juego.There are three main parts in getting set up for audio playback into your game.

  1. Crear e inicializar los recursos de audioCreate and initialize the audio resources
  2. Cargar archivo de audioLoad audio file
  3. Asociar sonido a objetoAssociate sound to object

Todos se definen en el método Simple3DGame:: Initialize .They are all defined in the Simple3DGame::Initialize method. Vamos a examinar primero este método y, a continuación, profundizaremos en más detalles en cada una de las secciones.So let's first examine this method and then dive into more details in each of the sections.

Después de configurar, aprenderá a desencadenar los efectos sonoros que se van a reproducir.After setting up, we learn how to trigger the sound effects to play. Para obtener más información, vaya a reproducir el sonido.For more info, go to Play the sound.

Simple3DGame:: Initialize (método)Simple3DGame::Initialize method

En Simple3DGame:: Initialize, donde también se inicializan el __ _ controlador m__ y el __ _ representador m__ , se configura el motor de audio y se prepara para reproducir sonidos.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.

  • Cree m _ audioController, que es una instancia de la clase audio .Create m_audioController, which is an instance of the Audio class.
  • Cree los recursos de audio necesarios con el método audio:: CreateDeviceIndependentResources .Create the audio resources needed using the Audio::CreateDeviceIndependentResources method. Aquí, dos objetos de XAudio2 — son un objeto de motor de música y un objeto de motor de sonido, y se ha creado una voz de maestro para cada uno de ellos.Here, two XAudio2 objects — a music engine object and a sound engine object, and a mastering voice for each of them were created. El objeto de motor de música se puede usar para reproducir música en segundo plano del juego.The music engine object can be used to play background music for your game. El motor de sonido se puede usar para reproducir efectos sonoros en el juego.The sound engine can be used to play sound effects in your game. Para obtener más información, consulte crear e inicializar los recursos de audio.For more info, see Create and initialize the audio resources.
  • Cree mediaReader, que es una instancia de la clase mediaReader .Create mediaReader, which is an instance of MediaReader class. MediaReader, que es una clase auxiliar para la clase SoundEffect , Lee los archivos de audio pequeños sincrónicamente desde la ubicación del archivo y devuelve datos de sonido como una matriz de bytes.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.
  • Use MediaReader:: LoadMedia para cargar archivos de sonido desde su ubicación y crear una variable targetHitSound que contenga los datos de sonido. wav cargados.Use MediaReader::LoadMedia to load sound files from its location and create a targetHitSound variable to hold the loaded .wav sound data. Para obtener más información, consulte carga de archivo de audio.For more info, see Load audio file.

Los efectos sonoros están asociados al objeto de juego.Sound effects are associated with the game object. Así, cuando se produce una colisión con ese objeto de juego, se desencadena el efecto de sonido que se va a reproducir.So when a collision occurs with that game object, it triggers the sound effect to be played. En este juego de ejemplo, tenemos efectos sonoros para la munición (lo que usamos para captar los destinos con) y para el destino.In this sample game, we have sound effects for the ammo (what we use to shoot targets with) and for the target.

  • En la clase GameObject , hay una propiedad HitSound que se usa para asociar el efecto de sonido al objeto.In the GameObject class, there's a HitSound property that is used to associate the sound effect to the object.
  • Cree una nueva instancia de la clase SoundEffect e inicialícela.Create a new instance of the SoundEffect class and initialize it. Durante la inicialización, se crea una voz de origen para el efecto de sonido.During initialization, a source voice for the sound effect is created.
  • Esta clase reproduce un sonido mediante una voz de masterización proporcionada por la clase audio .This class plays a sound using a mastering voice provided from the Audio class. Los datos de sonido se leen desde la ubicación del archivo mediante la clase MediaReader .Sound data is read from file location using the MediaReader class. Para obtener más información, vea asociar sonido a objeto.For more info, see Associate sound to object.

Nota

El desencadenador real para reproducir el sonido viene determinado por el movimiento y la colisión de estos objetos de juego.The actual trigger to play the sound is determined by the movement and collision of these game objects. Por lo tanto, la llamada para reproducir realmente estos sonidos se define en el método Simple3DGame:: UpdateDynamics .Hence, the call to actually play these sounds are defined in the Simple3DGame::UpdateDynamics method. Para obtener más información, vaya a reproducir el sonido.For more info, go to Play the sound.

void Simple3DGame::Initialize(
    _In_ std::shared_ptr<MoveLookController> const& controller,
    _In_ std::shared_ptr<GameRenderer> const& renderer
    )
{
    // The following member is defined in the header file:
    // Audio m_audioController;

    ...

    // 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.resize(GameConstants::MaxAmmo);

    ...

    // Create a media reader which is used to read audio files from its file location.
    MediaReader mediaReader;
    auto targetHitSoundX = mediaReader.LoadMedia(L"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(std::make_shared<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(),
            targetHitSoundX
            );
        ...
    }

    // 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(L"Assets\\bounce.wav");

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

Crear e inicializar los recursos de audioCreate and initialize the audio resources

  • Use XAudio2Create, una API de xaudio2, para crear dos nuevos objetos de xaudio2 que definen los motores de música y efecto sonoro.Use XAudio2Create, an XAudio2 API, to create two new XAudio2 objects which define the music and sound effect engines. Este método devuelve un puntero a la interfaz IXAudio2 del objeto que administra todos los Estados del motor de audio, el subproceso de procesamiento de audio, el gráfico de voz, etc.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.
  • Una vez creadas las instancias de los motores, use IXAudio2:: CreateMasteringVoice para crear una voz de registro para cada uno de los objetos del motor de sonido.After the engines have been instantiated, use IXAudio2::CreateMasteringVoice to create a mastering voice for each of the sound engine objects.

Para obtener más información, vaya a Cómo: inicializar XAudio2.For more info, go to How to: Initialize XAudio2.

Audio:: CreateDeviceIndependentResources (método)Audio::CreateDeviceIndependentResources method

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

    winrt::check_hresult(
        XAudio2Create(m_musicEngine.put(), flags)
        );

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

    winrt::check_hresult(
        XAudio2Create(m_soundEffectEngine.put(), flags)
        );

    winrt::check_hresult(
        m_soundEffectEngine->CreateMasteringVoice(&m_soundEffectMasteringVoice)
        );

    m_audioAvailable = true;
}

Cargar archivo de audioLoad audio file

En el juego de ejemplo, el código para leer archivos de formato de audio se define en MediaReader. h/cpp__.In the sample game, the code for reading audio format files is defined in MediaReader.h/cpp__. Para leer un archivo de audio. wav codificado, llame a MediaReader:: LoadMedia, pasando el nombre del archivo. wav como parámetro de entrada.To read an encoded .wav audio file, call MediaReader::LoadMedia, passing in the filename of the .wav as the input parameter.

MediaReader:: LoadMedia (método)MediaReader::LoadMedia method

Este método usa las API de Media Foundation para leer en los archivos de audio .wav como un búfer de modulación por impulsos codificados (PCM, del inglés Pulse Code Modulation).This method uses the Media Foundation APIs to read in the .wav audio file as a Pulse Code Modulation (PCM) buffer.

Configuración del lector de origenSet up the Source Reader

  1. Use MFCreateSourceReaderFromURL para crear un lector de origen multimedia (IMFSourceReader).Use MFCreateSourceReaderFromURL to create a media source reader (IMFSourceReader).
  2. Use MFCreateMediaType para crear un objeto de tipo de medio (IMFMediaType) (mediaType).Use MFCreateMediaType to create a media type (IMFMediaType) object (mediaType). Representa una descripción de un formato de medios.It represents a description of a media format.
  3. Especifique que la salida descodificada de _mediaType_sea audio PCM, que es un tipo de audio que puede usar XAudio2 .Specify that the mediaType's decoded output is PCM audio, which is an audio type that XAudio2 can use.
  4. Establece el tipo de medio de salida descodificado para el lector de origen mediante una llamada a IMFSourceReader:: SetCurrentMediaType.Sets the decoded output media type for the source reader by calling IMFSourceReader::SetCurrentMediaType.

Para obtener más información sobre por qué usamos el lector de origen, vaya a lector de código fuente.For more info on why we use the Source Reader, go to Source Reader.

Describir el formato de datos de la secuencia de audioDescribe the data format of the audio stream

  1. Use IMFSourceReader:: GetCurrentMediaType para obtener el tipo de medio actual para la secuencia.Use IMFSourceReader::GetCurrentMediaType to get the current media type for the stream.
  2. Use IMFMediaType:: MFCreateWaveFormatExFromMFMediaType para convertir el tipo de medio de audio actual en un búfer de WAVEFORMATEX , utilizando los resultados de la operación anterior como entrada.Use IMFMediaType::MFCreateWaveFormatExFromMFMediaType to convert the current audio media type to a WAVEFORMATEX buffer, using the results of the earlier operation as input. Esta estructura especifica el formato de datos de la secuencia de audio de onda que se utiliza después de cargar el audio.This structure specifies the data format of the wave audio stream that is used after audio is loaded.

El formato WAVEFORMATEX se puede usar para describir el búfer del PCM.The WAVEFORMATEX format can be used to describe the PCM buffer. En comparación con la estructura WAVEFORMATEXTENSIBLE , solo se puede usar para describir un subconjunto de formatos de onda de audio.As compared to the WAVEFORMATEXTENSIBLE structure, it can only be used to describe a subset of audio wave formats. Para obtener más información sobre las diferencias entre WAVEFORMATEX y WAVEFORMATEXTENSIBLE, consulte descriptores de formato de onda extensible.For more info about the differences between WAVEFORMATEX and WAVEFORMATEXTENSIBLE, see Extensible Wave-Format Descriptors.

Leer la secuencia de audioRead the audio stream

  1. Obtiene la duración, en segundos, de la secuencia de audio mediante una llamada a IMFSourceReader:: GetPresentationAttribute y, a continuación, convierte la duración en bytes.Get the duration, in seconds, of the audio stream by calling IMFSourceReader::GetPresentationAttribute and then converts the duration to bytes.
  2. Lea el archivo de audio en como una secuencia mediante una llamada a IMFSourceReader:: ReadSample.Read the audio file in as a stream by calling IMFSourceReader::ReadSample. ReadSample lee el siguiente ejemplo del origen multimedia.ReadSample reads the next sample from the media source.
  3. Use IMFSample:: ConvertToContiguousBuffer para copiar el contenido del búfer de ejemplo de audio (ejemplo) en una matriz (mediaBuffer).Use IMFSample::ConvertToContiguousBuffer to copy contents of the audio sample buffer (sample) into an array (mediaBuffer).
std::vector<byte> MediaReader::LoadMedia(_In_ winrt::hstring const& filename)
{
    winrt::check_hresult(
        MFStartup(MF_VERSION)
        );

    // Creates a media source reader.
    winrt::com_ptr<IMFSourceReader> reader;
    winrt::check_hresult(
        MFCreateSourceReaderFromURL(
        (m_installedLocationPath + filename).c_str(),
            nullptr,
            reader.put()
            )
        );

    // 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.
    winrt::com_ptr<IMFMediaType> mediaType;
    winrt::check_hresult(
        MFCreateMediaType(mediaType.put())
        );

    // 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
    winrt::check_hresult(
        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
    winrt::check_hresult(
        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
    winrt::check_hresult(
        reader->SetCurrentMediaType(static_cast<uint32_t>(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
    winrt::com_ptr<IMFMediaType> outputMediaType;
    winrt::check_hresult(
        reader->GetCurrentMediaType(static_cast<uint32_t>(MF_SOURCE_READER_FIRST_AUDIO_STREAM), outputMediaType.put())
        );

    // Converts the current media type into the WaveFormatEx buffer structure.
    UINT32 size = 0;
    WAVEFORMATEX* waveFormat;
    winrt::check_hresult(
        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;
    winrt::check_hresult(
        reader->GetPresentationAttribute(static_cast<uint32_t>(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
            );

    std::vector<byte> fileData(maxStreamLengthInBytes);

    winrt::com_ptr<IMFSample> sample;
    winrt::com_ptr<IMFMediaBuffer> mediaBuffer;
    DWORD flags = 0;

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

    return fileData;
}

Asociar sonido a objetoAssociate sound to object

La Asociación de sonidos al objeto tiene lugar cuando se inicializa el juego, en el método Simple3DGame:: Initialize .Associating sounds to the object takes place when the game initializes, in the Simple3DGame::Initialize method.

Resumen:Recap:

  • En la clase GameObject , hay una propiedad HitSound que se usa para asociar el efecto de sonido al objeto.In the GameObject class, there's a HitSound property that is used to associate the sound effect to the object.
  • Cree una nueva instancia del objeto de la clase SoundEffect y asóciela con el objeto Game.Create a new instance of the SoundEffect class object and associate it with the game object. Esta clase reproduce un sonido mediante las API de XAudio2 .This class plays a sound using XAudio2 APIs. Usa una voz de masterización proporcionada por la clase audio .It uses a mastering voice provided by the Audio class. Los datos de sonido se pueden leer desde la ubicación del archivo mediante la clase MediaReader .The sound data can be read from file location using the MediaReader class.

SoundEffect:: Initialize se usa para inicializar la instancia de SoundEffect con los siguientes parámetros de entrada: puntero al objeto de motor de sonido (objetos IXAudio2 creados en el método audio:: CreateDeviceIndependentResources ), puntero al formato del archivo. wav mediante __MediaReader:: GetOutputWaveFormatEx__y los datos de sonido cargados mediante el método 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. Durante la inicialización, también se crea la voz de origen del efecto de sonido.During initialization, the source voice for the sound effect is also created.

SoundEffect:: Initialize (método)SoundEffect::Initialize method

void SoundEffect::Initialize(
    _In_ IXAudio2* masteringEngine,
    _In_ WAVEFORMATEX* sourceFormat,
    _In_ std::vector<byte> const& 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.
    winrt::check_hresult(
        masteringEngine->CreateSourceVoice(
            &m_sourceVoice,
            sourceFormat
            )
        );
    m_audioAvailable = true;
}

Reproducir el sonidoPlay the sound

Los desencadenadores para reproducir efectos sonoros se definen en el método Simple3DGame:: UpdateDynamics porque es donde se actualiza el movimiento de los objetos y se determina la colisión entre objetos.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.

Dado que la interacción entre los objetos difiere en gran medida, en función del juego, no vamos a analizar aquí la dinámica de los objetos de juego.Since interaction of between objects differs greatly, depending on the game, we are not going to discuss the dynamics of the game objects here. Si le interesa entender su implementación, vaya al método Simple3DGame:: UpdateDynamics .If you're interested to understand its implementation, go to Simple3DGame::UpdateDynamics method.

En principio, cuando se produce una colisión, desencadena el efecto de sonido que se va a reproducir llamando a SoundEffect::P laysound.In principle, when a collision occurs, it triggers the sound effect to play by calling SoundEffect::PlaySound. Este método detiene los efectos sonoros que se reproducen actualmente y pone en cola el búfer en memoria con los datos de sonido deseados.This method stops any sound effects that's currently playing and queues the in-memory buffer with the desired sound data. Usa la voz de origen para establecer el volumen, enviar datos de sonido e iniciar la reproducción.It uses source voice to set the volume, submit sound data, and start the playback.

SoundEffect::P método laySoundSoundEffect::PlaySound method

void SoundEffect::PlaySound(_In_ float volume)
{
    XAUDIO2_BUFFER buffer = { 0 };

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

    // Interrupt sound effect if it is currently playing.
    winrt::check_hresult(
        m_sourceVoice->Stop()
        );
    winrt::check_hresult(
        m_sourceVoice->FlushSourceBuffers()
        );

    // Queue the memory buffer for playback and start the voice.
    buffer.AudioBytes = (UINT32)m_soundData.size();
    buffer.pAudioData = m_soundData.data();
    buffer.Flags = XAUDIO2_END_OF_STREAM;

    winrt::check_hresult(
        m_sourceVoice->SetVolume(volume)
        );
    winrt::check_hresult(
        m_sourceVoice->SubmitSourceBuffer(&buffer)
        );
    winrt::check_hresult(
        m_sourceVoice->Start()
        );
}

Simple3DGame:: UpdateDynamics (método)Simple3DGame::UpdateDynamics method

El método Simple3DGame:: UpdateDynamics se encarga de la interacción y la colisión entre los objetos de juego.The Simple3DGame::UpdateDynamics method takes care the interaction and collision between game objects. Cuando los objetos entran en conflicto (o forman una intersección), se desencadena el efecto sonoro asociado para reproducirlo.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_objects[i]->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
}

Pasos siguientesNext steps

Hemos tratado el marco de UWP, los gráficos, los controles, la interfaz de usuario y el audio de un juego de Windows 10.We have covered the UWP framework, graphics, controls, user interface, and audio of a Windows 10 game. La siguiente parte de este tutorial, ampliando el juego de ejemplo, explica otras opciones que se pueden usar al desarrollar un juego.The next part of this tutorial, Extending the sample game, explains other options that can be used when developing a game.

Conceptos de audioAudio concepts

Para el desarrollo de juegos de Windows 10, use XAudio2 versión 2,9.For Windows 10 games development, use XAudio2 version 2.9. Esta versión se incluye con Windows 10.This version is shipped with Windows 10. Para obtener más información, vaya a las versiones de XAudio2.For more info, go to XAudio2 Versions.

AudioX2 es una API de bajo nivel que proporciona procesamiento de señal y combinación de base.AudioX2 is a low-level API that provides signal processing and mixing foundation. Para obtener más información, consulte conceptos clave de XAudio2.For more info, see XAudio2 Key Concepts.

Voces de XAudio2XAudio2 voices

Hay tres tipos de objetos de voz de XAudio2: voces de origen, submezcla y maestra.There are three types of XAudio2 voice objects: source, submix, and mastering voices. Las voces son los objetos que usa XAudio2 para procesar, manipular y reproducir datos de audio.Voices are the objects XAudio2 use to process, to manipulate, and to play audio data.

  • Las voces de origen operan en datos de audio proporcionados por el cliente.Source voices operate on audio data provided by the client.
  • Las voces de origen y de submezcla envían su resultado a una o más voces de submezcla o de procesamiento.Source and submix voices send their output to one or more submix or mastering voices.
  • Las voces de submezcla y de procesamiento mezclan el audio de todas las voces que les alimentan y trabajan con el resultado.Submix and mastering voices mix the audio from all voices feeding them, and operate on the result.
  • Las voces de Master reciben datos de voces de origen y voces de submezcla, y envían los datos al hardware de audio.Mastering voices receive data from source voices and submix voices, and sends that data to the audio hardware.

Para obtener más información, vaya a XAudio2 Voices.For more info, go to XAudio2 voices.

Gráfico de audioAudio graph

El gráfico de audio es una colección de voces de XAudio2.Audio graph is a collection of XAudio2 voices. El audio se inicia en un lado de un gráfico de audio en las voces de origen y, opcionalmente, pasa a través de una o más voces de la mezcla y finaliza en una voz de la maestra.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. Un gráfico de audio contendrá una voz de origen para cada sonido que se reproduce actualmente, cero o más voces de submezcla y una voz de maestro.An audio graph will contain a source voice for each sound currently playing, zero or more submix voices, and one mastering voice. El gráfico de audio más sencillo, y el mínimo necesario para crear un ruido en XAudio2, es una voz de origen única que se envía directamente a una voz de mastering.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. Para obtener más información, vaya a gráficos de audio.For more info, go to Audio graphs.

Lecturas adicionalesAdditional reading

Archivos de Key audio. hKey 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.

class Audio
{
public:
    Audio();

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

private:
    ...
};

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
// vector of bytes.

class MediaReader
{
public:
    MediaReader();

    std::vector<byte> LoadMedia(_In_ winrt::hstring const& filename);
    WAVEFORMATEX* GetOutputWaveFormatEx();

private:
    winrt::Windows::Storage::StorageFolder  m_installedLocation{ nullptr };
    winrt::hstring                          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.

class SoundEffect
{
public:
    SoundEffect();

    void Initialize(
        _In_ IXAudio2* masteringEngine,
        _In_ WAVEFORMATEX* sourceFormat,
        _In_ std::vector<byte> const& soundData
        );

    void PlaySound(_In_ float volume);

private:
    ...
};