Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Световые эффекты » Плагин для Аимпа


Плагин для Аимпа

Сообщений 1 страница 30 из 35

1

Тряхнул стариной...

http://lightportal.at.ua/publ/cvetomuzy … /3-1-0-118

0

2

Режим стробоскопа мне показался по живее/интереснее.

0

3

Мне тоже стробоскоп нравится.
Хотя в обычном режиме ЦМУ можно затухание ускорить, тоже пошустрее станет.
А вообще поле для экспериментов не паханое.

0

4

Так всегда: море идей, доработки...только время нужно.)

зы: radan, глянь плиз ЛС.

0

5

Посмотрел SDK плагинов Аимпа. Вроде не сложно. Чем-то на модели протеуса похоже.
Аимп успешно "скушал" тестовый плагин. :)

http://s7.uploads.ru/FAWBJ.png

0

6

Пётр как всегда на высоте! Честно сказать  платформа NET для написания плагина Аимпа - что из гаубицы по воробьям...
На делфи писать не хочется, вот Пурик для этих вещей самое то.

0

7

Тестовый плагин, может кому будет интересно. http://pure-basic.narod.ru/forum_files/ … alPlug.zip
Нужно папку VisualPlug скопировать в папку плагинов AIMP.

+1

8

Пётр, я восхищён!
Самое интересное и полезное в том, что ваш плагин визуализации работает параллельно с другими плагинами!
Т.е. можно управлять железными девайсами на фоне каких либо сторонних визуализаций.
Взял на заметку, придётся опять Пурик расчехлять!

0

9

Плагин использует расширение IAIMPExtensionCustomVisualization сервиса IAIMPServiceVisualizations. Его описание.

IAIMPExtensionCustomVisualization

Представляет собой расширение для сервиса IAIMPServiceVisualizations. Этот тип визуализации позволяет выводить данные за пределом дисплея визуализации плеера, а так же не зависит от наличия дисплея визуализации в скине и его активности (выбрана визуализация пользователем или нет).

А если проще, то AIMP имеет несколько расширений для визуализации и эта по видимому предназначена для подобных цветомузык, т. к. работает в фоне и не требует рисования в окне плеера.
Ее класс содержит всего два метода.

Код:
Interface IAIMPExtensionCustomVisualization Extends IUnknown
  ; Common Information
  GetFlags()
  ; Basic functionality
  Draw(*Data.TAIMPVisualData)
EndInterface

Нам интересен метод Draw, т. к. он периодически вызывается плеером и передает нам заполненную структуру с двумя массивами, в одном из которых "сырые" данные, а во втором уже обработанные быстрым преобразованием Фурье.

0

10

Про Draw понятно, непонятно как он сразу стартует параллельно с активной в текущий момент визуализацией.
Практически в окне визуализации есть возможность выбирать только одну визуализацию.

0

11

Тип визуализации IAIMPExtensionCustomVisualization не предназначен для рисования в окне плеера и работает независимо от других визуализаций.
Та визуализация что сейчас активна, скорее всего имеет тип IAIMPExtensionEmbeddedVisualization.

Представляет собой расширение для сервиса IAIMPServiceVisualizations - визуализацию, отображаемую на дисплее визуализации в скине плеера и/или полноэкранном режиме.

0

12

Посмотрел тему на форуме Аимпа. В .NET действительно используется расширение IAimpExtensionEmbeddedVisualization. Нужно попросить чтобы Martin добавил еще и IAIMPExtensionCustomVisualization. Тогда появится возможность получать спектр без выбора активной визуализации и без необходимости рисования в окне Аимпа.

0

13

Есть IAIMPExtensionCustomVisualization.
Получается что он работает постоянно в каждом подгруженном плагине, в отличии от IAimpExtensionEmbeddedVisualization, который работает только при выборе конкретной визуализации.

0

14

Еще один пример плагина, типа IAimpExtensionEmbeddedVisualization, рисующий в окне аимпа. http://pure-basic.narod.ru/forum_files/ … zation.zip
Нужно выбрать визуализацию "Тест".
И еще, не кликайте в верхней левой области визуализации. Плагину это не нравится. :D

0

15

Ну вот, так всегда...
Один человек разрабатывал - разрабатывал прослойку между Аимпом и Нетом, другой писал-писал этот плагин...
Пришли Пётр с Пуриком и крупным размашистым почерком поставили своё резюме.  :cool:

0

16

radan написал(а):

разрабатывал прослойку между Аимпом и Нетом

У него ведь не только визуализация но и много чего другого...

0

17

