aboutsummaryrefslogtreecommitdiffstats
path: root/Game/Code/Classes/UAudio_FFMpeg.pas
diff options
context:
space:
mode:
authorjaybinks <jaybinks@b956fd51-792f-4845-bead-9b4dfca2ff2c>2007-10-27 06:31:04 +0000
committerjaybinks <jaybinks@b956fd51-792f-4845-bead-9b4dfca2ff2c>2007-10-27 06:31:04 +0000
commit8cca9e3e6f591c35d35d132a9d3f93ffc7cdfee8 (patch)
tree985dac320ed9d8456a682c952c1b0ab0f502859b /Game/Code/Classes/UAudio_FFMpeg.pas
parent64f2c9b369185575d397dccbbcacc7f818874952 (diff)
downloadusdx-8cca9e3e6f591c35d35d132a9d3f93ffc7cdfee8.tar.gz
usdx-8cca9e3e6f591c35d35d132a9d3f93ffc7cdfee8.tar.xz
usdx-8cca9e3e6f591c35d35d132a9d3f93ffc7cdfee8.zip
made some major progress with ffmpeg audio playback !!!
YAY !!! still a little choppy, so I suspect incorrect buffer sizes or something like that. also made some mods to support Unicode song file iteration on windows, this is no worse than what we had before, but is not complete.. oh this code only supports win 2000 and up .. no Win 98... git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@533 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to '')
-rw-r--r--Game/Code/Classes/UAudio_FFMpeg.pas153
1 files changed, 102 insertions, 51 deletions
diff --git a/Game/Code/Classes/UAudio_FFMpeg.pas b/Game/Code/Classes/UAudio_FFMpeg.pas
index 548fb343..35822a3b 100644
--- a/Game/Code/Classes/UAudio_FFMpeg.pas
+++ b/Game/Code/Classes/UAudio_FFMpeg.pas
@@ -7,6 +7,8 @@ This unit is primarily based upon -
and tutorial03.c
+ http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html
+
*******************************************************************************)
interface
@@ -25,10 +27,10 @@ uses Classes,
{$IFNDEF FPC}
Forms,
{$ENDIF}
+ SDL, // Used for Audio output Interface
avcodec, // FFMpeg Audio file decoding
avformat,
avutil,
- SDL, // Used for Audio output Interface
ULog,
UMusic;
@@ -47,19 +49,28 @@ type
function packet_queue_get(var aPacketQueue : TPacketQueue; var AVPacket : TAVPacket; block : integer ): integer;
procedure packet_queue_init( var aPacketQueue : TPacketQueue );
procedure audio_callback( userdata: Pointer; stream: PUInt8; len: Integer ); cdecl;
- function audio_decode_frame(aCodecCtx : TAVCodecContext; audio_buf : PUInt8; buf_size: integer): integer;
+ function audio_decode_frame(aCodecCtx : TAVCodecContext; aAudio_buf : PUInt8; buf_size: integer): integer;
var
singleton_MusicFFMpeg : IAudioPlayback = nil;
+var
+ audioq : TPacketQueue;
+ quit : integer = 0;
+// faudio_buf : array[ 0 .. 0 ] of byte; //pUInt8{$ifndef fpc};{$else} = nil;{$endif}
+// audio_buf : array[ 0 .. AVCODEC_MAX_AUDIO_FRAME_SIZE ] of byte; //pUInt8{$ifndef fpc};{$else} = nil;{$endif}
+
+type
+ Taudiobuff = array[ 0 .. AVCODEC_MAX_AUDIO_FRAME_SIZE ] of byte;
+ PAudioBuff = ^Taudiobuff;
implementation
uses
{$IFDEF FPC}
lclintf,
- {$ENDIF}
libc,
+ {$ENDIF}
// URecord,
UIni,
UMain,
@@ -82,9 +93,6 @@ type
const
ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open');
-var
- audioq : TPacketQueue;
- quit : integer = 0;
type
@@ -154,7 +162,7 @@ end;
constructor TAudio_ffMpeg.create();
begin
- writeln( 'UVideo_FFMpeg - av_register_all' );
+// writeln( 'UVideo_FFMpeg - av_register_all' );
av_register_all;
end;
@@ -170,20 +178,20 @@ begin
i := 0;
while ( i < aFormatCtx.nb_streams ) do
begin
- writeln( ' aFormatCtx.streams[i] : ' + inttostr( i ) );
+// writeln( ' aFormatCtx.streams[i] : ' + inttostr( i ) );
st := aFormatCtx.streams[i];
if(st.codec.codec_type = CODEC_TYPE_VIDEO ) AND
(aFirstVideoStream < 0) THEN
begin
- writeln( 'Found Video Stream' );
+// writeln( 'Found Video Stream' );
aFirstVideoStream := i;
end;
if ( st.codec.codec_type = CODEC_TYPE_AUDIO ) AND
( aFirstAudioStream < 0) THEN
begin
- writeln( 'Found Audio Stream' );
+// writeln( 'Found Audio Stream' );
aFirstAudioStream := i;
end;
@@ -206,8 +214,8 @@ var
S: integer;
begin
- LoadSoundFromFile(BassStart, SoundPath + 'foo fighters - best of you.mp3');
-
+// LoadSoundFromFile(BassStart, SoundPath + 'Green Day - American Idiot.mp3');
+
(*
LoadSoundFromFile(BassStart, SoundPath + 'Common start.mp3');
LoadSoundFromFile(BassBack, SoundPath + 'Common back.mp3');
@@ -438,12 +446,13 @@ end;
procedure TAudio_ffMpeg.StopCard(Card: byte);
begin
+
// TODO : jb_linux replace with something other than bass
// BASS_RecordSetDevice(Card);
// BASS_RecordFree;
end;
-function audio_decode_frame(aCodecCtx : TAVCodecContext; audio_buf : PUInt8; buf_size: integer): integer;
+function audio_decode_frame(aCodecCtx : TAVCodecContext; aAudio_buf : PUInt8; buf_size: integer): integer;
var
pkt : TAVPacket;
audio_pkt_data : pchar;//PUInt8 = nil;
@@ -451,26 +460,44 @@ var
len1 ,
data_size : integer;
begin
-// result := 1;
-// exit;
+ {$ifdef win32}
+ FillChar(pkt, sizeof(pkt), #0);
+ {$else}
+ memset(@pkt, 0, sizeof(pkt)); // todo : jb memset
+ {$endif}
+
+ audio_pkt_data := nil;
+ audio_pkt_size := 0;
while true do
begin
while ( audio_pkt_size > 0 ) do
begin
- writeln( 'got audio packet' );
+// writeln( 'got audio packet' );
data_size := buf_size;
-
-// len1 := avcodec_decode_audio2(aCodecCtx, (int16_t )audio_buf, &data_size, audio_pkt_data, audio_pkt_size);
- len1 := avcodec_decode_audio(@aCodecCtx, PWord( audio_buf ), data_size, audio_pkt_data, audio_pkt_size); // Todo.. should be avcodec_decode_audio2 but this wont link on my ubuntu box.
+
+ len1 := -1;
+
+ if aAudio_buf <> nil then
+ begin
+// writeln( 'pre avcodec_decode_audio' );
+ {$ifdef fpc}
+ len1 := avcodec_decode_audio(@aCodecCtx, PWord( aAudio_buf ), data_size, audio_pkt_data, audio_pkt_size); // Todo.. should be avcodec_decode_audio2 but this wont link on my ubuntu box.
+ {$else}
+ len1 := avcodec_decode_audio(@aCodecCtx, Pointer( aAudio_buf ), data_size, audio_pkt_data, audio_pkt_size); // Todo.. should be avcodec_decode_audio2 but this wont link on my ubuntu box.
+ {$endif}
+// writeln( 'post avcodec_decode_audio' );
+
+ end;
// writeln('avcodec_decode_audio');
if(len1 < 0) then
begin
//* if error, skip frame */
- audio_pkt_size := 0;
+// writeln( 'Skip audio frame' );
+ audio_pkt_size := 0;
break;
end;
@@ -506,7 +533,7 @@ begin
audio_pkt_data := pchar( pkt.data );
audio_pkt_size := pkt.size;
- writeln( 'Audio Packet Size - ' + inttostr(audio_pkt_size) );
+// writeln( 'Audio Packet Size - ' + inttostr(audio_pkt_size) );
end;
end;
@@ -517,52 +544,69 @@ var
audio_size ,
len1 : integer;
aCodecCtx : TAVCodecContext;
- audio_buf : pUInt8 = nil;
+
+ lSrc : pointer;
+
+ // this is used to emulate ...... static uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
+ lAudio_buf_data : Taudiobuff; // This created the memory we need
+ laudio_buf : PAudioBuff; // this makes it easy to work with.. since its the pointer to that memeory everywhere
begin
- aCodecCtx := pAVCodecContext(userdata)^;
- audio_buf := UInt8( (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) div 2); // todo : JB
- audio_size := -1;
+ laudio_buf := @lAudio_buf_data ;
-// writeln('----------- audio callback' );
+ aCodecCtx := pAVCodecContext(userdata)^;
+ audio_size := -1;
+ audio_buf_index := 0;
+ audio_buf_size := 0;
while (len > 0) do
begin
if(audio_buf_index >= audio_buf_size) then
begin
// We have already sent all our data; get more */
- audio_size := audio_decode_frame(aCodecCtx, audio_buf, sizeof(audio_buf));
+ audio_size := audio_decode_frame(aCodecCtx, pUInt8( laudio_buf ), sizeof(laudio_buf));
if(audio_size < 0) then
begin
// If error, output silence */
audio_buf_size := 1024; // arbitrary?
- memset(audio_buf, 0, audio_buf_size); // todo : jb memset
+
+ {$ifdef win32}
+ FillChar(laudio_buf, audio_buf_size, #0);
+ {$else}
+ memset(laudio_buf, 0, audio_buf_size); // todo : jb memset
+ {$endif}
end
else
begin
audio_buf_size := audio_size;
end;
-// audio_buf_index := 0; // Todo : jb - SegFault ?
+ audio_buf_index := 0; // Todo : jb - SegFault ?
end;
len1 := audio_buf_size - audio_buf_index;
if (len1 > len) then
len1 := len;
-
- memcpy(stream, PUInt8( audio_buf ) + audio_buf_index , len1);
- len := len - len1;
- stream := stream + len1;
+
+ {$ifdef win32}
+ lSrc := PUInt8( integer( laudio_buf ) + audio_buf_index );
+ CopyMemory(stream, lSrc , len1);
+ {$else}
+ memcpy(stream, PUInt8( laudio_buf ) + audio_buf_index , len1);
+ {$endif}
+
+ len := len - len1;
+ stream^ := stream^ + len1;
audio_buf_index := audio_buf_index + len1;
end;
end;
function TAudio_ffMpeg.LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
var
- L: Integer;
- pFormatCtx: PAVFormatContext;
+ L : Integer;
+ pFormatCtx : PAVFormatContext;
lVidStreamID ,
lAudStreamID : Integer;
aCodecCtx : pAVCodecContext;
@@ -578,7 +622,7 @@ begin
if FileExists(Name) then
begin
- writeln('Loading Sound: "' + Name + '"', 'LoadSoundFromFile');
+// writeln('Loading Sound: "' + Name + '"', 'LoadSoundFromFile');
// Open video file
if (av_open_input_file(pFormatCtx, pchar(Name), nil, 0, nil) > 0) then
@@ -593,11 +637,11 @@ begin
if not find_stream_ids( pFormatCtx, lVidStreamID, lAudStreamID ) then
exit;
- writeln( 'done searching for stream ids' );
+// writeln( 'done searching for stream ids' );
if lAudStreamID > -1 then
begin
- writeln( 'Audio Stream ID is : '+ inttostr( lAudStreamID ) );
+// writeln( 'Audio Stream ID is : '+ inttostr( lAudStreamID ) );
lAudioStream := pFormatCtx.streams[lAudStreamID];
aCodecCtx := lAudioStream.codec;
@@ -617,9 +661,9 @@ begin
writeln('SDL_OpenAudio: '+SDL_GetError());
exit
end;
-
- writeln( 'SDL opened audio device' );
-
+
+// writeln( 'SDL opened audio device' );
+
aCodec := avcodec_find_decoder(aCodecCtx.codec_id);
if (aCodec = nil) then
begin
@@ -629,27 +673,28 @@ begin
avcodec_open(aCodecCtx, aCodec);
- writeln( 'Opened the codec' );
+// writeln( 'Opened the codec' );
packet_queue_init( audioq );
SDL_PauseAudio(0);
- writeln( 'SDL_PauseAudio' );
+// writeln( 'SDL_PauseAudio' );
i := 0;
- while (av_read_frame(pFormatCtx, packet)>=0) do
+ while (av_read_frame(pFormatCtx, packet) >= 0) do
begin
- writeln( 'ffmpeg - av_read_frame' );
+// writeln( 'ffmpeg - av_read_frame' );
if (packet.stream_index = lAudStreamID ) then
begin
+// writeln( 'packet_queue_put' );
packet_queue_put(audioq, packet);
end
else
begin
av_free_packet(packet);
end;
-
+
// Free the packet that was allocated by av_read_frame
SDL_PollEvent(@event);
@@ -665,12 +710,14 @@ begin
*)
end;
-
+
+// halt(0);
+
// Close the codec
- avcodec_close(aCodecCtx);
+// avcodec_close(aCodecCtx);
// Close the video file
- av_close_input_file(pFormatCtx);
+// av_close_input_file(pFormatCtx);
(*
try
@@ -698,7 +745,11 @@ end;
procedure packet_queue_init(var aPacketQueue : TPacketQueue );
begin
- memset(@aPacketQueue, 0, sizeof(TPacketQueue));
+ {$ifdef win32}
+ FillChar(aPacketQueue, sizeof(TPacketQueue), #0);
+ {$else}
+ memset(@aPacketQueue, 0, sizeof(TPacketQueue));
+ {$endif}
aPacketQueue.mutex := SDL_CreateMutex();
aPacketQueue.cond := SDL_CreateCond();
@@ -710,7 +761,7 @@ var
begin
result := -1;
- writeln( 'TAudio_ffMpeg.packet_queue_put' );
+// writeln( 'TAudio_ffMpeg.packet_queue_put' );
if av_dup_packet(@AVPacket) < 0 then
exit;