Autor |
Beitrag |
Grunz
Hält's aus hier
Beiträge: 5
|
Verfasst: So 02.03.03 15:06
Hallo.
Weiß einer von euch wie ich einen kleinen Radio Player machen kann der Sender von www.shoutcast.com abspielen kann?
Vielleicht könnt ihr mir da ja helfen
MfG
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: So 02.03.03 17:27
Am einfachsten wird das mit FMOD oder BASS. Beide beherrschen Internetstreaming. Ich würde eher FMOD empfehlen. Ich habe es noch ncht ausprobiert, aber auf der HP steht, daß man einfach die URL der Datei übergeben muss, und schon wird die Datei über's Internet empfangen. Lad' dir einfach die beiden SDKs runter (sind nicht sonderlich groß) und lies' dir die Abschnitte über Streaming oder Internet durch.
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
Grunz 
Hält's aus hier
Beiträge: 5
|
Verfasst: So 02.03.03 19:15
danke für die Antwort.
Leider ist das nur für freeware projekte.
Gibt es nicht irgendwo so ein paar tipps oder beispiele?
MfG
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: So 02.03.03 19:28
also gratis wirst du außer MAD wahrscheinlich nichtmal 'nen Codec finden, geschweige denn ein Soundsystem daß die Ausgabe und das Resampling auch noch erledigt.
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
Grunz 
Hält's aus hier
Beiträge: 5
|
Verfasst: So 02.03.03 20:59
was meinst du mit MAD ?
Ich will ja eigentlich nur dass der die Sounds von einer Adresse(die Shoutcast Sender) praktisch runterläd damit ich das dann gleichzeitig abspielen kann und so hätte ich doch ein einfaches radio  ?
MfG
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: So 02.03.03 21:12
Die Dateien sind im MP3- oder Ogg-Format. Du musst sie also vorher dekodieren. Wenn du keinen eigenen Algo proggen willst, brauchst du eine Fremd-DLL. Also entweder MAD, oder BASS/FMOD.
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
Grunz 
Hält's aus hier
Beiträge: 5
|
Verfasst: Mo 03.03.03 14:42
danke  .
aber wieso muss ich die denn dekodieren?
Ich kann doch die .mp3 daten mit dem tmediaplayer abpsielen?
Hast du eine URL zu dem MOD?
MfG
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Mo 03.03.03 15:44
ach so, du willst den TMediaPlayer benutzen. Dann brauchst du keinen anderen Decoder (für MP3). Aber ich weiß nicht, ob der TMediaPlayer streaming zulässt, also auch Dateien öffnet, die noch nicht vollständig runtergeladen sind.
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
Grunz 
Hält's aus hier
Beiträge: 5
|
Verfasst: Mo 03.03.03 16:00
das wäre ja auch nicht schlimm.
ich könnte doch das ganze z.B. in ner .mp3 datei speichern und dann die streams immer drauf tun?
nur es wäre natürlich besser wenn es mit streams gehen würde.
Habe mich gerade mit den Indy VCL rumgeschlagen.Habe gehört dass es mit denen gehen soll. Nur wie?
MfG
|
|
Jebaz
      
Beiträge: 44
Win NT 4, Win XP, Linux
Delphi 7.0
|
Verfasst: Di 15.07.03 16:28
Titel: tolles Webradio Problem
Hei Leute
ich hab schon ne ewigkeit nicht mehr hier gepostet..finde es aber nach wie vor das beste Delphi Forum
AAlssoo..ich bin seit Monaten an einem (inzwischen genialen) Delphi-Chat..Emoticons und Chatroom-System und so zimlich alles was ich wollte hab ich inzwischen implementiert...da kam mir die Idee..für jeden Room mit dem passenden Web-Radio zu connecten...schöne Idee nicht?
Nun, ich hab fmod ausprobiert und Bassdingsda...und naja, fmod hat wenigstens noch beispiele dabei wie man so was macht..leider sind das alles Konsolen-Anwendungen.. Ich hab soeben versucht, den Code einer solchen Anwendung in eine normale Form-basierte Objektorientierte Applikation zu portieren, woran ich kläglich scheiterte... fmod ist verdammt kompliziert muss ich sagen, nur schon in der Hilfe gibts nur für Streams ein eigenes Kabitel und naja, sieht nach einer eigenen Wissenschaft aus für mich..
Gibt es heutzutage im Zeitalter der Gratis-Komponenten nicht irgend etwas einfach brauchbares? Gut, ich könnte mit Winamp den Stream öffnen und mit einem Winamp-API darauf zugreifen...was aber sehr wenig Sinn macht...
 es muss doch was geben...
_________________ ...and You will Know us By the Trail of Death.....
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Di 15.07.03 17:00
Man könnte bei Torry oder ähnlichen Seiten nach einem Wrapper für FMod suchen. Aber ob es einen gibt, weiß ich nicht.
Ich finde FMod recht überischtlich und einfach, zumindest was das Streaming angeht (mit 3D-Sound habe ich noch nicht gearbeitet, schon allein weil ich kein 4.1-Boxensystem für meine Soundkarte habe).
Du kannst dir natürlich auch selber 'nen Wrapper schreiben, aber den Aufwand halte ich für zu groß, wenn du ihn nicht öfter brauchst oder seperat veröffentlichen willst.
Wenn du Probleme hast (vor allem mit FMod, BASS liegt zu lange zurück...), kannst du mir ja 'ne Mail schreiben.
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
Jebaz
      