Да, он на данный момент почти весь SDK портировал.
Я тут подумал что неплохо бы на Пурике сделать универсальную библиотеку, которая получает спектр и помещает его в открытый для внешних программ массив.
Тогда появится возможность разрабатывать свои визуальные приложения на основе этого плагина на любом ЯП, включая  НЕТ.

0

18

Теоретически это возможно. Нужно лишь придумать как информировать приложение о наличии новых данных чтобы программа вызвала функцию из DLL и забрала данные. В .NET поддерживаются CallBack функции?

Отредактировано Пётр (2016-03-12 00:12:27)

0

19

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

Пётр написал(а):

В .NET поддерживаются CallBack функции?

https://msdn.microsoft.com/en-us/library/5zwkzwf4(v=vs.110).aspx

0

20

Если с DLL работает только один процесс/поток, то проблем вообще нет, а если множество... Если делать универсальную библиотеку, то так чтобы с DLL могли работать много программ, и каждую их них нужно проинформировать о новых данных и предоставить их по запросу.

0

21

Наверное для начала можно с одним процессом попробовать.

0

22

Итак, плагин. http://pure-basic.narod.ru/forum_files/ … lShare.zip
В плагине VisualShare.dll есть функции

Код:
AIMPPluginGetHeader(*Header.Integer)
SetCallBack(*Proc, Flag.a)
GetShare(*Data.TAIMPVisualData)

Функция AIMPPluginGetHeader для плеера и она нам не нужна (вызывать не нужно), а вот две другие позволяют получить доступ к данным визуализации.
Данные можно забрать двумя способами - через CallBack функцию или непосредственно запрашивая их.
В первом случае, нужно один раз вызвать функцию SetCallBack() и передать ей указатель на функцию такого формата.

Код:
CallBack(*Data.TAIMPVisualData)

и плагин будет ее регулярно вызывать по мере поступления данных. Если при вызове SetCallBack() во втором параметре передать 0 (#False), то CallBack функция будет вызываться с нулевым указателем, а данные потребуется забирать вызывая функцию GetShare(), а если передать 1 (#True), то CallBack функции будет передаваться указатель на структуру TAIMPVisualData.
Хочу обратить внимание что CallBack функция вызывается в отдельном потоке. Это нужно учитывать.
Структура TAIMPVisualData имеет вид.

PureBasic.

Код:
#AIMP_VISUAL_SPECTRUM_MAX = 256
#AIMP_VISUAL_WAVEFORM_MAX = 512

Structure TAIMPVisualDataSpectrum
  Arr.f[#AIMP_VISUAL_SPECTRUM_MAX]
EndStructure

Structure TAIMPVisualDataWaveform
  Arr.f[#AIMP_VISUAL_WAVEFORM_MAX];
EndStructure

Structure TAIMPVisualData
  Peaks.f[2]
  Spectrum.TAIMPVisualDataSpectrum[3]
  WaveForm.TAIMPVisualDataWaveform[2]
  Reserved.i
EndStructure

Дельфи.

Код:
  AIMP_VISUAL_SPECTRUM_MAX = 256;
  AIMP_VISUAL_WAVEFORM_MAX = 512;

type
  TAIMPVisualDataSpectrum = array[0..AIMP_VISUAL_SPECTRUM_MAX - 1] of Single;
  TAIMPVisualDataWaveform = array[0..AIMP_VISUAL_WAVEFORM_MAX - 1] of Single;

  PAIMPVisualData = ^TAIMPVisualData;
  TAIMPVisualData = packed record
    Peaks: array[0..1] of Single;
    Spectrum: array[0..2] of TAIMPVisualDataSpectrum;
    Waveform: array[0..1] of TAIMPVisualDataWaveform;
    Reserved: Integer;
  end;

C++

Код:
const int AIMP_VISUAL_SPECTRUM_MAX = 256;
const int AIMP_VISUAL_WAVEFORM_MAX = 512;

typedef float TAIMPVisualDataSpectrum[AIMP_VISUAL_SPECTRUM_MAX];
typedef float TAIMPVisualDataWaveform[AIMP_VISUAL_WAVEFORM_MAX];

#pragma pack(push, 1)
struct TAIMPVisualData
{
	float Peaks[2];
	TAIMPVisualDataSpectrum Spectrum[3];
	TAIMPVisualDataWaveform WaveForm[2];
	int Reserved;
};
#pragma pack(pop)

Для доступа к данным, приложение должно работать DLL находящейся в папке с плагином. В папке с плагином есть два примера. Поддерживается одновременная работа с множеством процессов, так что можете запустить сколько хотите копий приложений (в пределах разумного конечно).

+1

23

Спасибо, Пётр!
Как только немного освобожусь, сделаю примеры для C# и VBNET.

0

24

Добавил функцию IsData(), которая возвращает не 0 в случае наличия данных и переименовал функцию GetShare в GetData.
Также добавил пример считывания данных визуализации без CallBack, а только с использованием IsData и GetData.
Ссылка та же.

Отредактировано Пётр (2016-03-13 13:56:30)

0

25

Сделал пример на C#. Спасибо ещё раз, Пётр!

Нужно подключить пространство:

Код:
using System.Runtime.InteropServices;

Затем объявления:

Код:
        [DllImport("VisualShare.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern bool GetData([MarshalAs(UnmanagedType.Struct)] ref TAIMPVisualData data);

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct TAIMPVisualData
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
            public Single[] Peaks;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3 * 256)]
            public Single[] Spectrum;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * 512)]
            public Single[] WaveForm;
            public int Reserved;
        };

        TAIMPVisualData tavd = new TAIMPVisualData();

Затем в таймере получение данных:

Код:
            bool t = GetData(ref tavd);
            if (t)
            {
                //Выводим уровень левого и правого каналов в прогресс бары
                int LeftPeaks = Convert.ToInt32(tavd.Peaks[0] * 100);
                if (LeftPeaks > 100) LeftPeaks = 100;
                progressBar1.Value = LeftPeaks;
                int RightPeaks = Convert.ToInt32(tavd.Peaks[1] * 100);
                if (RightPeaks > 100) RightPeaks = 100;
                progressBar2.Value = RightPeaks;

                //рисуем спектр на имидже
                Bitmap bit = new Bitmap(PicVis.Width, PicVis.Height);
                Graphics graph = Graphics.FromImage(bit);
                Pen YellowPen = new Pen(Color.Green, 1);
                for (int X = 0; X <= PicVis.Width; X = X + 2)
                {
                    Single YY = tavd.Spectrum[X / 2];
                    YY = YY * PicVis.Height / 10;
                    if (YY > PicVis.Height) YY = PicVis.Height;
                    int DDD = Convert.ToInt16(YY);
                    graph.DrawLine(YellowPen, X, PicVis.Height, X, PicVis.Height - DDD);
                }
                PicVis.Image = bit;
            }

На форме должны быть прогресс бары - progressBar1, progressBar2 и контейнер для рисования PicVis шириной не более 512.

Чуть позже выложу полный код.

http://s7.uploads.ru/t/ge1TD.jpg

0

26

radan написал(а):

[DllImport("VisualShare.dll", CallingConvention = CallingConvention.Cdecl)]

Удивительно что оно вообще работает, т. к. у всех функций библиотеки (в т. ч. CallBack) соглашения вызова stdcall, т. е. как у WinAPI функций.

0

27

CallingConvention = CallingConvention.Cdecl можно вообще выбросить.

0

28

Доработал плагин (версия 1.0.0.5) http://pure-basic.narod.ru/forum_files/ … .0.0.5.zip
Добавлена функция IsAimp() возвращающая не 0 если плеером используется плагин, а также добавлена поддержка запуска программ при инициализации плагина плеером. Список программ должен находится в файле ProgramList.txt рядом с плагином. Формат файла - стандартный для ini файлов. Кодировка UTF-8.
Подробнее про этот тип файлов можно прочитать в википедии https://ru.wikipedia.org/wiki/.ini

Пример файла (две программы).

Код:
[1]
Program = Программа.exe
Parameter = Параметры программы
Directory = Папка программы

[2]
Program = Программа.exe
Parameter = Параметры программы
Directory = Папка программы

Секции могут иметь любое имя. Они нужны только для разделения пространства имен ключей.
Ключ Program должен содержать путь к программе. Абсолютный или относительный по отношению к папке с плагином.
Ключ Parameter содержит параметры программы. Является необязательным и может отсутствовать.
Ключ Directory содержит путь к рабочей папке программы. Является необязательным и может отсутствовать.

Отредактировано Пётр (2016-03-16 15:42:44)

0

29

Пётр, столкнулся с проблемой на 64 разрядной ОС.
IsData всегда возвращает 0, а в данных уровня и спектра тоже всегда нулевые значения.
Как то нужно перекомпилировать библиотеку для работы на 64 разряда ОС?

0

30

Какая версия винды? Тестировал на Win7 x64. Нормально работает.

0


Вы здесь » Программирование ATMEL в BASCOM. » Световые эффекты » Плагин для Аимпа