User Tools

Site Tools


tutorial:audio

====== Audio ====== [[tutorial:index|Tutorial index]] ==== Introduction ==== In this tutorial we will add audio support using the BASS audio provider. Start by downloading these three sounds and put them in the output folder ^ Name ^ Type ^ Url ^ | Bomb.mp3 | Sample | http://www.freesound.org/people/Zangrutz/sounds/155235/ | | Missile.wav | Sample | http://www.freesound.org/people/Benboncan/sounds/167563/ | | Music.wav | Stream | http://www.freesound.org/people/ERH/sounds/30192/ | Or download them in one zip file from {{:tutorial:resources:sampleaudio.zip|here}} You can download the source for this tutorial {{:tutorial:downloads:06_audio.zip|here}}. ==== Create the audio engine ==== Start by adding the [[http://phoenixlib.net/api/phxAudio.html|phxAudio]] unit to the uses list. We also need to include a provider, in this case we use the Bass provider. There is a OpenAL provider included aswell but it is not completed as of 2013-08-08 <code pascal> uses ... // Audio classes phxAudio, // Audio device using the bass provider phxAudio_Bass; </code> Next we have to add the audio engine variable and the other content that is needed. <code pascal> TGame = class(TPHXApplication) private Device: TPHXDevice; Timer : TPHXTimer; Canvas: TPHXCanvas; Fonts : TPHXFontList; Input : TPHXInput; Audio : TPHXAudioEngine; public procedure Init; override; procedure Update; override; procedure Render; override; procedure Shutdown; override; end; </code> Now we have to create a instance of the engine as well as initialize it. Calling the [[http://phoenixlib.net/api/phxAudio.TPHXAudioEngine.html#Initialize|Initialize]] function of the audio engine initializes the audio using the default sound device that is selected in the os. <code pascal> procedure TGame.Init; begin ... // Create the audio engine using the included BASS provider Audio:= TPHXAudioEngine.Create; // Initialize the audio engine using the default audio device Audio.Initialize; end; </code> ==== Selecting the audio device==== To select the audio output device we first have to determine the name or index of the device to use. The Devices property of the audio engine contains all supported devices and are initialized when the audio engine is creates. <code pascal> for Index:=0 to Audio.Devices.Count-1 do begin Fonts[0].TextOut(400, 4 + Fonts[0].Height * Index, Format('%d: %s', [Index, Audio.Devices[Index].Name])); end; </code> {{:tutorial:audio:audio-devices.png?direct&400|}} To select the audio engine with a specific device we have to call the [[http://phoenixlib.net/api/phxAudio.TPHXAudioEngine.html#Initialize|Initialize]] function with the device index or name. <code pascal> // Initialize the audio engine using a audio device by index Audio.Initialize(2); // Initialize the audio engine using a audio device by name Audio.Initialize('SPDIF Out (Creative SB X-Fi)'); </code> ==== Loading audio samples ==== Samples are loaded into memory and is used for effects that needs to be played without any delays. <code pascal> procedure TGame.Init; begin ... // Load the bomb sample Audio.LoadSample('Bomb.mp3', 'Bomb'); // Load the missile sample Audio.LoadSample('Missile.wav', 'Missile'); end; </code> ==== Playing audio samples ==== To play a loaded audio sample we can use the [[http://phoenixlib.net/api/phxAudio.TPHXAudioEngine.html#Play|Play]] method of the audio engine. <code pascal> procedure TGame.Update; begin ... // Update the audio engine Audio.Update; // Play the bomb sample with the left mouse button if isButton1 in Input.States then begin Audio.Play('Bomb'); Input.States:= Input.States - [isButton1]; end; // Play the missile sample the right mouse button if isButton2 in Input.States then begin Audio.Play('Missile'); Input.States:= Input.States - [isButton2]; end; end; </code> It is also possible to play the sample with a specific volume <code pascal> // Play the missile sample at 50% volume with the right mouse button if isButton3 in Input.States then begin Audio.Play('Missile', 0.5); // Remove the state Input.States:= Input.States - [isButton3]; end; </code> ==== Loading audio streams ==== Audio streams are used to play music that are to large to upload into memory before playing, there might be some delay when starting playing them due to the disk access. To load a music stream we call the [[http://phoenixlib.net/api/phxAudio.TPHXAudioEngine.html#LoadSample|LoadSample]] function of the audio engine with the filename and optional name of the audio file. <code pascal> procedure TGame.Init; begin ... // Streams are streamed from disk and are used for music Music:= Audio.LoadStream('string-1-loop.wav', 'Music'); // We want to loop the music Music.Looped:= True; // Set the volume of the music from 0.0 (silent) to 1.0 (full) Music.Volume:= 0.5; // Play the music Music.Play; end; </code> This function returns a [[http://phoenixlib.net/api/phxAudio.TPHXAudioStream.html|TPHXAudioStream]] instance where it is possible to set if the stream should be looped and read the duration and position of the sample. <code pascal> Fonts[0].TextOut(4, 4 + Fonts[0].Height * 0, Format('Music volume: %d %%', [ Round(Music.Volume*100)])); Fonts[0].TextOut(4, 4 + Fonts[0].Height * 1, Format('Music position: %.1f s', [Music.Position])); Fonts[0].TextOut(4, 4 + Fonts[0].Height * 2, Format('Music duration: %.1f s', [Music.Duration])); </code> ==== Changing volume ==== To change the master volume of the audio we can write to the [[http://phoenixlib.net/api/phxAudio.TPHXAudioEngine.html#Volume|Volume]] property of the audio engine. <code pascal> procedure TGame.KeyPressed(Key: TPHXVirtualKey; Shift: TPHXShiftStates); begin inherited; // Change the master volume to 50% when pressing 1 on the keyboard if Key = VK_1 then begin Audio.Volume:= 0.5; end; // Change the master volume to 100% when pressing 2 on the keyboard if Key = VK_2 then begin Audio.Volume:= 1.0; end; end; </code> To change the volume of the music we have to modify the [[http://phoenixlib.net/api/phxAudio.TPHXAudioStream.html#Volume|Volume]] property of the audio stream. <code pascal> // Raise the volume of the music if isUp in Input.States then begin Music.Volume:= Music.Volume + 0.2 * Timer.FrameTime; if Music.Volume > 1 then Music.Volume:= 1; end; // Lower the volume of the music if isDown in Input.States then begin Music.Volume:= Music.Volume - 0.2 * Timer.FrameTime; if Music.Volume < 0 then Music.Volume:= 0; end; </code> To change the volume of a sample we have to modify the [[http://phoenixlib.net/api/phxAudio.TPHXAudioSample.html#Volume|Volume]] property of the audio sample. This changes the volume of all channels playing this sample <code pascal> // Change the volume of all playing instances the missile sample if Key = VK_3 then begin Audio.Samples[1].Volume:= 0.1; end; </code> [[tutorial:index|Back to tutorial index]]

tutorial/audio.txt · Last modified: 2013/08/17 12:29 by amnoxx