Beiträge: 44
Win NT 4, Win XP, Linux
Delphi 7.0
|
Verfasst: Mi 16.07.03 10:33
Titel: Nachgeschaut
Halloooo allerseits, danke vielmals tommie-lie
ich hab dir noch ne mail geschrieben, falls du diesen eintrag vor dem mail sehen solltest
also wrapper habe ich gesucht, jedoch nicht sinnvolles gefunden...lediglich irgendwelche tools die files aus einem .cab file entpacken können und anderes.....jedoch ist von einem internet-radio mit fmod realisiert nichts zu sehen im ganzen netz...(komisch)
ich hab auch nochmals die console-app-samples die streams playen genauer angeschaut....der code sieht mit der zeit nicht mehr so schwer aus...nur finde ich komisch, dass ich keinen code gefunden habe...der sagt, welcher stream überhaupt gespielt werden soll....? keine url, kein file...einfach nichts, da wird lediglich der stream gestartet mit dem befehl
Quelltext 1: 2: 3: 4: 5:
| Stream := FSOUND_Stream_Create(StreamCallback, 1000 * 2 * 2, FSOUND_NORMAL or FSOUND_16BITS or FSOUND_STEREO, 22050, 12345);
//und dann
Channel := FSOUND_Stream_Play(FSOUND_FREE, Stream); |
ich dachte dann, die StreamCallback function würde da vieleicht etwas definieren....aber da wahr ich auch an der falschen adresse...langsam glaube ich, dass fmod gar keine online streams abspielen kann....was aber auf der feature-list der fmod site anders aussieht....
was mir auch aufgefallen ist....alle internet-radio-player die es fertig zum downloaden gibt (zumindest die die ich gefunden habe) benötigen den real-player auf dem ziel-system....also wird da lediglich auf den output des realplayers zugegriffen, und der realplayer verbindet dann auf die online streams, oder nicht? das könnte ich schon lange mit winamp tun...komisch
naja, auf jeden fall vielen dank für deine hilfe tommie-lie....vieleicht gibts ja mal eine realplayer komponente für delphi 
_________________ ...and You will Know us By the Trail of Death.....
|
|
Jebaz
      
Beiträge: 44
Win NT 4, Win XP, Linux
Delphi 7.0
|
Verfasst: Mi 16.07.03 10:38
Titel: ach ja
übrigens, ich hab noch ne mail an einen der fmod-entwickler, der das ganze auf delphi portiert hat geschrieben, und nach einer halben stunde ne antwort gekriegt
dieser hat keine ahnung ob fmod das ermöglicht, aber er meinte, er werde es heute nacht einmal ausprobieren und fragte mich nach einer adresse, von der ich streams playen möchte...ich gab mal [url] www.shoutcast.com[/url] an....morgen weiss ich hoffentlich mehr von offizieller seite 
_________________ ...and You will Know us By the Trail of Death.....
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Mi 16.07.03 14:49
Mail zurück *g*
Den RealPlayer brauchen die ganzen Webradios wohl nur für die Dekodierung der Audiodateien. FMod unterstützt aber von sich aus den MP3-Codec, benötigt also beim MP3-Streaming den RealPlayer nicht mehr. Für Dateien im RealAudio-Format sieht es natürlich anders aus. AFAIK gibt es nur den RealPlayer, weil das Format nicht freigelegt wurde. Wenn du also RealAudio-Dateien abspielen willst, wirst du wohl auf den RealPlayer zurückgreifen müssen.
Für alle die meine Mails nicht kriegen *g*:
Internetstreaming funktioniert in FMod wie das abspielen von Dateien mit FSound_Stream_OpenFile, nur daß anstatt einem Dateinamen die URL der Datei im Internet angegeben wird. Auf das Flag MPEG_ACCURATE sollte dabei verzichtet werden, ich weiß nicht ob FMod beim Internet-Streaming dieses automatisch ignoriert.
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
Wishmaster
      
