Вопрос Как создать муз. спектр?

SVY

Новичок
Возникла идея сделать визуализацию звука на страницах инсталлятора с помощью bass.dll. Десяток - полтора колеблющихся цветовых столбиков спектра в такт громкости музыки, как в плеерах, но без управления. Вроде в данной библиотеке есть необходимые функции. Как это можно реализовать? Можно ли этого вообще добиться в Inno?
 

sergey3695

Ветеран
Модератор
SVY, анимацию вставляешь. По-любому анимацию видел :D (в инно)
 

SVY

Новичок
Я видел разработки с визуализацией с использованием Delphi на этом сайте и здесь (Pure Basic). Только в программировании я не силён. Разобраться не могу.
 

SVY

Новичок
Tidro, это был чей установщик - R. G. Games? Получается что простую визуализацию можно сделать. Только вот не ясно, что за программа создала инсталлятор, на Inno не совсем похоже.
 
Последнее редактирование:

Tidro

Новичок
Tidro, это был чей установщик - R. G. Games? Получается что простую визуализацию можно сделать. Только вот не ясно, что за программа создала инсталлятор, на Inno не совсем похоже.
Этот установщик я писал для себя и т.к я в R.G. Games, то релизы происходят от имени группы
Времени на реализацию всего задуманного не так много, поэтому я постепенно добавляю несколько новых штук в инсталлятор с релизами
Код написан на китайской сборке Inno Setup
И вывод спектра можно так же легко реализовать, можно да же простую 2д игру сделать в инсталлятор по типу змейки)

Сейчас сделаю спектр)
Насчет поинтеров, придется написать небольшую dll
 
Последнее редактирование:

SVY

Новичок
Tidro, напишешь спектр поделись скриптом если можешь (ну и пояснениями заодно).
 

Tidro

Новичок
SVY, Я не делаю туторы и не даю исходные коды, я лишь показываю что это можно сделать
Держи инсталлятор со спектром (Он неоптимизирован настолько, насколько это было возможно т.к мне он не нужен)
 

Вложения

Последнее редактирование:

SVY

Новичок
Спасибо Tidro. Правда файл что ты представил не запускается без дополнительной dll. Ладно, попытаюсь разобраться сам.
 

Shegorat

Lord of Madness
Администратор
И вывод спектра можно так же легко реализовать, можно да же простую 2д игру сделать в инсталлятор по типу змейки)
Можно.. Все можно, только смысл? Это ведь инсталлятор, и его функции довольно специализированы.

SVY
Ну в общем, пока было свободное время портировал на инно небольшой примерчик. Дальше разбирайтесь сами
Код:
[Setup]
AppName=MyApp
AppVerName=MyApp
DefaultDirName={pf}\MyApp
OutputDir=.

[Files]
Source: bass.dll; Flags: dontcopy;
Source: sound.mp3; Flags: dontcopy;

[code]
const
   BASS_DATA_FFT2048  = $80000003;
   BASS_SAMPLE_LOOP  = 4;
   BASS_MUSIC_RAMP  = $200;

   SPECWIDTH  = 368;
   SPECHEIGHT = 127;

type
   TArrayOfSingle = array [0..1024-1] of Single;

   HSTREAM = Longword;
   HMUSIC = Longword;

function BASS_ChannelGetData(handle: DWORD; var buffer: TArrayOfSingle; length: DWORD): DWORD; external 'BASS_ChannelGetData@files:bass.dll stdcall';
function BASS_StreamCreateFile(mem: BOOL; f: PAnsiChar; offset1, offset2, length1, length2: DWORD; flags: DWORD): HSTREAM; external 'BASS_StreamCreateFile@files:bass.dll stdcall';
function BASS_MusicLoad(mem: BOOL; f: PAnsiChar; offset1, offset2: DWORD; length, flags, freq: DWORD): HMUSIC; external 'BASS_MusicLoad@files:bass.dll stdcall';
function BASS_ChannelPlay(handle: DWORD; restart: BOOL): BOOL; external 'BASS_ChannelPlay@files:bass.dll stdcall';
function BASS_Free: BOOL; external 'BASS_Free@files:bass.dll stdcall';
function BASS_Init(device: LongInt; freq, flags: DWORD; win: HWND; clsid: Longword): BOOL; external 'BASS_Init@files:bass.dll stdcall';

var
   chan: DWORD;
   specimg: TBitmapImage;
   fft: TArrayOfSingle;
   tmr: TTimer;

