Важная информация

User Tag List

Страница 2 из 2 ПерваяПервая 12
Показано с 11 по 17 из 17

Тема: Таблично-волновой синтез.

  1. #11

    Регистрация
    20.01.2010
    Адрес
    г. Зеленоград
    Сообщений
    600
    Спасибо Благодарностей отдано 
    28
    Спасибо Благодарностей получено 
    231
    Поблагодарили
    123 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от ALKO Посмотреть сообщение
    Хм.. а мне всегда казалось, что это издержки техпроцесса.
    В AY-8910 совершенно целенаправленно размеры выходых транзисторов растут экспоненциально на каждый из 15 вариантов (на 0 ток выдавать не надо), как раз чтобы соответствовать особенностям человеческого слуха.
    log(exp(x)) = x.

    Можно убедиться по снимкам кристалла.

  2. #12

    Регистрация
    30.01.2006
    Сообщений
    1,921
    Спасибо Благодарностей отдано 
    73
    Спасибо Благодарностей получено 
    119
    Поблагодарили
    80 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    а есть нетлист симулятор для AY?
    ZXMAK2 - Виртуальная Машина ZX Spectrum https://github.com/zxmak/ZXMAK2 (старая ссылка http://zxmak2.codeplex.com)
    ZXMAK.NET - спектрум на C# http://sourceforge.net/projects/zxmak-dotnet

  3. #13

    Регистрация
    20.01.2010
    Адрес
    г. Зеленоград
    Сообщений
    600
    Спасибо Благодарностей отдано 
    28
    Спасибо Благодарностей получено 
    231
    Поблагодарили
    123 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от ZXMAK Посмотреть сообщение
    а есть нетлист симулятор для AY?
    Настолько лень гуглить?
    https://github.com/lvd2/ay-3-8910_reverse_engineered

    Этот пользователь поблагодарил Sandro за это полезное сообщение:

    ZXMAK(06.04.2025)

  4. #14

    Регистрация
    26.03.2008
    Адрес
    Питкяранта
    Сообщений
    1,822
    Спасибо Благодарностей отдано 
    274
    Спасибо Благодарностей получено 
    122
    Поблагодарили
    95 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    ZXMAK, Вот чудесам нет предела, ты напоминаешь мне чат-робота (DeepSeek) - попросил wav послушать - накидано чёрт-те что, ну я прям восхищён...
    Ладно, по случаю откомпилю, вдруг да прозвучит что-то...
    (и что за ересь PSG такое... я походу лихо отстал в звукогенерации, это попахивает вообще линухами, а не дай боже ещё и крэями...)
    Ох обленился, пора снова грызть теорию (думал на пенсию выйду - буду облизывать кванты-бозоны-немножечко лептонов, ан вот тут со звукообразованием затык)

  5. #15

    Регистрация
    25.09.2009
    Адрес
    Одесса
    Сообщений
    2,311
    Спасибо Благодарностей отдано 
    96
    Спасибо Благодарностей получено 
    186
    Поблагодарили
    89 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    ещë мысля таблички хранить в 8 бит, а по мере воспроизведения дробить на полубайты, и посылать туда и туда на два разных канала.
    8 бит ЦАП. Правда логарифмическое искажение получится двухкратное... а может есть готовые решения, где wav конаертится в 8 бит на два канала AY ? Или всем влом таким маяться?

    - - - Добавлено - - -

    Ещë вариант - остаться на 4ëх битах, но использовать по два старших на двух разных каналах, тем самым минимизировав разброс напряжений.

    - - - Добавлено - - -

    дажы ни знаю, какой варик лутшы...

  6. #16

    Регистрация
    30.01.2006
    Сообщений
    1,921
    Спасибо Благодарностей отдано 
    73
    Спасибо Благодарностей получено 
    119
    Поблагодарили
    80 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Destr Посмотреть сообщение
    попросил wav послушать - накидано чёрт-те что, ну я прям восхищён...
    Ладно, по случаю откомпилю, вдруг да прозвучит что-то...
    (и что за ересь PSG такое... я походу лихо отстал в звукогенерации, это попахивает вообще линухами, а не дай боже ещё и крэями...)
    FLAC - это тот-же WAV но со сжатием без потерь, правда поддерживает только целочисленный формат сэмплов и не все частоты дискретизации, но зато в 2 раза меньше места на диске занимает и использует сжатие без потерь, т.е. что записал, то в точности и прочитается - без искажений сигнала. У меня диск всего 64 GB, из них только 15 свободно, поэтому использую FLAC вместо WAV, где возможно. Звуковые редакторы и плееры его понимают на всех платформах, поэтому проблем быть не должно.

    PSG - это старый формат, грубо говоря лог записей в регистры AY, что удобно для воспроизведения без необходимости эмуляции Z80. В этом формате часто музыку для AY выкладывают. Был доступен еще в эмуляторе x128 и Z80Stealth:
    Код:
    PSG
    
    These files are produced by 'x128' Speccy Emulator by James McKey and 'fMSX' emulator (I never saw this one). x128 creates PSG with errors. Therefore more better to use 'Z80 Stealth' Speccy Emulator by Kirill Kolpakov (Mr.Kirill). This emulator contains special features for creating PSG files and also has good debugger which very simplifies PSG creating process. Z80 Stealth Home Page is http://z80.da.ru.
    
    This is all data about PSG found in Internet:
    
    Offset  Number of byte  Description
    +0      3               Identifier 'PSG'
    +3      1               Marker “End of Text” (1Ah)
    +4      1               Version number
    +5      1               Player frequency (for versions 10+)
    +6      10              Unknown
    
    Further byte strings follows. Each string begins from byte 0FFh or 0FEh. Byte 0FFh is marker of interrupt beginning. If after it byte exists (in range 0–15) then it is number of AY register, and next byte is value of this register. Further next pair of byte follows, first byte of which is register number, and second byte is register value. And so on, until end of file, or byte 0FFh (next interrupt), or byte 0FEh will be meet. Byte after 0FEh marker is multiplied by four is number of interrupts without outing to AY. For example sequence “FE 01 FF” is equivalent to sequence “FF FF FF FF FF”. If in PSG you will find register number in range 16–252, then you can ignore this and next byte (this is outing to other MSX devices).
    
    RDOSPLAY documentation describes yet another marker is 253 called as 'End Of Music', but this marker is not supported in Emulator.
    
    Also, RDOSPLAY documentation and some my researching of existing PSG-files talk about is more simple header of PSG. This header consists of only first 4 bytes of described header and outing log starts at +4 file offset (instead of +16). So, for correct playing this PSG, need to add zero to expanse header size to 16 bytes length. If you are trying to play such PSG-files without header correcting, you don't hear differences in the most cases.
    
    EPSG
    
    Z80 Stealth emulator creates these files. EPSG additionally contents information about time of outing to AY registers.
    
    Next text from z80s.faq file.
    
    Q: What is it – this EPSG format?
    A: It's PSG format improved just a bit to handle output of digitized samples 
    
    Here's the description:
    
    Offset	Length	Value
    ============================
    Header
    ============================
    0	4	'EPSG'
    4	1	0x1A marker
    5	1	Machine type: 0x00 – ZX Spectrum 128 0x01 – Pentagon
    		0xFF – Other machines
    6	4	Zero for machine type 0x00 and 0x01 or
    		Number of Z80 tacts between interrupt markers
    		for other machines
    10	6	zeroes
    ============================
    AY(YM) log during 1 frame
    ============================
    16	1	AY(YM) register number
    17	1	value written to this register
    18	3	T-state
    .....
    ??	5	0xFFFFFFFFFF – interrupt marker
    Последний раз редактировалось ZXMAK; 09.04.2025 в 02:29.
    ZXMAK2 - Виртуальная Машина ZX Spectrum https://github.com/zxmak/ZXMAK2 (старая ссылка http://zxmak2.codeplex.com)
    ZXMAK.NET - спектрум на C# http://sourceforge.net/projects/zxmak-dotnet

    Эти 2 пользователя(ей) поблагодарили ZXMAK за это полезное сообщение:

    Denn(12.04.2025), Destr(11.04.2025)

  7. #16
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  8. #17

    Регистрация
    30.01.2006
    Сообщений
    1,921
    Спасибо Благодарностей отдано 
    73
    Спасибо Благодарностей получено 
    119
    Поблагодарили
    80 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от ALKO Посмотреть сообщение
    Правда логарифмическое искажение получится двухкратное... а может есть готовые решения, где wav конаертится в 8 бит на два канала AY ? Или всем влом таким маяться?
    вот набросал MATLAB/Octave скрипт для конвертации wav/flac в бинарник, где 1 байт это 2 сэмпла для левого и правого канала, с учетом логарифмического масштабирования. Скрипт также читает созданный файл и производит обратное преобразование во flac, чтобы послушать что получилось. Результаты не очень - искажения сильнее, чем на 4 битном ЦАП-е. Как улучшить не знаю, может кто другой подскажет...

    Код:
    if exist('OCTAVE_VERSION', 'builtin')
        pkg load signal;
    end
    
    folderOut = '/dev/shm/OCTAVE';
    if ~exist(folderOut, 'dir')
        mkdir(folderOut);
    end
    
    fileNameIn = 'TEST/test.flac';
    fileNameBin = 'test-ay-%d.bin';     % %d will be replaced with sample rate
    fileNameOut = 'test-ay.flac';
    
    if 0
    % YM2149 volume table (taken from emulator)
    x = [0x0000,0x0000,0x00EF,0x01D0,0x0290,0x032A,0x03EE,0x04D2,...
         0x0611,0x0782,0x0912,0x0A36,0x0C31,0x0EB6,0x1130,0x13A0,...
         0x1751,0x1BF5,0x20E2,0x2594,0x2CA1,0x357F,0x3E45,0x475E,...
         0x5502,0x6620,0x7730,0x8844,0xA1D2,0xC102,0xE0A2,0xFFFF];
    else
    % AY8910 volume table (taken from emulator)
    x = [0x0000,0x0340,0x04C0,0x06F2,...
         0x0A44,0x0F13,0x1510,0x227E,...
         0x289F,0x414E,0x5B21,0x7258,...
         0x905E,0xB550,0xD7A0,0xFFFF];
    end
    y = 0:(length(x)-1);
    x = double(x);
    y = double(y);
    % normalize to 0..1 range
    x = x / max(x);
    y = y / max(y);
    % remove duplicated values
    [x, unique_idx] = unique(x);
    y = y(unique_idx);
    
    % read wave
    [signal, Fs] = audioread(fileNameIn);
    
    % get first 5 seconds
    signal = signal(1:(Fs*5), :);
    
    if 0
        % change sample rate from Fs to Fs2
        Fs2 = 24000;
        signal = resample(signal, Fs2, Fs);
        Fs = Fs2;
    end
    
    % split L and R channels
    signal_l = double(signal(:,1)');
    signal_r = double(signal(:,2)');
    
    % gain normalization
    peak = max(max(abs(signal_l)), max(abs(signal_r)));
    signal_l = signal_l / peak;
    signal_r = signal_r / peak;
    
    if min(signal_l) < -1 || max(signal_l) > 1 || min(signal_r) < -1 || max(signal_r) > 1
        fprintf('warn stage w0: min-l: %g, max-l: %g, min-r: %g, max-r: %g\n', min(signal_l), max(signal_l), min(signal_r), max(signal_r));
    end
    
    % scale to 0..+1
    signal_l = (1+signal_l) / 2;
    signal_r = (1+signal_r) / 2;
    
    if min(signal_l) < 0 || max(signal_l) > 1 || min(signal_r) < 0 || max(signal_r) > 1
        fprintf('warn stage w1: min-l: %g, max-l: %g, min-r: %g, max-r: %g\n', min(signal_l), max(signal_l), min(signal_r), max(signal_r));
    end
    
    % scale from linear to AY
    signal_l = spline(x, y, signal_l);
    signal_r = spline(x, y, signal_r);
    
    if min(signal_l) < 0 || max(signal_l) > 1 || min(signal_r) < 0 || max(signal_r) > 1
        fprintf('warn stage w2: min-l: %g, max-l: %g, min-r: %g, max-r: %g\n', min(signal_l), max(signal_l), min(signal_r), max(signal_r));
        signal_l = min(1, max(0, signal_l));
        signal_r = min(1, max(0, signal_r));
    end
    
    signal_l = round(signal_l * 15);
    signal_r = round(signal_r * 15);
    
    if min(signal_l) < 0 || max(signal_l) > 15 || min(signal_r) < 0 || max(signal_r) > 15
        fprintf('warn stage w3: min-l: %g, max-l: %g, min-r: %g, max-r: %g\n', min(signal_l), max(signal_l), min(signal_r), max(signal_r));
    end
    
    % combine L and R channels into byte
    signal_8 = bitshift(signal_r, 4) + signal_l;
    
    if min(signal_8) < 0 || max(signal_8) > 255
        fprintf('warn stage w4: min: %g, max: %g\n', min(signal_8), max(signal_8));
    end
    
    % write result
    fid = fopen(fullfile(folderOut, sprintf(fileNameBin, Fs)), 'wb');
    fwrite(fid, signal_8, 'uint8');
    fclose(fid);
    
    %-----------------------------------------------------------------------
    % read and convert to wav
    
    % read back
    fid = fopen(fullfile(folderOut, sprintf(fileNameBin, Fs)), 'rb');
    signal_8 = fread(fid, 'uint8');
    fclose(fid);
    
    % restore L and R channels from byte
    signal_l = bitand(signal_8, 15);
    signal_r = bitshift(signal_8, -4);
    
    signal_l = signal_l / 15;
    signal_r = signal_r / 15;
    
    if min(signal_l) < 0 || max(signal_l) > 1 || min(signal_r) < 0 || max(signal_r) > 1
        fprintf('warn stage r0: min-l: %g, max-l: %g, min-r: %g, max-r: %g\n', min(signal_l), max(signal_l), min(signal_r), max(signal_r));
    end
    
    % scale back from AY to linear
    signal_l = spline(y, x, signal_l);
    signal_r = spline(y, x, signal_r);
    
    if min(signal_l) < 0 || max(signal_l) > 1 || min(signal_r) < 0 || max(signal_r) > 1
        fprintf('warn stage r1: min-l: %g, max-l: %g, min-r: %g, max-r: %g\n', min(signal_l), max(signal_l), min(signal_r), max(signal_r));
        signal_l = min(1, max(0, signal_l));
        signal_r = min(1, max(0, signal_r));
    end
    
    % scale to -1..+1
    signal_l = signal_l*2 - 1;
    signal_r = signal_r*2 - 1;
    
    if min(signal_l) < -1 || max(signal_l) > 1 || min(signal_r) < -1 || max(signal_r) > 1
        fprintf('warn stage r2: min-l: %g, max-l: %g, min-r: %g, max-r: %g\n', min(signal_l), max(signal_l), min(signal_r), max(signal_r));
    end
    
    signal = [signal_l signal_r];
    
    if Fs > 48000
        signal = resample(signal, 48000, Fs);
        Fs = 48000;
    end
    
    % write result
    audiowrite(fullfile(folderOut, fileNameOut), signal, Fs, 'BitsPerSample', 16);
    - - - Добавлено - - -

    хм, если заменить табличку громкости на вариант от AY8910 (с 16 уровнями), то результат заметно лучше. Видимо результат зависит от линейности используемой кривой.
    Update: обновил скрипт, исправил ошибку.

    Думаю если поиграть с табличкой уровней, то можно еще лучше результат получить, но нужно пробовать как на самом AY будет звучать.


    Вот пример что получилось: https://transfiles.ru/asd3e
    FLAC - это то как это по идее должно звучать на AY, а bin - это бинарный файл, где младшие 4 бита - это AY громкость для левого канала, старшие 4 бита- это AY громкость для правого канала.

    В идеале конечно лучше померять реальную амплитуду на выходе AY и обновить таблички, это по идее даст более качественный сигнал, т.к. позволит уменьшить нелинейные искажения сигнала.
    Последний раз редактировалось ZXMAK; 09.04.2025 в 12:40.
    ZXMAK2 - Виртуальная Машина ZX Spectrum https://github.com/zxmak/ZXMAK2 (старая ссылка http://zxmak2.codeplex.com)
    ZXMAK.NET - спектрум на C# http://sourceforge.net/projects/zxmak-dotnet

    Этот пользователь поблагодарил ZXMAK за это полезное сообщение:

    ALKO(12.08.2025)

Страница 2 из 2 ПерваяПервая 12

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Синтез 3
    от andreysur в разделе Несортированное железо
    Ответов: 9
    Последнее: 03.10.2023, 08:05
  2. Синтез-М
    от Trunk17 в разделе Несортированное железо
    Ответов: 40
    Последнее: 18.07.2021, 15:15
  3. Ремонт Синтез 2
    от JNipper в разделе Несортированное железо
    Ответов: 53
    Последнее: 28.04.2017, 18:09
  4. подарю СИНТЕЗ 2
    от Олег85 в разделе Барахолка (архив)
    Ответов: 13
    Последнее: 07.01.2011, 11:17
  5. Синтез гласных
    от Krenon в разделе Музыка
    Ответов: 9
    Последнее: 13.06.2007, 19:51

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •