aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Game/Code/Classes/UAudio_FFMpeg.pas153
-rw-r--r--Game/Code/Classes/UCommon.pas88
-rw-r--r--Game/Code/Classes/UFiles.pas20
-rw-r--r--Game/Code/Classes/USongs.pas65
-rw-r--r--Game/Code/Classes/UVideo.pas85
-rw-r--r--Game/Code/Screens/UScreenSong.pas8
-rw-r--r--Game/Code/UltraStar.dpr13
7 files changed, 311 insertions, 121 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;
diff --git a/Game/Code/Classes/UCommon.pas b/Game/Code/Classes/UCommon.pas
index af9ae82d..44ec6bb3 100644
--- a/Game/Code/Classes/UCommon.pas
+++ b/Game/Code/Classes/UCommon.pas
@@ -58,6 +58,26 @@ function AdaptFilePaths( const aPath : widestring ): widestring;
procedure ZeroMemory( Destination: Pointer; Length: DWORD );
{$ENDIF}
+{$IFDEF Win32}
+
+type
+ TSearchRecW = record
+ Time: Integer;
+ Size: Integer;
+ Attr: Integer;
+ Name: WideString;
+ ExcludeAttr: Integer;
+ FindHandle: THandle;
+ FindData: TWin32FindDataW;
+ end;
+
+ function FindFirstW(const Path: WideString; Attr: Integer; var F: TSearchRecW): Integer;
+ function FindNextW(var F: TSearchRecW): Integer;
+ procedure FindCloseW(var F: TSearchRecW);
+ function FindMatchingFileW(var F: TSearchRecW): Integer;
+ function DirectoryExistsW(const Directory: widestring): Boolean;
+{$endif}
+
implementation
function StringReplaceW(text : WideString; search, rep: WideChar):WideString;
@@ -190,7 +210,75 @@ begin
end;
{$ENDIF}
+
+
+
{$ENDIF}
+{$ifdef win32}
+function FindFirstW(const Path: widestring; Attr: Integer; var F: TSearchRecW): Integer;
+const
+ faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
+begin
+ F.ExcludeAttr := not Attr and faSpecial;
+ F.FindHandle := FindFirstFileW(PWideChar(Path), F.FindData);
+ if F.FindHandle <> INVALID_HANDLE_VALUE then
+ begin
+ Result := FindMatchingFileW(F);
+ if Result <> 0 then FindCloseW(F);
+ end else
+ Result := GetLastError;
+end;
+
+function FindNextW(var F: TSearchRecW): Integer;
+begin
+ if FindNextFileW(F.FindHandle, F.FindData) then
+ Result := FindMatchingFileW(F)
+ else
+ Result := GetLastError;
+end;
+
+procedure FindCloseW(var F: TSearchRecW);
+begin
+ if F.FindHandle <> INVALID_HANDLE_VALUE then
+ begin
+ Windows.FindClose(F.FindHandle);
+ F.FindHandle := INVALID_HANDLE_VALUE;
+ end;
+end;
+
+function FindMatchingFileW(var F: TSearchRecW): Integer;
+var
+ LocalFileTime: TFileTime;
+begin
+ with F do
+ begin
+ while FindData.dwFileAttributes and ExcludeAttr <> 0 do
+ if not FindNextFileW(FindHandle, FindData) then
+ begin
+ Result := GetLastError;
+ Exit;
+ end;
+ FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
+ FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi, LongRec(Time).Lo);
+ Size := FindData.nFileSizeLow;
+ Attr := FindData.dwFileAttributes;
+ Name := FindData.cFileName;
+ end;
+ Result := 0;
+end;
+
+function DirectoryExistsW(const Directory: widestring): Boolean;
+var
+ Code: Integer;
+begin
+ Code := GetFileAttributesW(PWideChar(Directory));
+ Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
+end;
+{$endif}
+
+
+
+
end.
diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas
index 7e23b42f..717d20e2 100644
--- a/Game/Code/Classes/UFiles.pas
+++ b/Game/Code/Classes/UFiles.pas
@@ -333,16 +333,22 @@ Result := False;
//Open File and set File Pointer to the beginning
AssignFile(SongFile, Song.Path + Song.FileName);
- Reset(SongFile);
+// if assinged( SongFile ) then
+ begin
+ try
+ Reset(SongFile);
- //Clear old Song Header
- ClearSong(Song);
+ //Clear old Song Header
+ ClearSong(Song);
- //Read Header
- Result := ReadTxTHeader(Song);
+ //Read Header
+ Result := ReadTxTHeader(Song);
- //And Close File
- CloseFile(SongFile);
+ //And Close File
+ finally
+ CloseFile(SongFile);
+ end;
+ end;
{except
CloseFile(SongFile);
diff --git a/Game/Code/Classes/USongs.pas b/Game/Code/Classes/USongs.pas
index 99474961..e3c54ac4 100644
--- a/Game/Code/Classes/USongs.pas
+++ b/Game/Code/Classes/USongs.pas
@@ -13,6 +13,7 @@ uses SysUtils,
{$endif}
ULog,
UTexture,
+ UCommon,
UCatCovers;
type
@@ -23,33 +24,33 @@ type
end;
TScore = record
- Name: string;
+ Name: widestring;
Score: integer;
Length: string;
end;
TSong = record
- Path: string;
- Folder: string; // for sorting by folder
- FileName: string;
+ Path: widestring;
+ Folder: widestring; // for sorting by folder
+ FileName: widestring;
// sorting methods
- Category: array of string; // I think I won't need this
- Genre: string;
- Edition: string;
- Language: string; // 0.5.0: new
+ Category: array of widestring; // I think I won't need this
+ Genre: widestring;
+ Edition: widestring;
+ Language: widestring; // 0.5.0: new
- Title: string;
- Artist: string;
+ Title: widestring;
+ Artist: widestring;
- Text: string;
- Creator: string;
+ Text: widestring;
+ Creator: widestring;
- Cover: string;
+ Cover: widestring;
CoverTex: TTexture;
- Mp3: string;
- Background: string;
- Video: string;
+ Mp3: widestring;
+ Background: widestring;
+ Video: widestring;
VideoGAP: real;
VideoLoaded: boolean; // 0.5.0: true if the video has been loaded
NotesGAP: integer;
@@ -79,7 +80,7 @@ type
procedure LoadSongList; // load all songs
procedure BrowseDir(Dir: widestring); // should return number of songs in the future
procedure Sort(Order: integer);
- function FindSongFile(Dir, Mask: string): string;
+ function FindSongFile(Dir, Mask: widestring): widestring;
end;
TCatSongs = class
@@ -133,7 +134,7 @@ end;
procedure TSongs.BrowseDir(Dir: widestring);
var
- SR: TSearchRec; // for parsing Songs Directory
+ SR: TSearchRecW; // for parsing Songs Directory
SLen: integer;
{$ifndef win32}
@@ -144,16 +145,16 @@ var
{$endif}
begin
{$ifdef win32}
- if FindFirst(Dir + '*', faDirectory, SR) = 0 then // JB_Unicode - windows
+ if FindFirstW(Dir + '*', faDirectory, SR) = 0 then // JB_Unicode - windows
begin
repeat
if (SR.Name <> '.') and (SR.Name <> '..') then
begin
BrowseDir(Dir + Sr.Name + PathDelim);
end
- until FindNext(SR) <> 0;
+ until FindNextw(SR) <> 0;
end; // if
- FindClose(SR);
+ FindClosew(SR);
{$else}
// Itterate the Songs Directory... ( With unicode capable functions for linux )
TheDir := opendir( Dir ); // JB_Unicode - linux
@@ -178,7 +179,7 @@ begin
// Log.LogStatus('Parsing directory: ' + Dir + SR.Name, 'LoadSongList');
- if FindFirst(Dir + '*.txt', 0, SR) = 0 then
+ if FindFirstW(Dir + '*.txt', 0, SR) = 0 then
begin
repeat
SLen := BrowsePos;
@@ -204,9 +205,9 @@ begin
SetLength(Song, Length(Song) + 50);
end;
- until FindNext(SR) <> 0;
+ until FindNextW(SR) <> 0;
end; // if FindFirst
- FindClose(SR);
+ FindCloseW(SR);
end;
procedure TSongs.Sort(Order: integer);
@@ -309,7 +310,7 @@ begin
end; // case
end;
-function TSongs.FindSongFile(Dir, Mask: string): string;
+function TSongs.FindSongFile(Dir, Mask: widestring): widestring;
var
SR: TSearchRec; // for parsing song directory
begin
@@ -463,10 +464,12 @@ case Ini.Sorting of
CatSongs.Song[CatLen].Visible := true;
end
- else if (Ini.Sorting = sTitle) and (Length(Songs.Song[S].Title)>=1) and (Letter <> UpCase(Songs.Song[S].Title[1])) then begin
+ else if (Ini.Sorting = sTitle) and
+ (Length(Songs.Song[S].Title)>=1) and
+ (Letter <> UpperCase(Songs.Song[S].Title)[1]) then begin
// add a letter Category Button
Inc(Order);
- Letter := UpCase(Songs.Song[S].Title[1]);
+ Letter := Uppercase(Songs.Song[S].Title)[1];
CatLen := Length(CatSongs.Song);
SetLength(CatSongs.Song, CatLen+1);
CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
@@ -491,10 +494,10 @@ case Ini.Sorting of
CatSongs.Song[CatLen].Visible := true;
end
- else if (Ini.Sorting = sArtist) and (Length(Songs.Song[S].Artist)>=1) and (Letter <> UpCase(Songs.Song[S].Artist[1])) then begin
+ else if (Ini.Sorting = sArtist) and (Length(Songs.Song[S].Artist)>=1) and (Letter <> UpperCase(Songs.Song[S].Artist)[1]) then begin
// add a letter Category Button
Inc(Order);
- Letter := UpCase(Songs.Song[S].Artist[1]);
+ Letter := UpperCase(Songs.Song[S].Artist)[1];
CatLen := Length(CatSongs.Song);
SetLength(CatSongs.Song, CatLen+1);
CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
@@ -545,7 +548,7 @@ case Ini.Sorting of
end
else if (Ini.Sorting = sTitle2) AND (Length(Songs.Song[S].Title)>=1) then begin
- if (ord(Songs.Song[S].Title[1]) > 47) and (ord(Songs.Song[S].Title[1]) < 58) then Letter2 := '#' else Letter2 := UpCase(Songs.Song[S].Title[1]);
+ if (ord(Songs.Song[S].Title[1]) > 47) and (ord(Songs.Song[S].Title[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(Songs.Song[S].Title)[1];
if (Letter <> Letter2) then begin
// add a letter Category Button
Inc(Order);
@@ -575,7 +578,7 @@ case Ini.Sorting of
end
else if (Ini.Sorting = sArtist2) AND (Length(Songs.Song[S].Artist)>=1) then begin
- if (ord(Songs.Song[S].Artist[1]) > 47) and (ord(Songs.Song[S].Artist[1]) < 58) then Letter2 := '#' else Letter2 := UpCase(Songs.Song[S].Artist[1]);
+ if (ord(Songs.Song[S].Artist[1]) > 47) and (ord(Songs.Song[S].Artist[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(Songs.Song[S].Artist)[1];
if (Letter <> Letter2) then begin
// add a letter Category Button
Inc(Order);
diff --git a/Game/Code/Classes/UVideo.pas b/Game/Code/Classes/UVideo.pas
index 4c27867d..154cd04c 100644
--- a/Game/Code/Classes/UVideo.pas
+++ b/Game/Code/Classes/UVideo.pas
@@ -10,9 +10,11 @@ unit UVideo;
# #
############################################################################## }
-{$define DebugDisplay} // uncomment if u want to see the debug stuff
+//{$define DebugDisplay} // uncomment if u want to see the debug stuff
//{$define DebugFrames}
//{$define Info}
+
+//{$define FFMpegAudio}
{}
@@ -45,6 +47,9 @@ uses SDL,
dialogs,
{$endif}
{$ENDIF}
+ {$ifdef FFMpegAudio}
+ UAudio_FFMpeg,
+ {$endif}
UIni,
UMusic;
@@ -108,7 +113,9 @@ type
end;
-
+ const
+ SDL_AUDIO_BUFFER_SIZE = 1024;
+
{$ifdef DebugDisplay}
//{$ifNdef win32}
@@ -262,19 +269,23 @@ begin
FrameFinished:=0;
// read packets until we have a finished frame (or there are no more packets)
-// while (FrameFinished=0) and (av_read_frame(VideoFormatContext, @AVPacket)>=0) do
- while (FrameFinished=0) and (av_read_frame(VideoFormatContext, AVPacket)>=0) do // JB-ffmpeg
+ while ( FrameFinished = 0 ) and
+ ( av_read_frame(VideoFormatContext, AVPacket) >= 0 ) do // JB-ffmpeg
begin
// if we got a packet from the video stream, then decode it
if (AVPacket.stream_index=VideoStreamIndex) then
-// errnum:=avcodec_decode_video(VideoCodecContext, AVFrame, @frameFinished , AVPacket.data, AVPacket.size);
+ begin
errnum := avcodec_decode_video(VideoCodecContext, AVFrame, frameFinished , AVPacket.data, AVPacket.size); // JB-ffmpeg
-
-
- // release internal packet structure created by av_read_frame
-// av_free_packet(PAVPacket(@AVPacket));
+ {$ifdef FFMpegAudio}
+ end
+ else
+ if (AVPacket.stream_index = AudioStreamIndex ) then
+ begin
+ UAudio_FFMpeg.packet_queue_put(UAudio_FFMpeg.audioq, AVPacket);
+ {$endif}
+ end;
try
if AVPacket.data <> nil then
@@ -427,6 +438,10 @@ var
errnum, i, x,y: Integer;
lStreamsCount : Integer;
+ wanted_spec ,
+ spec : TSDL_AudioSpec;
+ aCodec : pAVCodec;
+
begin
fVideoOpened := False;
fVideoPaused := False;
@@ -471,27 +486,47 @@ begin
end;
aCodecCtx := VideoFormatContext.streams[ AudioStreamIndex ].codec;
+ {$ifdef FFMpegAudio}
+ // This is the audio ffmpeg audio support Jay is working on.
if aCodecCtx <> nil then
begin
+ wanted_spec.freq := aCodecCtx.sample_rate;
+ wanted_spec.format := AUDIO_S16SYS;
+ wanted_spec.channels := aCodecCtx.channels;
+ wanted_spec.silence := 0;
+ wanted_spec.samples := SDL_AUDIO_BUFFER_SIZE;
+ wanted_spec.callback := UAudio_FFMpeg.audio_callback;
+ wanted_spec.userdata := aCodecCtx;
-// WantedAudioCodecContext.freq := aCodecCtx^.sample_rate;
-// WantedAudioCodecContext.format := AUDIO_S16SYS;
-// WantedAudioCodecContext.channels := aCodecCtx^.channels;
-(* WantedAudioCodecContext.silence := 0;
- WantedAudioCodecContext.samples := 1024;//SDL_AUDIO_BUFFER_SIZE;
-// WantedAudioCodecContext.callback := audio_callback;
- WantedAudioCodecContext.userdata := aCodecCtx;
-*)
+
+ if (SDL_OpenAudio(@wanted_spec, @spec) < 0) then
+ begin
+ writeln('SDL_OpenAudio: '+SDL_GetError());
+ exit;
+ end;
+
+ writeln( 'SDL opened audio device' );
+
+ aCodec := avcodec_find_decoder(aCodecCtx.codec_id);
+ if (aCodec = nil) then
+ begin
+ writeln('Unsupported codec!');
+ exit;
+ end;
+
+ avcodec_open(aCodecCtx, aCodec);
+
+ writeln( 'Opened the codec' );
+
+ packet_queue_init( audioq );
+ SDL_PauseAudio(0);
+
+ writeln( 'SDL_PauseAudio' );
+
end;
-(*
- if(SDL_OpenAudio(WantedAudioCodecContext, AudioCodecContext) < 0) then
- begin
- writeln( 'Could not do SDL_OpenAudio' );
- exit;
- end;
-*)
-
+ {$endif}
+
if(VideoStreamIndex >= 0) then
begin
VideoCodecContext:=VideoFormatContext^.streams[VideoStreamIndex]^.codec;
diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas
index ea1dd8a5..4d146283 100644
--- a/Game/Code/Screens/UScreenSong.pas
+++ b/Game/Code/Screens/UScreenSong.pas
@@ -261,7 +261,9 @@ begin
begin
For I := 1 to high(CatSongs.Song) do
begin
- if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) AND (UpCase(CatSongs.Song[(I + Interaction) mod I2].Title[1]) = Letter) then
+ if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND
+ (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) AND
+ (widechar(UpperCase(CatSongs.Song[(I + Interaction) mod I2].Title)[1]) = widechar(Letter)) then
begin
SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
@@ -280,7 +282,9 @@ begin
begin
For I := 1 to high(CatSongs.Song) do
begin
- if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) AND (UpCase(CatSongs.Song[(I + Interaction) mod I2].Artist[1]) = Letter) then
+ if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND
+ (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) AND
+ (widechar(uppercase(CatSongs.Song[(I + Interaction) mod I2].Artist)[1]) = widechar(Letter)) then
begin
SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr
index 1e418a49..0b7e8449 100644
--- a/Game/Code/UltraStar.dpr
+++ b/Game/Code/UltraStar.dpr
@@ -59,8 +59,6 @@ uses
UCommon in 'Classes\UCommon.pas',
UGraphic in 'Classes\UGraphic.pas',
UTexture in 'Classes\UTexture.pas',
- UMusic in 'Classes\UMusic.pas',
- UAudio_Bass in 'Classes\UAudio_Bass.pas',
ULanguage in 'Classes\ULanguage.pas',
UMain in 'Classes\UMain.pas',
UDraw in 'Classes\UDraw.pas',
@@ -100,10 +98,14 @@ uses
UParty in 'Classes\UParty.pas', // to - do : rewrite Party Manager as Module, reomplent ability to offer party Mody by Plugin
//------------------------------
- //Includes - Video Support
+ //Includes - Media support classes....
+ // Make sure UMedia always first, then UMedia_dummy
//------------------------------
- UMedia_dummy in 'Classes\UMedia_dummy.pas',
- UVideo in 'Classes\UVideo.pas',
+ UMusic in 'Classes\UMusic.pas',
+ UMedia_dummy in 'Classes\UMedia_dummy.pas',
+ UVideo in 'Classes\UVideo.pas',
+// UAudio_FFMpeg in 'Classes\UAudio_FFMpeg.pas', // this is NEARLY to a working point :P
+ UAudio_Bass in 'Classes\UAudio_Bass.pas',
//------------------------------
//Includes - Screens
@@ -330,6 +332,7 @@ begin
Log.BenchmarkEnd(1);
Log.LogBenchmark('Initializing Sound', 1);
+// exit;
// Graphics
Log.BenchmarkStart(1);