procedure UpdateSpectrum(Sender: TObject);
var
   x, y: Integer;
   R: TRect;
   ret: Integer;
begin
   ret:= BASS_ChannelGetData(chan,fft,BASS_DATA_FFT2048);

   R.Left:= 0;
   R.Top:= 0;
   R.Right:= SPECWIDTH;
   R.Bottom:= SPECHEIGHT;

   SpecImg.Bitmap.Canvas.Brush.Color:= 0;
   SpecImg.Bitmap.Canvas.FillRect(R);

   for x:= 0 to (SPECWIDTH div 2) do begin
     y:= Trunc(sqrt(fft[X + 1]) * 3 * SPECHEIGHT - 4);
     if (y < 0) then
       y:= 0;
     if (y > SPECHEIGHT) then
       y:= SPECHEIGHT;
 
     R.Left:= x*2 - 1;
     R.Top:= SPECHEIGHT - y;
     R.Right:= R.Left + 1;
     R.Bottom:= R.Top + y;
 
     SpecImg.Bitmap.Canvas.Brush.Color:= clWhite;
     SpecImg.Bitmap.Canvas.FillRect(R);
   end;
end;

procedure InitializeWizard();
begin
   WizardForm.InnerNotebook.Hide;
   WizardForm.OuterNotebook.Hide;

   SpecImg:= TBitmapImage.Create(WizardForm);
   SpecImg.SetBounds(25, 25, SPECWIDTH, SPECHEIGHT);
   SpecImg.Bitmap.Height:= SPECHEIGHT;
   SpecImg.Bitmap.Width:= SPECWIDTH;
   SpecImg.Stretch:= false;
   SpecImg.AutoSize:= false;
   SpecImg.Parent:= WizardForm;

   ExtractTemporaryFile('Sound.mp3');
   BASS_Init(-1, 44100, 0, WizardForm.Handle, 0)

   chan:= BASS_StreamCreateFile(FALSE,PAnsiChar(ExpandConstant('{tmp}\Sound.mp3')),0,0,0,0,BASS_SAMPLE_LOOP);
 
   //chan:= BASS_MusicLoad(FALSE,PAnsiChar(ExpandConstant('{tmp}\Sound.mp3')),0,0,0,BASS_MUSIC_RAMP or BASS_SAMPLE_LOOP,0);

   BASS_ChannelPlay(chan, FALSE);
 
   tmr:= TTimer.Create(WizardForm);
   tmr.Interval:= 25;
   tmr.OnTimer:= @UpdateSpectrum;
end;

procedure DeinitializeSetup();
begin
   tmr.Free;
   BASS_Free();
end;
P.S. Запускать из под инно не советую...
 

Tidro

Новичок
Shegorat, Обозначение var ниже type, в этом была моя ошибка (очень глупая) из-за этого я не смог нормально извлечь FFT, если кому нужно то вот пример dll
Код:
typedef DWORD (CALLBACK* LPFNDLLFUNC1)(DWORD,float*,DWORD);


HINSTANCE hinst;

extern "C" __declspec( dllexport )
float foo(DWORD handle,DWORD flag,DWORD num){
    LPFNDLLFUNC1 lpfnDllFunc1;
    float fft[16384];
    hinst = LoadLibrary(TEXT("bass.dll"));
    lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(HMODULE (hinst),"BASS_ChannelGetData");
    lpfnDllFunc1(handle,fft,flag);
    return fft[num];
}
Код:
function foo(handle: DWORD;flag: DWORD;num: DWORD):Single;
external 'foo@files:test4.dll cdecl';
Инклуды в stdafx.h
#include <string>
#include <windows.h>
 
Последнее редактирование:

SVY

Новичок
Tidro. Ошибка такая:
Runtime Error (at -1:0):
Cannot Import
dll:C:\Users\73B5~1\AppData\Local\Temp\is-V64JH.tmp\test4.dll
 

Shegorat

Lord of Madness
Администратор
если кому нужно то вот пример dll
Вызывать n раз функцию, чтобы получить n-ый элемент fft не есть гуд, тем более что при каждом вызове значения fft будут меняться.

Cannot Import
dll:C:\Users\73B5~1\AppData\Local\Temp\is-V64JH.tmp\test4.dll
Возможно антивирус съел ее?
 

SVY

Новичок
Скачанный файл выдаёт туже ошибку, антивирус тут не причём. Может всё из-за того, что папка Users не существует, а переименовать папку Пользователи не даёт система.
 
Сверху