Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Programming with MP3 (http://forum.oszone.net/showthread.php?t=29682)

Admiral 31-05-2004 00:31 205305

Народ, как оптимальнеэ всего сделать поддержку МР3 в своих програмах:
через MP3.h, MP3.ocx или другими способами(например хаudio.dll)?

JCooper 01-06-2004 20:31 205306

Admiral если тебе нужно просто проигрывать звуковые фрагменты, то значительно проще использовать формат wav. Не парься.

Prisoner 03-06-2004 01:35 205307

Угу, особенно если они мелкие, в пределах ~2-5 (а может и более) секунд. К примеру, если присмотреться, то звуки Half-Life все в wav'ках.

hasherfrog 03-06-2004 16:08 205308

Kuper
Prisoner
Имхо, человек собирается проигрывать музыку, а не звуковые эффоекты. Wav - это всё-таки от лени.
Admiral
Поскольку про язык программирования ни слова, посмотрите вот это.
Мне вот интересно, когда же directx начнёт поддерживать vp3 напрямую

Admiral 03-06-2004 19:45 205309

hasherfrog
Спасибо, но я хотел узнать как лучше для процессора, что б наименьше он грузился из-за этой музыки. Например когда играет Winamp там всего 1-2% а когда этот ТМеdiaPlayer целых 5%. Ассемблер не предлагать.
Если на С то плеєр не так уж грузит процесор, но там долго писать, на Делфи намного быстрее и легче. Мож кто знает где можно достать SDK для хаudio.dll(кроме офицыального сайта)?

Prisoner 04-06-2004 03:26 205310

hasherfrog, а ты "сожми" пятисекундную вафельку в mp3 и погляди процент "сжатия" :). В теме малых вафель разговор не о лени, имхо.

hasherfrog 04-06-2004 09:56 205311


:no: Чтобы подсунуть directX'у wav-ку, никаких телодвижений не нужно. А mp3 придётся пергнать в pcm, то есть нужен кодек, шмодек и ... начинающего программиста начинают посещать именно такие вопросы, какие задаёт Admiral. И Именно это я это имею в виду, когда говорю о лени.
А то, что для звуковых эффектов целесообразнее использовать вавки, :yes: я не спорю - это было известно с древнейших времён, ещё с доса. Помню, откроешь файл с каким-нибудь экзотическим расширением - а там вавка без хидера.


Guest 04-06-2004 22:05 205312

Есть вопрос как в программу зашить музыку - т.е. загружаешь программу и начинает проигрываться музыка (одна и таже по кругу), но не отдельным файлом, а в теле программы. Сам новичок пробую Delphi. Просто видел как-то кряк для какой-то программы (точно не помню какой), его запускаешь и начинает идти мызыка. Если кто знает как это сделать, подскажите, заранее спасибо.

Prisoner 05-06-2004 14:53 205313

Есть такая штука как ресурс, он компилируется компилятором ресурсов и потом прилинковывается к исполняемому модулю, таким образом программа может содержать в себе картинки и много чего еще.
Алгоритм в общем-то прост:
1) Создать rc-файл, он текстовый.
Код:

WAV1        WAV     wav1.wav
WAV2        WAV     wav2.wav
BMP1        BITMAP  bmp1.bmp
BMP2        BITMAP  bmp2.bmp

2) Попросить компилятор ресурсов (он входит в состав Дельфи) заняться его прямыми обязанностями:
Код:

brcc32 наш_файл.rc
Если оный компилятор не найден, то ищите его в директории bin, что в директории куда ставили Дельфи.
3) Получившийся на выходе наш_файл.res необходимо "прилинковать" к проекту, для этого в каком-нибудь юните вставляете такую опцию компилирования
Код:

{$R наш_файл}
4) Про то как использовать ресурсы, как их находить читайте в справочной системе в стороне FindResource, LoadResource, LoadFromResourceName, LockResource, UnLockResource, FreeResource.

Admiral 25-12-2006 03:56 528746

Много времени прошло после создания темы, а интереса к теме (по крайне мере у меня) не поубавилось.

Вот написанный мною пример на Visual Basic 6.0 с использованием мультимедийной библиотеки Bass (исп. версия 2.2, в настоящее время уже доступна 2.3).

Код:

Option Explicit
Dim A As Integer 'The number of song in list
Dim B As String 'The time of sound
Dim FName As String
Dim C As Integer
Const MaxTime = 65535 'Max of interval in timer
Dim chan As Long
Dim File As Long

'display error message
Sub Error_(ByVal es As String)
    Call MsgBox(es & vbCrLf & vbCrLf & "error code: " & BASS_ErrorGetCode, vbExclamation, "Error")
End Sub
Private Sub Form_Load()

'Check if bass.dll is exists
    If (Not FileExists(RPP(App.Path) & "bass.dll")) Then
        Call MsgBox("BASS.DLL does not exists", vbCritical, "BASS.DLL")
        End
    End If
   
'Check that BASS 2.2 was loaded
    If (BASS_GetVersion <> MakeLong(2, 2)) Then
        Call MsgBox("BASS version 2.2 was not loaded", vbCritical, "Incorrect BASS.DLL")
        End
    End If
   
    If (Not FileExists(RPP(App.Path) & "play.ini")) Then
        Call MsgBox("play.ini does not exists.", vbCritical, "play.ini")
        End
    End If
 
File = FreeFile
Open "play.ini" For Input As File
  Do Until EOF(File)
  Line Input #File, B
  List1.AddItem (B)
 Loop
