-- ----------------------------------------------------------------- --
-- AdaSDL --
-- Binding to Simple Direct Media Layer --
-- Copyright (C) 2001 A.M.F.Vargas --
-- Antonio M. F. Vargas --
-- Ponta Delgada - Azores - Portugal --
-- http://www.adapower.net/~avargas --
-- E-mail: avargas@adapower.net --
-- ----------------------------------------------------------------- --
-- --
-- This library is free software; you can redistribute it and/or --
-- modify it under the terms of the GNU General Public --
-- License as published by the Free Software Foundation; either --
-- version 2 of the License, or (at your option) any later version. --
-- --
-- This library is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
-- General Public License for more details. --
-- --
-- You should have received a copy of the GNU General Public --
-- License along with this library; if not, write to the --
-- Free Software Foundation, Inc., 59 Temple Place - Suite 330, --
-- Boston, MA 02111-1307, USA. --
-- --
-- As a special exception, if other files instantiate generics from --
-- this unit, or you link this unit with other files to produce an --
-- executable, this unit does not by itself cause the resulting --
-- executable to be covered by the GNU General Public License. This --
-- exception does not however invalidate any other reasons why the --
-- executable file might be covered by the GNU Public License. --
-- ----------------------------------------------------------------- --
-- **************************************************************** --
-- This is an Ada binding to SDL ( Simple DirectMedia Layer from --
-- Sam Lantinga - www.libsld.org ) --
-- **************************************************************** --
-- In order to help the Ada programmer, the comments in this file --
-- are, in great extent, a direct copy of the original text in the --
-- SDL header files. --
-- **************************************************************** --
with Interfaces.C.Strings;
with SDL.Types; use SDL.Types;
with SDL.RWops;
package SDL.Audio is
pragma Elaborate_Body;
package C renames Interfaces.C;
type Callback_ptr_Type is access procedure (
userdata : void_ptr;
stream : Uint8_ptr;
len : C.int);
pragma Convention (C, Callback_ptr_Type);
-- The calculated values in this structure are calculated by OpenAudio
type AudioSpec is
record
freq : C.int; -- DSP frequency -- samples per second
format : Uint16; -- Audio data format
channels : Uint8; -- Number of channels: 1 mono, 2 stereo
silence : Uint8; -- Audio buffer silence value (calculated)
samples : Uint16; -- Audio buffer size in samples
padding : Uint16; -- Necessary for some compile environments
size : Uint32; -- Audio buffer size in bytes (calculated)
-- This function is called when the audio device needs more data.
-- 'stream' is a pointer to the audio data buffer
-- 'len' is the length of that buffer in bytes.
-- Once the callback returns, the buffer will no longer be valid.
-- Stereo samples are stored in a LRLRLR ordering.
callback : Callback_ptr_Type;
userdata : void_ptr;
end record;
pragma Convention (C, AudioSpec);
type AudioSpec_ptr is access all AudioSpec;
pragma Convention (C, AudioSpec_ptr);
type Format_Flag is mod 2**16;
pragma Convention (C, Format_Flag);
type Format_Flag_ptr is access Format_Flag;
pragma Convention (C, Format_Flag_ptr);
-- Audio format flags (defaults to LSB byte order)
-- Unsigned 8-bit samples
AUDIO_U8 : constant Format_Flag := 16#0008#;
-- Signed 8-bit samples
AUDIO_S8 : constant Format_Flag := 16#8008#;
-- Unsigned 16-bit samples
AUDIO_U16LSB : constant Format_Flag := 16#0010#;
-- Signed 16-bit samples
AUDIO_S16LSB : constant Format_Flag := 16#8010#;
-- As above, but big-endian byte order
AUDIO_U16MSB : constant Format_Flag := 16#1010#;
-- As above, but big-endian byte order
AUDIO_S16MSB : constant Format_Flag := 16#9010#;
AUDIO_U16 : constant Format_Flag := AUDIO_U16LSB;
AUDIO_S16 : constant Format_Flag := AUDIO_S16LSB;
function Get_Audio_U16_Sys return Format_Flag;
function Get_Audio_S16_Sys return Format_Flag;
-- A structure to hold a set of audio conversion filters and buffers
type AudioCVT;
type AudioCVT_ptr is access all AudioCVT;
pragma Convention (C, AudioCVT_ptr);
type filter_ptr is access procedure (
cvt : AudioCVT_ptr;
format : Uint16);
pragma Convention (C, filter_ptr);
type filters_array is array (0 .. 9) of filter_ptr;
pragma Convention (C, filters_array);
type AudioCVT is
record
need : C.int; -- Set to 1 if conversion possible
src_format : Uint16; -- Source audio format
dst_format : Uint16; -- Target audio format
rate_incr : C.double; -- Rate conversion increment
buf : Uint8_ptr; -- Buffer to hold entire audio data
len : C.int; -- Length of original audio buffer
len_cvt : C.int; -- Length of converted audio buffer
len_mult : C.int; -- buffer must be len*len_mult big
len_ratio : C.double; -- Given len, final size is len*len_ratio
filters : filters_array;
filter_index : filters_array; -- Current audio conversion function
end record;
pragma Convention (C, AudioCVT);
-- -------------------
-- Function prototypes
-- -------------------
-- These function and procedure are used internally, and should not
-- be used unless you have a specific need to specify the audio driver
-- you want to use.You should normally use Init or InitSubSystem.
function AudioInit (driver_name : C.Strings.chars_ptr) return C.int;
pragma Import (C, AudioInit, "SDL_AudioInit");
procedure AudioQuit;
pragma Import (C, AudioQuit, "SDL_AudioQuit");
-- This function fills the given character buffer with the name of the
-- current audio driver, and returns a pointer to it if the audio driver
-- has been initialized. It returns NULL if no driver has been initialized.
function AudioDriverName (
namebuf : C.Strings.chars_ptr;
maslen : C.int)
return C.Strings.chars_ptr;
pragma Import (C, AudioDriverName, "SDL_AudioDriverName");
-- This function opens the audio device with the desired parameters, and
-- returns 0 if successful, placing the actual hardware parameters in the
-- structure pointed to by 'obtained'. If 'obtained' is NULL, the audio
-- data passed to the callback function will be guaranteed to be in the
-- requested format, and will be automatically converted to the hardware
-- audio format if necessary. This function returns -1 if it failed
-- to open the audio device, or couldn't set up the audio thread.
-- When filling in the desired audio spec structure,
-- 'desired.freq' should be the desired audio frequency in samples-per-sec.
-- 'desired.format' should be the desired audio format.
-- 'desired.samples' is the desired size of the audio buffer, in samples.
-- This number should be a power of two, and may be adjusted by the audio
-- driver to a value more suitable for the hardware. Good values seem to
-- range between 512 and 8096 inclusive, depending on the application and
-- CPU speed. Smaller values yield faster response time, but can lead
-- to underflow if the application is doing heavy processing and cannot
-- fill the audio buffer in time. A stereo sample consists of both right
-- and left channels in LR ordering.
-- Note that the number of samples is directly related to time by the
-- following formula: ms := (samples*1000)/freq
-- 'desired->size' is the size in bytes of the audio buffer, and is
-- calculated by OpenAudio.
-- 'desired->silence' is the value used to set the buffer to silence,
-- and is calculated by OpenAudio.
-- 'desired->callback' should be set to a function that will be called
-- when the audio device is ready for more data. It is passed a pointer
-- to the audio buffer, and the length in bytes of the audio buffer.
-- This function usually runs in a separate thread, and so you should
-- protect data structures that it accesses by calling LockAudio
-- and UnlockAudio in your code.
-- 'desired.userdata' is passed as the first parameter to your callback
-- function.
-- The audio device starts out playing silence when it's opened, and should
-- be enabled for playing by calling PauseAudio(0) when you are ready
-- for your audio callback function to be called. Since the audio driver
-- may modify the requested size of the audio buffer, you should allocate
-- any local mixing buffers after you open the audio device.
function OpenAudio (
desired : AudioSpec_ptr;
obtained : AudioSpec_ptr)
return C.int;
pragma Import (C, OpenAudio, "SDL_OpenAudio");
-- Get the current audio state:
type audiostatus is new C.int;
AUDIO_STOPED : constant := 0;
AUDIO_PLAYING : constant := 1;
AUDIO_PAUSED : constant := 2;
function GetAudioStatus return audiostatus;
pragma Import (C, GetAudioStatus, "SDL_GetAudioStatus");
-- This function pauses and unpauses the audio callback processing.
-- It should be called with a parameter of 0 after opening the audio
-- device to start playing sound. This is so you can safely initialize
-- data for your callback function after opening the audio device.
-- Silence will be written to the audio device during the pause.
procedure PauseAudio (pause_on : C.int);
pragma Import (C, PauseAudio, "SDL_PauseAudio");
-- This function loads a WAVE from the data source, automatically freeing
-- that source if 'freesrc' is non-zero. For example, to load a WAVE file,
-- you could do:
-- LoadWAV_RW(RWFromFile("sample.wav", "rb"), 1, ...);
-- If this function succeeds, it returns the given AudioSpec,
-- filled with the audio data format of the wave data, and sets
-- 'audio_buf' to a malloc()'d buffer containing the audio data,
-- and sets 'audio_len' to the length of that audio buffer, in bytes.
-- You need to free the audio buffer with FreeWAV when you are
-- done with it.
-- This function returns NULL and sets the SDL error message if the
-- wave file cannot be opened, uses an unknown data format, or is
-- corrupt. Currently raw and MS-ADPCM WAVE files are supported.
function LoadWAV_RW (
src : SDL.RWops.RWops_ptr;
freesrc : C.int;
spec : AudioSpec_ptr;
audio_buf : Uint8_ptr_ptr;
audio_len : Uint32_ptr)
return AudioSpec_ptr;
pragma Import (C, LoadWAV_RW, "SDL_LoadWAV_RW");
function LoadWAV (
file : C.Strings.chars_ptr;
spec : AudioSpec_ptr;
audio_buf : Uint8_ptr_ptr;
audio_len : Uint32_ptr)
return AudioSpec_ptr;
pragma Inline (LoadWAV);
-- LoadWAV_RW_VP not working properly
-- for some strange reason. Result is Always null.
procedure LoadWAV_RW_VP (
Result : out AudioSpec_ptr;
src : SDL.RWops.RWops_ptr;
freesrc : C.int;
spec : out AudioSpec_ptr;
audio_buf : out Uint8_ptr;
audio_len : out Uint32);
pragma Import (C, LoadWAV_RW_VP, "SDL_LoadWAV_RW");
pragma Import_Valued_Procedure (LoadWAV_RW_VP);
procedure Load_WAV (
file : C.Strings.chars_ptr;
spec : AudioSpec_ptr; -- out AudioSpec
audio_buf : Uint8_ptr_ptr; -- out Uint8_ptr
audio_len : Uint32_ptr; -- out Uint32
Valid_WAV : out Boolean);
pragma Inline (Load_WAV);
-- This function frees data previously allocated with SDL_LoadWAV_RW()
procedure FreeWAV (audio_buf : Uint8_ptr);
pragma Import (C, FreeWAV, "SDL_FreeWAV");
-- This function takes a source format and rate and a destination format
-- and rate, and initializes the 'cvt' structure with information needed
-- by ConvertAudio to convert a buffer of audio data from one format
-- to the other.
-- This function returns 0, or -1 if there was an error.
function BuildAudioCVT (
cvt : AudioCVT_ptr;
src_format : Uint16;
src_channels : Uint8;
src_rate : C.int;
dst_format : Uint16;
dst_channels : Uint8;
dst_rate : C.int)
return C.int;
pragma Import (C, BuildAudioCVT, "SDL_BuildAudioCVT");
-- Once you have initialized the 'cvt' structure using BuildAudioCVT,
-- created an audio buffer cvt.buf, and filled it with cvt.len bytes of
-- audio data in the source format, this function will convert it in-place
-- to the desired format.
-- The data conversion may expand the size of the audio data, so the buffer
-- cvt.buf should be allocated after the cvt structure is initialized by
-- BuildAudioCVT, and should be cvt.len * cvt.len_mult bytes long.
function ConvertAudio (cvt : AudioCVT_ptr) return C.int;
pragma Import (C, ConvertAudio, "SDL_ConvertAudio");
-- This takes two audio buffers of the playing audio format and mixes
-- them, performing addition, volume adjustment, and overflow clipping.
-- The volume ranges from 0 - 128, and should be set to _MIX_MAXVOLUME
-- for full audio volume. Note this does not change hardware volume.
-- This is provided for convenience -- you can mix your own audio data.
MIX_MAXVOLUME : constant := 128;
procedure MixAudio (
dst : Uint8_ptr;
src : Uint8_ptr;
len : Uint32;
volume : C.int);
pragma Import (c, MixAudio, "SDL_MixAudio");
-- The lock manipulated by these functions protects the callback function.
-- During a LockAudio/UnlockAudio pair, you can be guaranteed that the
-- callback function is not running. Do not call these from the callback
-- function or you will cause deadlock.
procedure LockAudio;
pragma Import (C, LockAudio, "SDL_LockAudio");
procedure UnlockAudio;
pragma Import (C, UnlockAudio, "SDL_UnlockAudio");
-- This procedure shuts down audio processing and closes the audio device.
procedure CloseAudio;
pragma Import (C, CloseAudio, "SDL_CloseAudio");
end SDL.Audio;
syntax highlighted by Code2HTML, v. 0.9.1