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

User Tag List

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

Тема: Эмуляция AY/YM

  1. #11
    Member Аватар для mungo
    Регистрация
    04.10.2006
    Адрес
    Минск
    Сообщений
    89
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Ну, наверно вы не проверили свой код. Тот же результат.
    Сомневаюсь, и вам советую!

  2. #12
    Vitamin C++ Аватар для Vitamin
    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,254
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    80
    Поблагодарили
    34 сообщений
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от mungo Посмотреть сообщение
    Ну, наверно вы не проверили свой код. Тот же результат.
    Ну свой код я выдернул из другого своего, работающего, кода.
    А что ожидается от данного куска? Он должен проиграть два щелчка по идее- в начале воспроизведения и в конце.

  3. #13
    Member Аватар для mungo
    Регистрация
    04.10.2006
    Адрес
    Минск
    Сообщений
    89
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Ну я подготовил фрейм, проиграл отрывок, пошел следующий готовить. Так вот при любом раскладе получается как в том отрывке, что я приводил - по сути бесконечный цикл с паузой только на проигрывание отрывка. Вот тут и получается, что каким бы методом я не ждал - вашим или своим (из MSDN), я получаю щелчок.
    Сомневаюсь, и вам советую!

  4. #14
    Vitamin C++ Аватар для Vitamin
    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,254
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    80
    Поблагодарили
    34 сообщений
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от mungo Посмотреть сообщение
    Вот тут и получается, что каким бы методом я не ждал - вашим или своим (из MSDN), я получаю щелчок.
    Щелчок из-за того, что устройству нечего играть во время подготовки данных. Значит надо использовать двойную (в простейшем случае) буферизацию.

  5. #15
    Member Аватар для mungo
    Регистрация
    04.10.2006
    Адрес
    Минск
    Сообщений
    89
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Я так и подозревал, но пока с синхронизацией не очень. По сути получается, что не дожидаясь окончания проигрывания первого куска ставить на проигрывание второй, и только на третьем ждать пока выпадет из очереди первый, после чего и третий ставить. Наверно так.
    Сомневаюсь, и вам советую!

  6. #16
    Vitamin C++ Аватар для Vitamin
    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,254
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    80
    Поблагодарили
    34 сообщений
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от mungo Посмотреть сообщение
    Я так и подозревал, но пока с синхронизацией не очень. По сути получается, что не дожидаясь окончания проигрывания первого куска ставить на проигрывание второй, и только на третьем ждать пока выпадет из очереди первый, после чего и третий ставить. Наверно так.
    Алгоритм такой же, как и при работе с двумя спековскими экранами.

    10 создать event
    20 открыть устройство
    30 создать и инициализировать буфер1
    40 создать и инициализировать буфер2
    50 курсор=буфер1
    60 ждем пока освободится *курсор
    70 пишем в *курсор
    80 отправляем *курсор на воспроизведение
    90 если курсор=буфер1, то курсор=буфер2, иначе курсор=буфер1
    100 если не завершили переход на 60
    110 закрыть устройство
    120 освободить буфер1
    130 освободить буфер2
    140 освободить event

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

  8. #17
    Guru Аватар для newart
    Регистрация
    19.01.2005
    Адрес
    Санкт-Петербург
    Сообщений
    11,439
    Спасибо Благодарностей отдано 
    192
    Спасибо Благодарностей получено 
    145
    Поблагодарили
    61 сообщений
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Кусочек из AY эмулятора на PureBasic отвечающий за вывод звука:

    PHP код:



    ; ----------------------------------------------
    ;   Public 
    functions
    ; ----------------------------------------------

    Declare.
    l Sound_Start()
    Declare.
    l Sound_Stop()
    Declare.
    l Sound_SetCallbacks(adressReset.ladressSample.ladressUpdate.ladressTick.l)
    Declare.
    l Sound_SetCallbackReset(adress.l)
    Declare.
    l Sound_GetCallbackReset()
    Declare.
    l Sound_SetCallbackSample(adress.l)
    Declare.
    l Sound_GetCallbackSample()
    Declare.
    l Sound_SetCallbackTick(adress.l)
    Declare.
    l Sound_GetCallbackTick()
    Declare.
    l Sound_SetCallbackUpdate(adress.l)
    Declare.
    l Sound_GetCallbackUpdate()



    ; ----------------------------------------------
    ;   Private 
    functions
    ; ----------------------------------------------

    Declare.
    l Sound_Software_Fill()
    Declare.
    l Sound_Software_DoubleBufferThread(value.l)
    Declare.
    l Sound_ClearBuffer()

    ; ----------------------------------------------
    ;   Private 
    vars
    ; ----------------------------------------------

    ;- 
    Vars

    #Sound_LATENCY = 20
    #Sound_SLEEPTIME = 4
        
    Global Sound_BufferSizeMs.l            1000
    Global Sound_Channels.l                2
    Global Sound_Bits.l                16
    Global Sound_Bytes.l                Sound_Bits Sound_Channels
    Global Sound_MixRate.l                44100
    Global Sound_BlockSize.l            = ((Sound_MixRate #Sound_LATENCY / 1000) + 3) & $FFFFFFFC                ;    // Number of *samples*
    Global Sound_BufferSize.l            = ( Sound_BlockSize << ) << 1                                     ;( Sound_BlockSize * (Sound_BufferSizeMs #Sound_LATENCY) ) << 1        ;    // make it perfectly divisible by granularity - double buffer
    Global Sound_TotalBlocks.l            Sound_BufferSize Sound_BlockSize
    Global Sound_BufferMemoryLength.l        Sound_BufferSize Sound_Bytes        ;// 16bits
    Global Sound_BufferMemory.l            0

    Global Sound_SampleCount.0                            
    Global Sound_SampleMax.Sound_MixRate 50            

    Global Sound_WaveHdr.WAVEHDR                
    Global Sound_WaveOutHandle.0                

    Global Sound_Software_Exit.#False                
    Global Sound_Software_ThreadFinished.#False            
    Global Sound_Software_Thread.0                    

    Global Sound_Software_FillBlock.0
    Global Sound_Software_RealBlock.0
    Global Sound_Software_UpdateMutex.#False

    Global Sound_CallbackReset.0                    
    Global Sound_CallbackSample.0                    
    Global Sound_CallbackTick.0
    Global Sound_CallbackUpdate.0            

    Debug_
    ("Sound_Bytes "+Str(Sound_Bytes))
    Debug_("Sound_BlockSize "+Str(Sound_BlockSize))
    Debug_("Sound_BufferSize "+Str(Sound_BufferSize))
    Debug_("Sound_TotalBlocks "+Str(Sound_TotalBlocks))
    Debug_("Sound_BufferMemoryLength "+Str(Sound_BufferMemoryLength))
    Debug_("Sound_SampleMax "+Str(Sound_SampleMax))
    Debug_("")



    ;- 
    Procedures

    Procedure
    .l Sound_Software_Fill()
        Protected 
    i.l
        
    Protected mixpos.l
        
    Protected mixBuffer.l
        
        mixpos 
    Sound_Software_FillBlock Sound_BlockSize
        mixBuffer 
    Sound_BufferMemory mixpos Sound_Bytes
        
         
    Debug_Str(Sound_Software_FillBlock)+" "+Str(mixBuffer) )

        For 
    i=0 To Sound_BlockSize-1        
            
    If Sound_CallbackSample<>0  :  CallFunctionFast(Sound_CallbackSample,mixBuffer)  :  EndIf
            
            
    Sound_SampleCount+1
            
    If Sound_SampleCount Sound_SampleMax
                
    If Sound_CallbackTick<>0  :  CallFunctionFast(Sound_CallbackTick)  :  EndIf
                
    Sound_SampleCount=0
            
    EndIf
        
            
    mixBuffer Sound_Bytes
        Next

        Sound_Software_FillBlock 
    1
        
    If Sound_Software_FillBlock >= Sound_TotalBlocks 
            Sound_Software_FillBlock 
    0
        
    EndIf
    EndProcedure

    Procedure
    .l Sound_CreateBuffer()
        If 
    Sound_BufferMemory=0
            Sound_BufferMemory 
    AllocateMemory(Sound_BufferMemoryLength)
        EndIf
    EndProcedure

    Procedure
    .l Sound_FreeBuffer()
        If 
    Sound_BufferMemory<>0
            
    FreeMemory(Sound_BufferMemory)
            
    Sound_BufferMemory 0
        
    EndIf
    EndProcedure

    Procedure
    .l Sound_ClearBuffer()
        For 
    i=0 To Sound_BufferMemoryLength-1
            PokeL 
    (Sound_BufferMemory+i,0)
        
    Next
    EndProcedure

    Procedure
    .l Sound_Start()
        Protected 
    i.l
        
    Protected res.l
        
    Protected pcmwf.WAVEFORMATEX
        
        Debug_ 
    ("Sound start")
        
        If 
    Sound_CallbackReset<>0  :  CallFunctionFast(Sound_CallbackReset)  :  EndIf
        
    Sound_CreateBuffer()
        
    Sound_ClearBuffer()
        
        
    Sound_WaveOutHandle 0
        
        pcmwf
    \wFormatTag        #WAVE_FORMAT_PCM
        
    pcmwf\nChannels            Sound_Channels
        pcmwf
    \wBitsPerSample    Sound_Bits
        pcmwf
    \nBlockAlign        Sound_Bytes
        pcmwf
    \nSamplesPerSec    Sound_MixRate
        pcmwf
    \nAvgBytesPerSec    Sound_MixRate Sound_Bytes
        pcmwf
    \cbSize            0
        
        res
    .waveOutOpen_( @Sound_WaveOutHandle#WAVE_MAPPER, @pcmwf, 0, 0, 0)
        
    Debug_ ("waveOutOpen "+Str(res))
        
    Debug_ ("waveOutHandle "+Str(Sound_WaveOutHandle))
        
        If 
    res<>0
            ProcedureReturn 1
        
    EndIf
            
        
    Sound_WaveHdr\dwFlags            #WHDR_BEGINLOOP | #WHDR_ENDLOOP
        
    Sound_WaveHdr\lpData            Sound_BufferMemory                ;Sound_Memory_Calloc(length);
        
    Sound_WaveHdr\dwBufferLength    Sound_BufferMemoryLength
        Sound_WaveHdr
    \dwBytesRecorded    0
        Sound_WaveHdr
    \dwUser            0
        Sound_WaveHdr
    \dwLoops            = -1
        Sound_WaveHdr
    \lpNext            0
        
        res 
    waveOutPrepareHeader_(Sound_WaveOutHandle, @Sound_WaveHdrSizeOf(WAVEHDR))
        
    Debug_ ("waveOutPrepareHeader "+Str(res))
        
        If 
    res<>0
            ProcedureReturn 2
        
    EndIf
        
        
    res waveOutWrite_(Sound_WaveOutHandle, @Sound_WaveHdrSizeOf(WAVEHDR))
        
    Debug_ ("waveOutWrite "+Str(res))
        
        If 
    res<>0
            ProcedureReturn 3
        
    EndIf

        
    Sound_Software_FillBlock 0
        Sound_Software_RealBlock 
    0
        Sound_Software_UpdateMutex 
    #False
        
    Sound_SampleCount 0
        Sound_Software_Exit 
    #False
        
        
    Debug_ ("Create thread")
        
        
    timeBeginPeriod_(1)
        
    Sound_Software_Thread CreateThread(@Sound_Software_DoubleBufferThread(), 0)
        
    ThreadPriority(Sound_Software_Thread32)                                            ; THREAD_PRIORITY_TIME_CRITICAL)
        
        
    Debug_ ("")
        
        
    ProcedureReturn 0
    EndProcedure

    Procedure
    .l Sound_Stop()

        
    Debug_("Sound stop")

        ; 
    kill Thread
        Sound_Software_Exit 
    #True
        
    While Not Sound_Software_ThreadFinished
            Debug_ 
    ("Wait thread")
            
    Sleep_(10)
        
    Wend
        Sound_Software_Thread 
    0
        Debug_
    ("Kill thread")

        
    res waveOutReset_(Sound_WaveOutHandle)
        
    Debug_ ("waveOutReset "+Str(res)) 
        
        
    res waveOutUnprepareHeader_(Sound_WaveOutHandle, @Sound_WaveHdrSizeOf(WAVEHDR))
        
    Debug_ ("waveOutUnprepareHeader "+Str(res))
        
        
    Debug_ ("WHDR_DONE flag " StrSound_WaveHdr\dwFlags #WHDR_DONE ))    

        
    res waveOutClose_(Sound_WaveOutHandle)
        
    Debug_ ("waveOutClose "+Str(res))
        
        
    Sound_FreeBuffer()
        
        
    ProcedureReturn 0 
    EndProcedure

    Procedure
    .l Sound_SetCallbackReset(adress.l)
        If 
    adress<>0
            Sound_CallbackReset 
    adress
            ProcedureReturn 1
        
    Else
            
    ProcedureReturn 0
        
    EndIf
    EndProcedure

    Procedure
    .l Sound_GetCallbackReset()
        
    ProcedureReturn Sound_CallbackReset
    EndProcedure

    Procedure
    .l Sound_SetCallbackSample(adress.l)
        If 
    adress<>0
            Sound_CallbackSample 
    adress
            ProcedureReturn 1
        
    Else
            
    ProcedureReturn 0
        
    EndIf
    EndProcedure

    Procedure
    .l Sound_GetCallbackSample()
        
    ProcedureReturn Sound_CallbackSample
    EndProcedure

    Procedure
    .l Sound_SetCallbackTick(adress.l)
        If 
    adress<>0
            Sound_CallbackTick 
    adress
            ProcedureReturn 1
        
    Else
            
    ProcedureReturn 0
        
    EndIf
    EndProcedure

    Procedure
    .l Sound_GetCallbackTick()
        
    ProcedureReturn Sound_CallbackTick
    EndProcedure

    Procedure
    .l Sound_SetCallbackUpdate(adress.l)
        If 
    adress<>0
            Sound_CallbackUpdate 
    adress
            ProcedureReturn 1
        
    Else
            
    ProcedureReturn 0
        
    EndIf
    EndProcedure

    Procedure
    .l Sound_GetCallbackUpdate()
        
    ProcedureReturn Sound_CallbackUpdate
    EndProcedure

    Procedure
    .l Sound_SetCallbacks(adressReset.ladressSample.ladressUpdate.ladressTick.l)
        
    Sound_SetCallbackReset (adressReset)
        
    Sound_SetCallbackSample (adressSample)
        
    Sound_SetCallbackTick (adressTick)
        
    Sound_SetCallbackUpdate (adressUpdate)
    EndProcedure

    Procedure
    .l Sound_Software_DoubleBufferThread(value.l)
        Protected 
    mmt.MMTIME
        
    Protected cursorpos.l
        
    Protected cursorblock.l
        
    Protected prevblock.l    
        
        
    ;Debug_ ("Thread Started")
        
    Sound_Software_ThreadFinished #False    
        
        
    While Not Sound_Software_Exit

             mmt
    \wType #TIME_BYTES
             
    waveOutGetPosition_(Sound_WaveOutHandle, @mmtSizeOf(MMTIME))
             
    cursorpos mmt\u\cb >> 2
             cursorpos 
    Sound_BufferSize         
             cursorblock 
    cursorpos Sound_BlockSize
             
             
    ;Debug_(Str(cursorpos)+" "+Str(cursorblock)+" "+Str(Sound_Software_FillBlock))

            
    prevblock cursorblock 1
            
    If prevblock 0
                prevblock 
    Sound_TotalBlocks  1
            
    EndIf

             While 
    Sound_Software_FillBlock <> cursorblock
                 Sound_Software_UpdateMutex 
    #True
                 
    Sound_Software_Fill()
                 
    Sound_Software_RealBlock+1
                 
    If Sound_Software_RealBlock >= Sound_TotalBlocks 
                     Sound_Software_RealBlock 
    0
                
    EndIf
                
    Sound_Software_UpdateMutex #False
            
    Wend
            
            
    If Sound_CallbackUpdate<>0  :  CallFunctionFast(Sound_CallbackUpdate)  :  EndIf
            
            
    Sleep_(#Sound_SLEEPTIME)
        
    Wend
        
    ;Debug_ ("Thread Finished")
        
    Sound_Software_ThreadFinished #True
    EndProcedure 

  9. #18
    Member Аватар для mungo
    Регистрация
    04.10.2006
    Адрес
    Минск
    Сообщений
    89
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Если у нас есть 71680 тактов на кадр, 882 куска звука, то получается нам надо рендерить каждые 81.26 тактов.
    Ну с AY пока абы что, но это понятно, только понял как оно работает. Но вот спикер - девайс простейший. Ни волны, ни плавных уровней. Сразу же заработало. Диззик прекрасно пищит, прям как на реале. Чудесно.
    Но вот дальше тупичок. Почему-то простой клавиатурный "пук" не слышен. Там нет никаких хитростей?
    Сомневаюсь, и вам советую!

  10. #19
    Veteran Аватар для ZXMAK
    Регистрация
    30.01.2006
    Адрес
    Харьков
    Сообщений
    1,404
    Спасибо Благодарностей отдано 
    2
    Спасибо Благодарностей получено 
    19
    Поблагодарили
    13 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от mungo Посмотреть сообщение
    Ну я подготовил фрейм, проиграл отрывок, пошел следующий готовить. Так вот при любом раскладе получается как в том отрывке, что я приводил - по сути бесконечный цикл с паузой только на проигрывание отрывка. Вот тут и получается, что каким бы методом я не ждал - вашим или своим (из MSDN), я получаю щелчок.
    пишешь данные в буфер постоянно, пока данных нету - пишешь нули, вот и все
    ZXMAK2 - Виртуальная Машина ZX Spectrum https://github.com/zxmak/ZXMAK2 (старая ссылка http://zxmak2.codeplex.com)
    ZXMAK.NET - спектрум на C# http://sourceforge.net/projects/zxmak-dotnet

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

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

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

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

Похожие темы

  1. [Поиск 1] Эмуляция
    от KingArthur в разделе Поиск
    Ответов: 192
    Последнее: 05.12.2021, 15:48
  2. Эмуляция ПЗУ с помощью МК
    от research в разделе Память
    Ответов: 51
    Последнее: 10.04.2012, 14:35
  3. Эмуляция Sprinter'а
    от breeze в разделе Эмуляторы
    Ответов: 7
    Последнее: 28.03.2008, 23:08
  4. Эмуляция инструкции IM 0/1
    от DZh в разделе Эмуляторы
    Ответов: 1
    Последнее: 09.03.2008, 09:20

Ваши права

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