Advertisement
Guest User

Untitled

a guest
Apr 11th, 2013
290
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. program sdl_audio_test;
  2.  
  3. { SDL1/SDL2 imports }
  4.  
  5. const
  6.   SDL_INIT_AUDIO = $00000010;
  7.  
  8.   AUDIO_S16LSB = $8010;
  9.   AUDIO_S16 = AUDIO_S16LSB;
  10.  
  11.   SDL_MIX_MAXVOLUME = 128;
  12.  
  13. type
  14.   UInt8 = Byte;
  15.   PUInt8 = ^UInt8;
  16.   UInt16 = Word;
  17.   UInt32 = LongWord;
  18.   SDL_Double = Double;
  19.  
  20.   TSDL_AudioSpecCallback = procedure(userdata: Pointer; stream: PUInt8; len: Integer); cdecl;
  21.  
  22.   TSDL_AudioSpec = record
  23.     freq: Integer;
  24.     format: UInt16;
  25.     channels: UInt8;
  26.     silence: UInt8;
  27.     samples: UInt16;
  28.     padding: UInt16;
  29.     size: UInt32;
  30.     callback: TSDL_AudioSpecCallback;
  31.     userdata: Pointer;
  32.   end;
  33.   PSDL_AudioSpec = ^TSDL_AudioSpec;
  34.  
  35.   PSDL_AudioCVT = ^TSDL_AudioCVT;
  36.  
  37.   TSDL_AudioFilter = procedure(cvt: PSDL_AudioCVT; format: Uint16); cdecl;
  38.  
  39.   TSDL_AudioCVT = record
  40.     needed: LongInt;
  41.     src_format: Uint16;
  42.     dst_format: Uint16;
  43.     rate_incr: double;
  44.     buf: PUint8;
  45.     len: LongInt;
  46.     len_cvt: LongInt;
  47.     len_mult: LongInt;
  48.     len_ratio: SDL_Double;
  49.     filters: array[0..9] of TSDL_AudioFilter;
  50.     filter_index: LongInt;
  51.   end;
  52.  
  53.   TSDL_RWops = record
  54.     seek: Pointer;
  55.     read: Pointer;
  56.     write: Pointer;
  57.     close: Pointer;
  58.     type_: UInt32;
  59.   end;
  60.   PSDL_RWops = ^TSDL_RWops;
  61.  
  62. function SDL_Init(flags: UInt32): Integer; cdecl; external;
  63. procedure SDL_Delay(msec: UInt32); cdecl; external;
  64. procedure SDL_Quit; cdecl; external;
  65. function SDL_GetError: PAnsiChar; cdecl; external;
  66. function SDL_OpenAudio(desired, obtained: PSDL_AudioSpec): LongInt; cdecl; external;
  67. procedure SDL_CloseAudio; cdecl; external;
  68. procedure SDL_PauseAudio(pause_on: LongInt); cdecl; external;
  69. procedure SDL_MixAudio(dst, src: PUint8; len: Uint32; volume: LongInt); cdecl; external;
  70. function SDL_ConvertAudio(var cvt: TSDL_AudioCVT): LongInt; cdecl; external;
  71. function SDL_BuildAudioCVT(out cvt: TSDL_AudioCVT; src_format: UInt16;
  72.   src_channels: UInt8; src_rate: Integer; dst_format: UInt16; dst_channels: UInt8;
  73.   dst_rate: Integer): Integer; cdecl; external;
  74. function SDL_LoadWAV_RW(src: PSDL_RWops; freesrc: LongInt; out spec:
  75.   TSDL_AudioSpec; out audio_buf: PUInt8; out audiolen: UInt32): PSDL_AudioSpec; cdecl; external;
  76. function SDL_RWFromFile(filename, mode: PAnsiChar): PSDL_RWops; cdecl; external;
  77. procedure SDL_FreeWAV(audio_buf: PUInt8); cdecl; external;
  78. procedure SDL_LockAudio; cdecl; external;
  79. procedure SDL_UnlockAudio; cdecl; external;
  80.  
  81. { Macros }
  82.  
  83. function SDL_LoadWAV(filename: PAnsiChar; out spec: TSDL_AudioSpec; out audio_buf: PUInt8;
  84.   out audiolen: UInt32): PSDL_AudioSpec;
  85. begin
  86.   Result := SDL_LoadWAV_RW(SDL_RWFromFile(filename, 'rb'), 1, spec, audio_buf, audiolen);
  87. end;
  88.  
  89. { Example starts here }
  90.  
  91. var
  92.   Sample: record
  93.     Data: PUint8;
  94.     Len: LongInt;
  95.     Pos: LongInt;
  96.   end;
  97.  
  98. { The AudioMixer callback plays samples and controls volume levels }
  99.  
  100. procedure AudioMixer(userdata: Pointer; stream: PUInt8; len: LongInt); cdecl;
  101. var
  102.   Amount: LongInt;
  103.   Cursor: PUint8;
  104. begin
  105.   Amount := Sample.Len - Sample.Pos;
  106.   if Amount < 1 then
  107.     Exit;
  108.   if Amount > len then
  109.     Amount := len;
  110.   Cursor := Sample.Data;
  111.   Inc(Cursor, Sample.Pos);
  112.   Inc(Sample.Pos, Amount);
  113.   SDL_MixAudio(stream, Cursor, Amount, SDL_MIX_MAXVOLUME);
  114. end;
  115.  
  116. { Initialize the sound system }
  117.  
  118. function OpenSounds: Boolean;
  119. var
  120.   Spec: TSDL_AudioSpec;
  121. begin
  122.   if SDL_Init(SDL_INIT_AUDIO) <> 0 then
  123.   begin
  124.     WriteLn('SDL failed to initialize audio: ', SDL_GetError);
  125.     Exit(False);
  126.   end;
  127.   Spec.freq := 22050;
  128.   Spec.format := AUDIO_S16;
  129.   Spec.channels := 2;
  130.   Spec.samples := 512;
  131.   Spec.callback := @AudioMixer;
  132.   Spec.userdata := nil;
  133.   if SDL_OpenAudio(@Spec, nil) <> 0 then
  134.   begin
  135.     WriteLn('SDL failed to open audio: ', SDL_GetError);
  136.     Exit(False);
  137.   end;
  138.   WriteLn('SDL opened audio');
  139.   SDL_PauseAudio(0);
  140. end;
  141.  
  142. { Load and convert a WAV file, then pause while the sample file plays }
  143.  
  144. procedure PlaySound(const FileName: AnsiString);
  145. var
  146.   Wave: TSDL_AudioSpec;
  147.   Convert: TSDL_AudioCVT;
  148.   Buf: PUint8;
  149.   Len: Uint32;
  150. begin
  151.   if SDL_LoadWAV(PAnsiChar(FileName), Wave, Buf, Len) = nil then
  152.   begin
  153.     WriteLn('Failed to load audio file: ', SDL_GetError);
  154.     Exit;
  155.   end;
  156.   { Build our format conversion }
  157.   SDL_BuildAudioCVT(Convert, Wave.format, Wave.channels, Wave.freq,
  158.     AUDIO_S16, 2, 22050);
  159.   { Allocate memory and copy buffer from the loaded wave }
  160.   Convert.buf := GetMem(Len * Convert.len_mult);
  161.   Move(Buf^, Convert.buf^, Len);
  162.   { Free the original buffer }
  163.   SDL_FreeWAV(Buf);
  164.   Convert.len := Len;
  165.   { Convert the loaded wave to our format }
  166.   SDL_ConvertAudio(Convert);
  167.   { Lock the callback and populate Sample with the converted data }
  168.   SDL_LockAudio;
  169.   Sample.Data := Convert.buf;
  170.   Sample.Len := Convert.len_cvt;
  171.   Sample.Pos := 0;
  172.   SDL_UnlockAudio;
  173.   { Pause while we listen to the sound }
  174.   WriteLn('Stating delay');
  175.   SDL_Delay(5000);
  176.   WriteLn('Ending delay');
  177. end;
  178.  
  179. { Close the sound system }
  180.  
  181. procedure CloseSounds;
  182. begin
  183.   SDL_LockAudio;
  184.   FreeMem(Sample.Data);
  185.   Sample.Len := 0;
  186.   Sample.Pos := 0;
  187.   SDL_UnlockAudio;
  188.   SDL_CloseAudio;
  189.   SDL_Quit;
  190. end;
  191.  
  192. { Uncomment the define below to use SDL 2.0 }
  193. {.$define use_sdl_2}
  194.  
  195. {$ifdef use_sdl_2}
  196.   {$linklib SDL2}
  197. {$else}
  198.   {$linklib SDL}
  199. {$endif}
  200.  
  201. begin
  202.   if OpenSounds then
  203.   begin
  204.     PlaySound('hello.wav');
  205.     CloseSounds;
  206.   end;
  207.   WriteLn('Done');
  208. end.
Advertisement
RAW Paste Data Copied
Advertisement