Close File
 
'initialize BASS
 
  If (BASS_Init(-1, 44100, 0, Me.hWnd, 0) = 0) Then
      Call Error_("Can't initialize device")
      End
  End If
   
  ' If (Not PlayFile) Then      'start a file playing by calling the PlayFile pushing
    '    BASS_Free
    '  End
    'End If
   
    Play.value = True 'start a file playing by pushing the play button
End Sub

Private Sub Form_Unload(Cancel As Integer)
Call BASS_Free
    End
End Sub

Private Sub Nx_Click()
If A = List1.ListCount - 1 Then
 A = 0
 Else
 A = A + 1
 End If
Play.value = True
End Sub

Private Sub Play_Click()
Timer1.Enabled = False
Text1.Text = List1.List(A)
If (Not PlayFile) Then      'start a file playing - call PlayFile function
        BASS_Free
        End
    End If
End Sub

Private Sub Prev_Click()
If A = 0 Then
 A = List1.ListCount - 1
 Else
 A = A - 1
 End If
Play.value = True
End Sub

Function PlayFile() As Boolean
    On Local Error Resume Next    'if Cancel pressed...

    Call BASS_StreamFree(chan)
    'Call BASS_MusicFree(chan)

    chan = BASS_StreamCreateFile(BASSFALSE, List1.List(A), 0, 0, 0)
    'If chan = 0 Then chan = BASS_MusicLoad(BASSFALSE, List1.List(A), 0, 0, 0, 0)

    If chan = 0 Then
        Call Error_("Selected file couldn't be played!")
        PlayFile = False 'Can't load the file
        Exit Function
    End If

    Call BASS_ChannelPlay(chan, BASSFALSE)
    B = BASS_ChannelBytes2Seconds(chan, BASS_ChannelGetLength(chan))
    B = Left(B, InStrRev(B, ",") - 1)
    B = 1000 * B + 1000
   
    Label1.Caption = B
    CheckTime
   
    Timer1.Enabled = True
   
    FName = GetFileName(List1.List(A))
    Text1.Text = Left(FName, InStrRev(FName, ".") - 1)
   
    PlayFile = True
End Function

Private Sub Stp_Click()
Timer1.Enabled = False
Call BASS_ChannelStop(chan)
End Sub

Private Sub Timer1_Timer()
If C = 1 Then
    CheckTime
Else: Timer1.Enabled = False 'C = 0
Nx.value = True
End If
Label1.Caption = B
End Sub

'--------------------------
' some useful functions :)
'--------------------------

'check if any file exists
Public Function FileExists(ByVal fp As String) As Boolean
    FileExists = (Dir(fp) <> "")
End Function

'RPP = Return Proper Path
Function RPP(ByVal fp As String) As String
    RPP = IIf(Mid(fp, Len(fp), 1) <> "\", fp & "\", fp)
End Function

'get file name from file path
Public Function GetFileName(ByVal fp As String) As String
    GetFileName = Mid(fp, InStrRev(fp, "\") + 1)
End Function

'check Time
Public Sub CheckTime()
        If B > MaxTime Then
        B = B - MaxTime
        C = 1 'Tell timer that i use big time
        Timer1.Interval = MaxTime
        Else:
        Timer1.Interval = B
        C = 0
        End If
End Sub

Была следующая сложность в реализации: как можно было узнать, когда одна композиция доиграет, что б запустить следующую по списку?

Так вот, обратите внимание на функции таймера
Код:

Dim A As Integer 'Количество песен в списке
Dim B As String 'Время песни
Dim C As Integer
Const MaxTime = 65535 'Max of interval in timer
...
B = BASS_ChannelBytes2Seconds(chan, BASS_ChannelGetLength(chan))
B = Left(B, InStrRev(B, ",") - 1)
B = 1000 * B + 1000 `получаем длину композиции в миллисекундах и округляем до секунды (+1000)
...
Private Sub Timer1_Timer()
If C = 1 Then
    CheckTime
Else: Timer1.Enabled = False 'C = 0
Nx.value = True
End If
Label1.Caption = B
End Sub
...
Public Sub CheckTime()
        If B > MaxTime Then
        B = B - MaxTime
        C = 1 'Tell timer that i use big time
        Timer1.Interval = MaxTime
        Else:
        Timer1.Interval = B
        C = 0
        End If
End Sub

Время, которое максимально допустимо задать таймеру в Visual Basic 6.0, ограничено (65535 мс).
Естественно средне статическая песня играет значительно больше.
Так вот, я узнаю в сколько раз больше она играет, и сохраняю данное значение в переменной.

А таймер каждый интервал, будет проверят, не пора ли переключится на следующую песню.
А так как интервал (кроме последнего, а иногда и первого, если песня короче 65535 мс) достаточно велик, то и нагрузка на CPU будет достаточно либеральна.

P.S.
До этой реализации я использовал mp3.ocx производства Vision Factory, который можно скачать вместе с примером.
Во времена создания темы меня устраивал, но теперь увы требования по серьёзней.
Там естественно никакого таймера не надо было придумывать.
У объекта мр3.осх есть событие SongPlayed() которое и отвечает за конец песни.

Достаточно написать
Код:


Private Sub mp3_SongPlayed()
NX.Value = True
End Sub

где NX. кнопка на следующую песню (см исх выше).


Время: 22:09.

Время: 22:09.
© OSzone.net 2001-