Beiträge: 34
|
Verfasst: Mi 16.06.04 03:13
Titel: Bass code
bass v1.6 /1.7/1.8
unit CommonTypes;
interface
uses Windows;
Type TEqPreset = array [0..9] of Integer;
Type TWaveData = array [0..2048] of DWORD;
Type TFFTData = array [0..512] of Single;
const
ENGINE_CST_OFFSET = 1000;
ENGINE_STOP = ENGINE_CST_OFFSET + 1;
ENGINE_PLAY = ENGINE_CST_OFFSET + 2;
ENGINE_PAUSE = ENGINE_CST_OFFSET + 3;
ENGINE_SONG_END = ENGINE_CST_OFFSET + 4;
ENGINE_ON_LINE = ENGINE_CST_OFFSET + 5;
const
ECHBUFLEN = 1200; // buffer length
FLABUFLEN = 350; // buffer length
implementation
end.
[code]
unit AudioEngine;
interface
uses Windows, Bass, Dialogs, Forms, Controls, StdCtrls,
Classes, ExtCtrls, SysUtils, CommonTypes;
Type TAudioEngine = Class(TObject)
private
Channel : DWORD;
WaveFreq : Integer;
PlayerState : Integer;
SongLength : Integer;
DeviceIDX : Integer;
AppHWND : THandle;
EqParam : array [0..9] of HFX;
EQBands : array [0..9] of Integer;
NullWave : TWaveData;
NullFFT : TFFTData;
CurPreset : TEqPreset;
UseEQ : Boolean;
DevList : TStringList;
CurFileName : String;
EventTimer : TTimer;
URLSaveFile : String;
MonoAudio : Boolean;
WriteToFile : Boolean;
WriteDir : String;
DevVolume : Single;
FFadeOut : Boolean;
FFadeIn : Boolean;
FFadeTime : LongInt;
stream: HSTREAM;
procedure NotifyState (Sender : TObject);
procedure CreateEqualyzer;
procedure DecodeFile(OutPath : String);
public
constructor Create (HWND : THandle); virtual;
destructor Destroy;
procedure Play (FileName : String); virtual;
function PlayURL (FileName : String) : Boolean; virtual;
procedure Pause; virtual;
procedure UnPause; virtual;
procedure Stop; virtual;
procedure InitDevice(idx : Integer);
procedure UpdateEq (aEqPreset : TEqPreset);
function CheckPlayableFile (FileName : String) : Boolean; virtual;
function GetSongPos : Integer; virtual;
function GetSongLen : Integer; virtual;
function GetCurSong : String; virtual;
function GetMainVolume : Integer;
function GetGainVolume : Integer;
function GetPanning : Integer; virtual;
function GetPitch : Integer;
function GetWaveBuffer : TWaveData; virtual;
function GetDialogFilter : String; virtual;
function GetFFTData : TFFTData; virtual;
function GetSongTitle (FileName : String): String;
function GetSongLength (FileName : String): Integer; virtual;
function GetSaveUrlFile : String;
procedure GetICYMetaBroadcast (ServerURL : String; var Name, Genere, WebURL, Bitrate, Title, TitleURL, Comment : String);
procedure GetVULevel(var R, L : Integer);
function GetBitrate : Integer;
function IsOnLine : Boolean;
procedure SetSongPos (SongPos : Integer); virtual;
procedure SetMainVolume (Vol : Integer); virtual;
procedure SetGainVolume (Vol : Integer); virtual;
procedure SetPanning (Pan : Integer); virtual;
procedure SetPitch (Ptc : Integer);
procedure SetOutBufferLen (Len : Integer);
procedure SetSaveUrlFile (FileName : String);
procedure DecodeToFile (FileOut : Boolean; OutDir : String);
property OutFrequency : Integer read WaveFreq write WaveFreq;
procedure SetEqualizer;
procedure ResetEqualizer;
property AudioDevices : TStringList read DevList;
function EngineState : Integer; virtual;
property Mono : Boolean read MonoAudio write MonoAudio;
property FadeOut : Boolean read FFadeOut write FFadeOut;
property FadeIN : Boolean read FFadeIn write FFadeIn;
property FadeTime : LongInt read FFadeTime write FFadeTime;
function Get_CPU : String;
function DSP_Rotate(YN : Boolean) : Boolean; // Rotation
function DSP_Echo(YN: Boolean) : Boolean; // Echo
function DSP_Flange(YN: Boolean) : Boolean; // Flange
end;
implementation
var
{------------------------ DSP ------------------------}
d: ^DWORD;
rotdsp: HDSP; // DSP handle
rotpos: FLOAT; // cur.pos
echdsp: HDSP; // DSP handle
echbuf: array[0..ECHBUFLEN-1, 0..1] of SmallInt; // buffer
echpos: Integer; // cur.pos
fladsp: HDSP; // DSP handle
flabuf: array[0..FLABUFLEN-1, 0..2] of SmallInt; // buffer
flapos: Integer; // cur.pos
flas, flasinc: FLOAT; // sweep pos/min/max/inc
function fmod(a, b: FLOAT): FLOAT;
begin
Result := a - (b * Trunc(a / b));
end;
function Clip(a: Integer): Integer;
begin
if a <= -32768 then a := -32768
else if a >= 32767 then a := 32767;
Result := a;
end;
procedure Rotate(handle: HDSP; channel: DWORD; buffer: Pointer; length, user: DWORD); stdcall;
var
lc, rc: SmallInt;
begin
d := buffer;
while (length > 0) do
begin
lc := LOWORD(d^); rc := HIWORD(d^);
lc := SmallInt(Trunc(sin(rotpos) * lc));
rc := SmallInt(Trunc(cos(rotpos) * rc));
d^ := MakeLong(lc, rc);
Inc(d);
rotpos := rotpos + fmod(0.00003, PI);
length := length - 4;
end;
end;
procedure Echo(handle: HDSP; channel: DWORD; buffer: Pointer; length, user: DWORD); stdcall;
var
lc, rc: SmallInt;
l, r: Integer;
begin
d := buffer;
while (length > 0) do
begin
lc := LOWORD(d^); rc := HIWORD(d^);
l := lc + (echbuf[echpos, 1] div 2);
r := rc + (echbuf[echpos, 0] div 2);
echbuf[echpos, 0] := lc;
echbuf[echpos, 1] := rc;
lc := Clip(l);
rc := Clip(r);
d^ := MakeLong(lc, rc);
Inc(d);
Inc(echpos);
if (echpos = ECHBUFLEN) then
echpos := 0;
length := length - 4;
end;
end;
procedure Flange(handle: HDSP; channel: DWORD; buffer: Pointer; length, user: DWORD); stdcall;
var
lc, rc: SmallInt;
p1, p2, s: Integer;
f: FLOAT;
begin
d := buffer;
while (length > 0) do
begin
lc := LOWORD(d^); rc := HIWORD(d^);
p1 := (flapos + Trunc(flas)) mod FLABUFLEN;
p2 := (p1 + 1) mod FLABUFLEN;
f := fmod(flas, 1.0);
s := lc + Trunc(((1.0-f) * flabuf[p1, 0]) + (f * flabuf[p2, 0]));
flabuf[flapos, 0] := lc;
lc := Clip(s);
s := rc + Trunc(((1.0-f) * flabuf[p1, 1]) + (f * flabuf[p2, 1]));
flabuf[flapos, 1] := rc;
rc := Clip(s);
d^ := MakeLong(lc, rc);
Inc(d);
Inc(flapos);
if (flapos = FLABUFLEN) then flapos := 0;
flas := flas + flasinc;
if (flas < 0) or (flas > FLABUFLEN) then
flasinc := -flasinc;
length := length - 4;
end;
end;
function TaudioEngine.DSP_Rotate(YN: Boolean) : Boolean; // Rotation
begin
if YN = true then
begin
rotpos := 0.7853981;
rotdsp := BASS_ChannelSetDSP(Channel, Rotate, 0);
end
else
BASS_ChannelRemoveDSP(Channel, rotdsp);
end;
function TaudioEngine.DSP_Echo(YN: Boolean) : Boolean; // Echo
begin
if YN = true then
begin
FillChar(echbuf, SizeOf(echbuf), 0);
echpos := 0;
echdsp := BASS_ChannelSetDSP(Channel, Echo, 0);
end
else
BASS_ChannelRemoveDSP(Channel, echdsp);
end;
function TaudioEngine.DSP_Flange(YN: Boolean) : Boolean; // Flange
begin
if YN = true then
begin
FillChar(flabuf, SizeOf(flabuf), 0);
flapos := 0;
flas := FLABUFLEN / 2;
flasinc := 0.002;
fladsp := BASS_ChannelSetDSP(Channel, Flange, 0);
end
else
BASS_ChannelRemoveDSP(Channel, fladsp);
end;
{--------------- NotifyState --------------}
procedure TAudioEngine.NotifyState (Sender : TObject);
var NetFile : Boolean;
begin
if (FFadeOut) and (GetSongLen - GetSongPos < FFadeTime) then
DevVolume := 100 * ((GetSongLen - GetSongPos) / FFadeTime);
if (FFadeIn) and (GetSongPos < FFadeTime) then
DevVolume := 100 * (GetSongPos / FFadeTime);
if DevVolume > 100 then
DevVolume := 100;
if DevVolume < 0 then
DevVolume := 0;
BASS_ChannelSetAttributes(Channel, -1, Trunc(DevVolume), -1);
if WriteToFile then
exit;
if (Pos('HTTP://', UpperCase(GetCurSong)) > 0) or
(Pos('FTP://', UpperCase(GetCurSong)) > 0) then
Exit;
if ((GetSongPos >= GetSongLen - 50) and not (PlayerState = ENGINE_STOP)) then
begin
Stop;
DevVolume := 100;
PlayerState := ENGINE_SONG_END;
Exit;
end;
if Not FileExists(CurFileName) then
begin
PlayerState := ENGINE_STOP; Exit; end;
end;
{--------------- EngineState --------------}
function TAudioEngine.EngineState : Integer;
begin
Result := PlayerState;
end;
{--------------- Create --------------}
constructor TAudioEngine.Create (HWND : THandle);
var i : integer; DevChar : PChar;
begin
WriteToFile := False;
WaveFreq := 44100;
AppHWND := HWND;
DeviceIDX := -1;
EQBands[0] := 80;
EQBands[1] := 170;
EQBands[2] := 310;
EQBands[3] := 600;
EQBands[4] := 1000;
EQBands[5] := 3000;
EQBands[6] := 6000;
EQBands[7] := 10000;
EQBands[8] := 12000;
EQBands[9] := 14000;
for i := 0 to 9 do
EqParam[i] := 0;
{ Calculating Null Arrays}
for i := 0 to 255 do NullWave[i] := 0;
for i := 0 to 255 do NullFFT[i] := 0;
UseEQ := False;
PlayerState := ENGINE_STOP;
InitDevice(DeviceIDX);
DevList := TStringList.Create;
i := 0;
while (BASS_GetDeviceDescription(i) <> nil ) do
begin
DevChar := BASS_GetDeviceDescription(i);
inc(i);
DevList.Add(DevChar);
end;
rotdsp := 0;
echdsp := 0;
fladsp := 0;
DevVolume := 100;
FFadeTime := 5000;
FFadeIn := False;
FFadeOut := False;
SetOutBufferLen(500);
EventTimer := TTimer.Create (nil);
EventTimer.Interval := 1;
EventTimer.OnTimer := NotifyState;
EventTimer.Enabled := True;
end;
{--------------- Destroy --------------}
destructor TAudioEngine.Destroy;
begin
Stop;
Bass_Stop;
Bass_Free;
end;
{-------------- InitDevice ------------}
procedure TAudioEngine.InitDevice(idx : Integer);
begin
Stop;
BASS_Stop();
BASS_Free();
BASS_Init(idx, WaveFreq, BASS_DEVICE_LEAVEVOL, AppHWND);
BASS_Start();
end;
{----------------- EQ ----------------}
procedure TAudioEngine.SetEqualizer;
begin
UpdateEq(CurPreset);
end;
procedure TAudioEngine.ResetEqualizer;
var aEqPreset : TEqPreset; i: Integer;
begin
for i := 0 to 9 do
aEqPreset[i] := 0;
UpdateEq (aEqPreset);
end;
procedure TAudioEngine.UpdateEq (aEqPreset : TEqPreset);
var EqP : BASS_FXPARAMEQ; i :Integer;
begin
CurPreset := aEqPreset;
for i := 0 to 9 do
begin
BASS_FXGetParameters(EqParam[i],@EqP);
EqP.fGain:= aEqPreset[i];
BASS_FXSetParameters(EqParam[i],@EqP);
end;
end;
procedure TAudioEngine.CreateEqualyzer;
var i, cnt : integer; EqP : BASS_FXPARAMEQ;
begin
for i := 0 to 9 do
begin
EqParam[i] := BASS_ChannelSetFX(Channel, BASS_FX_PARAMEQ);
EqP.fGain := 0;
EqP.fBandwidth := 3;
EqP.fCenter := EQBands[i];
if not BASS_FXSetParameters(EqParam[i], @EqP) then
begin
// if BASS_ERROR_HANDLE = BASS_ErrorGetCode then showmessage('h');
// if BASS_ERROR_ILLPARAM = BASS_ErrorGetCode then showmessage('ill');
// if BASS_ERROR_UNKNOWN = BASS_ErrorGetCode then showmessage('uk');
// showmessage(inttostr(i));
end;
end;
end;
{------------------- Play -------------------}
procedure TAudioEngine.Play (FileName : String);
var SngLen : Integer; Flags : DWORD;
begin
if FFadeIn then
DevVolume := 0;
if FFadeOut then
DevVolume := 100;
if Not(FFadeOut or FFadeIn) then
DevVolume := 100;
CurFileName := FileName;
if (Copy(UpperCase(FileName), 1, 7) = 'HTTP://') or
(Copy(UpperCase(FileName), 1, 6) = 'FTP://') then
begin
PlayURL(FileName);
exit;
end;
BASS_MusicFree(Channel);
BASS_StreamFree(Channel);
Flags := 0;
// if HalfBit then Flags := BASS_MP3_HALFRATE;
if MonoAudio then
Flags := Flags or
BASS_SAMPLE_MONO;
if WriteToFile then
Flags := BASS_STREAM_DECODE
else Flags := Flags or
BASS_SAMPLE_FX;
Channel := BASS_StreamCreateFile(FALSE, PChar(CurFileName), 0, 0, Flags);
if (Channel <> 0) then
SngLen := 0;
if (Channel = 0) then
Channel := BASS_MusicLoad(FALSE, PChar(CurFileName), 0, 0, BASS_MUSIC_FX);
if (Channel <> 0) then
SngLen := 0;
if (Channel = 0) then
Exit;
if (SngLen = 0) then
SongLength := BASS_StreamGetLength(Channel);
if (SngLen = 1) then
SongLength := BASS_MusicGetLength(Channel, True);
PlayerState := ENGINE_PLAY;
if not WriteToFile then
begin
{Apply Equalyzation}
CreateEqualyzer;
SetEqualizer;
BASS_StreamPlay(Channel, false, 0);
BASS_MusicPlay(Channel);
end
else
begin
DecodeFile(WriteDir);
end;
if (SngLen = 0) then
SongLength := BASS_StreamGetLength(Channel);
if (SngLen = 1) then
SongLength := BASS_MusicGetLength(Channel, True);
BASS_ChannelSetAttributes(Channel, -1, Trunc(DevVolume), -1);
PlayerState := ENGINE_PLAY;
end;
function TAudioEngine.PlayURL (FileName : String) : Boolean;
var SngLen : Integer;
begin
CurFileName := FileName;
BASS_MusicFree(Channel);
BASS_StreamFree(Channel);
Channel := BASS_StreamCreateURL(PChar(CurFileName), 0, BASS_STREAM_META, PChar(URLSaveFile));
SngLen := 0;
{Apply Equalyzation}
// CreateEqualyzer;
// SetEqualizer;
if Channel = 0 then
Result := False
else
Result := True;
if not BASS_StreamPlay(Channel, false, 0) then
Result := False;
if (SngLen = 0) then
SongLength := BASS_StreamGetLength(Channel);
PlayerState := ENGINE_PLAY;
end;
{----------------- Pause, UNPause, Stop ------------------}
procedure TAudioEngine.Pause; // Pause
begin
BASS_ChannelPause(Channel);
PlayerState := ENGINE_PAUSE;
end;
procedure TAudioEngine.UnPause; // UNPause
begin
BASS_ChannelResume(Channel);
PlayerState := ENGINE_PLAY;
end;
procedure TAudioEngine.Stop; // Play
begin
BASS_ChannelStop(Channel);
PlayerState := ENGINE_STOP;
end;
{--------------- SingPos --------------------}
function TAudioEngine.GetSongPos : Integer;
var SongPos : DWORD; MilliSec : Integer; FloatPos : FLOAT;
begin
SongPos := BASS_ChannelGetPosition(Channel);
FloatPos := BASS_ChannelBytes2Seconds(Channel, SongPos);
MilliSec := Trunc(1000 * FloatPos);
if MilliSec < 0 then
MilliSec := 0;
if (PlayerState = ENGINE_STOP) or
(PlayerState = ENGINE_SONG_END) then
Result := 0
else
Result := MilliSec;
end;
procedure TAudioEngine.SetSongPos (SongPos : Integer);
begin
if WriteToFile Then Exit;
SongPos := BASS_ChannelSeconds2Bytes(Channel, SongPos / 1000);
BASS_ChannelSetPosition(Channel, SongPos);
end;
{-------------------- Song Len --------------- }
function TAudioEngine.GetSongLen : Integer;
var MilliSec : Integer; FloatPos : FLOAT;
begin
FloatPos := BASS_ChannelBytes2Seconds(Channel, SongLength);
MilliSec := Trunc(1000 * FloatPos);
if MilliSec < 0 then
MilliSec := 0;
result := MilliSec;
end;
{------------------- CuSong Name ---------------}
function TAudioEngine.GetCurSong : String;
begin
result := CurFileName;
end;
{------------------- Volume ---------------------}
function TAudioEngine.GetMainVolume : Integer;
begin
result := BASS_GetVolume;
end;
function TAudioEngine.GetGainVolume : Integer;
var MVol, SVol, STVol : DWORD;
begin
BASS_GetGlobalVolumes(MVol, SVol, STVol);
result := MVol;
end;
procedure TAudioEngine.SetMainVolume (Vol : Integer);
begin
BASS_SetVolume(Vol);
end;
procedure TAudioEngine.SetGainVolume (Vol : Integer);
begin
BASS_SetGlobalVolumes(Vol, Vol, Vol);
end;
{----------------- Panning -------------------}
function TAudioEngine.GetPanning : Integer;
var freq, volume : DWORD; Pan : Integer;
begin
BASS_ChannelGetAttributes(Channel, freq, volume, Pan);
result := Pan;
end;
procedure TAudioEngine.SetPanning (Pan : Integer);
var freq, volume : DWORD; Pn : Integer;
begin
BASS_ChannelSetAttributes(Channel, -1, -1, Pan);
end;
{-------------------- Pich -------------------}
function TAudioEngine.GetPitch : Integer;
var handle, freq, volume : DWORD; Pan : Integer;
begin
BASS_ChannelGetAttributes(Channel, freq, volume, Pan);
result := Trunc((Pan / WaveFreq) * 100);
end;
procedure TAudioEngine.SetPitch (Ptc : Integer);
var freq : Integer; Pn : Integer;
begin
freq := Trunc((Ptc/ 10) * WaveFreq);
if freq < 100 then
freq := 100;
if freq > 100000 then
freq := 100000;
BASS_ChannelSetAttributes(Channel, freq, -1, -1);
end;
{----------------- WaveBuffer ---------------}
function TAudioEngine.GetWaveBuffer : TWaveData;
var BuffLen : Integer; WaveData : TWaveData;
begin
BuffLen := 2048;
if (PlayerState <> ENGINE_PLAY) or
(BASS_ChannelIsActive(Channel) <> BASS_ACTIVE_PLAYING) or
WriteToFile then
Result := NullWave
else
begin
BASS_ChannelGetData(Channel, @WaveData, BuffLen);
result := WaveData;
end;
end;
{------------------- FFTData ----------------}
function TAudioEngine.GetFFTData : TFFTData;
var FFTData : TFFTData;
begin
if (PlayerState <> ENGINE_PLAY) or
(BASS_ChannelIsActive(Channel) <> BASS_ACTIVE_PLAYING) or
(WriteToFile) then
Result := NullFFT
else
begin
BASS_ChannelGetData(Channel, @FFTData, BASS_DATA_FFT1024);
result := FFTData;
end;
end;
{------------------- VULevel ----------------}
procedure TAudioEngine.GetVULevel(var R, L : Integer);
var VUCH : DWORD;
begin
VUCH := BASS_ChannelGetLevel(Channel);
L := LOWORD(VUCH);
R := HIWORD(VUCH);
end;
{----------------- CPU usage -----------------}
// update the CPU usage % display
function TAudioEngine.Get_CPU : String;
begin
Get_CPU:= FloatToStrF(BASS_GetCPU, ffFixed, 4, 1) + ' %';
end;
{------------------- Bitrate ----------------}
function TAudioEngine.GetBitrate : Integer;
var ByteLen : DWORD;
begin
ByteLen := BASS_ChannelSeconds2Bytes(Channel, SongLength);
Result := Trunc((ByteLen / (2 * 8 * GetSongLen)));
end;
{--------------- DialogFilter --------------}
function TAudioEngine.GetDialogFilter : String;
begin
result := 'mp1/mp2/mp3/wav/ogg/mod/s3m/it/umx/mo3/mtm/xm|*.mp1;*.mp2;*.mp3;*.wav;*.ogg;*.mod;*.s3m;*.it;*.umx;*.mo3;*.mtm;*.xm|'
+ 'Streams (mp1/mp2/mp3/wav/ogg)|*.mp1;*.mp2;*.mp3;*.wav;*.ogg|'
+ 'Trackers (mod/s3m/it/umx/mo3/mtm/xm)|*.mod;*.s3m;*.it;*.umx;*.mo3;*.mtm;*.xm';
end;
{--------------- BufferLen --------------}
procedure TAudioEngine.SetOutBufferLen (Len : Integer);
begin
if Len < 150 then
Len := 150;
if Len > 2000 then
len := 2000;
BASS_SetBufferLength(Len / 1000);
end;
{--------------- SongTitle --------------}
function TAudioEngine.GetSongTitle (FileName : String): String;
var ServerUrl, Name, Genere, WebURL, Bitrate, Title, TitleURL, Comment : String;
begin
if (Copy(Trim(UpperCase(FileName)), 1, 5) = 'HTTP:') or
(Copy(Trim(UpperCase(FileName)), 1, 4) = 'FTP:') then
begin
if CurFileName = FileName then
ServerUrl := ''
else
ServerUrl := FileName;
GetICYMetaBroadcast(ServerUrl, Name, Genere, WebURL, Bitrate, Title, TitleURL, Comment);
if Name <> '' then
Result := Name + ' ' + WebURL + ' - ' + Title
else
Result := 'Unknown Host';
end
else
begin
FileName := ExtractFileName(FileName);
result := Copy(FileName, 1, Length(FileName) - Length(ExtractFileExt(FileName)));
end;
end;
{-------------- SongLength -------------}
function TAudioEngine.GetSongLength (FileName : String): Integer;
Var Chn : DWORD; res, MilliSec: Integer; SongLength : DWORD; FloatPos : FLOAT;
begin
Chn := BASS_StreamCreateFile(FALSE,PChar(FileName), 0, 0, 0);
if Chn <> 0 then SongLength := BASS_StreamGetLength(Chn);
if (Chn = 0) then
begin
Chn := BASS_MusicLoad(FALSE, PChar(FileName), 0, 0, 0);
SongLength := BASS_MusicGetLength(Chn, True);
end;
if (Chn <> 0) then
begin
FloatPos := BASS_ChannelBytes2Seconds(Chn, SongLength);
MilliSec := Trunc(1000 * FloatPos);
if MilliSec < 0 then
MilliSec := 0;
res := MilliSec;
end
else res := -1;
BASS_StreamFree(Chn);
BASS_MusicFree(Chn);
result := res;
end;
{-------------- CheckPlayableFile -------------}
function TAudioEngine.CheckPlayableFile (FileName : String) : Boolean;
var Ext : String;
begin
Ext := UpperCase(ExtractFileExt(FileName));
if (Ext = '.MP1') or (Ext = '.MP2') or (Ext = '.MP3') or (Ext = '.WAV') or (Ext = '.OGG') or (Ext = '.MOD') or
(Ext = '.S3M') or (Ext = '.IT') or (Ext = '.UMX') or (Ext = '.MO3') or (Ext = '.MTM') or (Ext = '.XM') then
Result := True
else
Result := False;
end;
{---------------- SaveUrlFil ----------------}
function TAudioEngine.GetSaveUrlFile : String;
begin
Result := URLSaveFile;
end;
procedure TAudioEngine.SetSaveUrlFile (FileName : String);
begin
URLSaveFile := FileName;
end;
{---------------- ICYMetaBroadcast ----------------}
procedure TAudioEngine.GetICYMetaBroadcast (ServerURL : String; var Name, Genere, WebURL, Bitrate, Title, TitleURL, Comment : String);
var i, cnt : Integer; ICY : PChar; Tmp : String; RadioICY : TStringList; SrvChan : DWORD;
function StrIndex( StrList : TStringList; SubStr : String) : Integer;
var i : Integer;
begin
Result := -1;
for i := 0 to StrList.Count -1 do
if Pos(UpperCase(SubStr), UpperCase(StrList[i])) > 0 then
Result := i;
end;
function ExtractICYSubStr(aStr : String) : String;
var i : Integer;
begin
Result := Copy(aStr, Pos(':', aStr) + 1, Length(aStr));
end;
begin
RadioICY := TStringList.Create;
RadioICY.Clear;
if ServerURL <> '' then
begin
SrvChan := BASS_StreamCreateURL(PChar(ServerURL), 0, BASS_STREAM_META, nil);
if SrvChan = 0 then
Exit;
end
else SrvChan := Channel;
if SrvChan = 0 then
exit;
{Radio Broadcast ICY}
i := 0;
icy := BASS_StreamGetTags(SrvChan, BASS_TAG_ICY);
while (i < 400) do //(icy[i] + icy[i + 1] <> #0 + #0) and
begin
try
if icy[i] = #0 then
begin RadioICY.add(Tmp); Tmp :='';
end
else
tmp := tmp + icy[i] except
end;
Inc(i);
end;
{Broadcast radio ICY Tag}
RadioICY.add(BASS_StreamGetTags(SrvChan, BASS_TAG_META));
i := StrIndex (RadioICY, 'icy-name');
if i > -1 then
Name := ExtractICYSubStr(RadioICY[i]);
i := StrIndex (RadioICY, 'icy-genre');
if i > -1 then
Genere := ExtractICYSubStr(RadioICY[i]);
i := StrIndex (RadioICY, 'icy-url');
if i > -1 then
WebURL := ExtractICYSubStr(RadioICY[i]);
i := StrIndex (RadioICY, 'icy-br');
if i > -1 then
Bitrate := ExtractICYSubStr(RadioICY[i]);
cnt := 1;
While StrIndex (RadioICY, 'icy-notice' + IntToStr(cnt)) > -1 do
begin
i := StrIndex (RadioICY, 'icy-notice' + IntToStr(cnt));
if Pos(UpperCase('Winamp'), Uppercase(RadioICY[i])) = 0 then
Comment := Comment + ExtractICYSubStr(RadioICY[i]) + ' ';
inc(cnt);
end;
{Getting Meta}
i := StrIndex (RadioICY, 'StreamTitle');
if i > -1 then
Title := Copy(RadioICY[i], Pos(#39, RadioICY[i]) + 1,
Pos(#39 , Copy(RadioICY[i], Pos(#39, RadioICY[i]) + 1, Length(RadioICY[i]))) - 1);
i := StrIndex (RadioICY, 'StreamUrl');
if i > -1 then
begin
RadioICY[i] := Copy(RadioICY[i], Pos('StreamUrl', RadioICY[i]), Length(RadioICY[i]) + 1);
TitleURL := Copy(RadioICY[i], Pos(#39, RadioICY[i]) + 1,
Pos(#39 , Copy(RadioICY[i], Pos(#39, RadioICY[i]) + 1, Length(RadioICY[i]))) - 1);
end;
if ServerURL <> '' then
BASS_StreamFree(SrvChan);
end;
function TAudioEngine.IsOnLine : Boolean;
begin
if ((PlayerState = ENGINE_PLAY) or (PlayerState =ENGINE_PAUSE)) and((Copy(Trim(UpperCase(CurFileName)), 1, 5) = 'HTTP:') or
(Copy(Trim(UpperCase(CurFileName)), 1, 4) = 'FTP:' )) then
Result := True
else
Result := False;
end;
{--------------- DecodeFile ----------------}
procedure TAudioEngine.DecodeFile(OutPath : String);
var chan, flags, frq, vl : DWORD; fp : integer; Tmp, pos : Integer;
cbuff : PChar; buf : array [0..10000] of DWORD;
ProgressRatio : integer;
BytesBuffer, BytesRead : integer;
StartSector, EndSector : integer;
temp : string;
i : longint;
RecStream : TFileStream;
nChannels : Word; // number of channels (i.e. mono, stereo, etc.)
nSamplesPerSec : DWORD; // sample rate
nAvgBytesPerSec : DWORD;
nBlockAlign : Word;
wBitsPerSample : Word; // number of bits per sample of mono data
FileName : String;
begin
chan := Channel;
pos := BASS_StreamGetLength(chan);
flags := BASS_ChannelGetFlags(chan);
if (flags and BASS_SAMPLE_MONO > 0) then
nChannels := 1 else nChannels :=2;
if nChannels = 2 then
nBlockAlign := 4
else
nBlockAlign := 2;
if (flags and BASS_SAMPLE_8BITS > 0) then
wBitsPerSample := 8
else
wBitsPerSample := 16;
BASS_ChannelGetAttributes(chan, frq, vl, Tmp);
nSamplesPerSec := frq;
nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
FileName := ExtractFileName(CurFileName);
FileName := Copy(FileName, 1, Length(FileName) - Length(ExtractFileExt(FileName)));
RecStream := TFileStream.Create(OutPath + FileName + '.wav', fmCreate);
// Write header portion of wave file
temp := 'RIFF'; RecStream.write(temp[1], length(temp));
temp := #0#0#0#0; RecStream.write(temp[1], length(temp)); // File size: to be updated
temp := 'WAVE'; RecStream.write(temp[1], length(temp));
temp := 'fmt '; RecStream.write(temp[1], length(temp));
temp := #$10#0#0#0; RecStream.write(temp[1], length(temp)); // Fixed
temp := #1#0; RecStream.write(temp[1], length(temp)); // PCM format
if nChannels = 1 then
temp := #1#0
else
temp := #2#0;
RecStream.write(temp[1], length(temp));
RecStream.write(nSamplesPerSec, 2);
temp := #0#0; RecStream.write(temp[1], length(temp)); // SampleRate is given as dWord
RecStream.write(nAvgBytesPerSec, 4);
RecStream.write(nBlockAlign, 2);
RecStream.write(wBitsPerSample, 2);
temp := 'data'; RecStream.write(temp[1],length(temp));
temp := #0#0#0#0; RecStream.write(temp[1],length(temp)); // Data size: to be updated
BytesRead := 1024 * 10; // 10kBytes
while (BASS_ChannelIsActive(chan) > 0) do
begin
BASS_ChannelGetData(chan, @buf, BytesRead);
RecStream.Write(buf, BytesRead);
Application.ProcessMessages;
if (PlayerState = ENGINE_STOP) or
(BASS_ChannelGetPosition(Chan) >= BASS_StreamGetLength(chan)) then
Break;
end;
Stop;
// complete WAV header
// Rewrite some fields of header
i := RecStream.Size - 8; // size of file
RecStream.Position := 4;
RecStream.write(i, 4);
i := i - $24; // size of data
RecStream.Position := 40;
RecStream.write(i, 4);
RecStream.Free;
PlayerState := ENGINE_SONG_END;
end;
procedure TAudioEngine.DecodeToFile (FileOut : Boolean; OutDir : String);
begin
WriteToFile := FileOut;
WriteDir := OutDir;
end;
end.
|
|
|