Subversion Repositories Kolibri OS

Rev

Rev 4323 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. SSMIX_CHANMODE_FREE   equ 0
  2. SSMIX_CHANMODE_SINGLE equ 1
  3. SSMIX_CHANMODE_REPEAT equ 2
  4. SSMIX_CHANMODE_SINGLE_WITHOUT_RESET equ 3
  5. SSMIX_CHANMODE_WAITRESET equ 4
  6.  
  7. include  'snd.inc'
  8. include  'snd_const.inc'
  9. include  '../../proc32.inc'
  10. ;include  'macros.inc'
  11. ;include  'debug.inc'
  12.  
  13. SSMIX_CHANNEL_COUNT equ 32
  14.  
  15. DEBUG equ 0 ; 0
  16.  
  17.  
  18. ; èíèöèàëèçàöèÿ ìèêøåðà
  19. ssmix_init:
  20. ; âûäåëèòü ïàìÿòü äëÿ êàíàëîâ ìèêøåðà
  21.     mov  eax, 68
  22.     mov  ebx, 12
  23.     mov  ecx, 4*8*SSMIX_CHANNEL_COUNT
  24.     int  0x40
  25.     mov  [ssmix_channels], eax
  26. ; âûäåëèòü ïàìÿòü äëÿ ñòåêà ïîòîêà ìèêøåðà
  27.     mov  eax, 68
  28.     mov  ebx, 12
  29.     mov  ecx, 4096
  30.     int  0x40
  31.     mov  [ssmix_thread_stack], eax
  32. ; âêëþ÷èòü ìèêøåð
  33.     mov  [ssmix_state], 1
  34. ; óñòàíîâèòü ãðîìêîñòè ñòåðåîêàíàëîâ
  35.     mov  [ssmix_volumeL], 128
  36.     mov  [ssmix_volumeR], 128
  37. ; ñîçäàòü ïîòîê
  38.     mov  eax, 51
  39.     mov  ebx, 1
  40.     mov  ecx, ssmix_thread_proc
  41.     mov  edx,[ssmix_thread_stack]
  42.     add  edx,4092
  43.     int 0x40
  44.  
  45.     ret
  46.  
  47.  
  48.  
  49. ; çàâåðøåíèå ðàáîòû ìèêøåðà
  50. ssmix_release:
  51. ; âûêëþ÷èòü ìèêøåð
  52.     mov  [ssmix_state], 0
  53.  
  54.     ret
  55.  
  56.  
  57.  
  58. ; îñâîáîæäåíèå ïàìÿòè
  59. ssmix_free:
  60. ; îñâîáîäèòü ïàìÿòü êàíàëîâ ìèêøåðà
  61.     mov  eax, 68
  62.     mov  ebx, 13
  63.     mov  ecx, [ssmix_channels]
  64.     int  0x40
  65. ; îñâîáîäèòü ïàìÿòü ñòåêà ïîòîêà ìèêøåðà
  66.     mov  eax, 68
  67.     mov  ebx, 13
  68.     mov  ecx, [ssmix_thread_stack]
  69.     int  0x40
  70.  
  71.     ret
  72.  
  73. ; óñòàíîâèòü ãðîìêîñòü
  74. ssmix_setvolume:  ; stdcall
  75.                   ; LeftVolume: dword, RightVolume: dword
  76.  
  77.     push  eax
  78.     mov   eax, [esp+8]   ; ãðîìêîñòü ëåâîãî êàíàëà
  79.     cmp   eax, 255
  80.     jle   @f
  81.     mov   eax, 255
  82.   @@:
  83.     cmp   eax, 0
  84.     jge   @f
  85.     mov   eax, 0
  86.   @@:
  87.     mov   [ssmix_volumeL], eax
  88.  
  89.     mov   eax, [esp+12]   ; ãðîìêîñòü ïðàâîãî êàíàëà
  90.     cmp   eax, 255
  91.     jle   @f
  92.     mov   eax, 255
  93.   @@:
  94.     cmp   eax, 0
  95.     jge   @f
  96.     mov   eax, 0
  97.   @@:
  98.     mov   [ssmix_volumeR], eax
  99.     pop   eax
  100.  
  101.     ret
  102.  
  103.  
  104. ; âîñïðîèçâåñòè òðåê
  105. ssmix_playtrack:  ; stdcall
  106.                   ; p_starttrack:dword, p_endtrack:dword, volumeL: dword, volumeR: dword; playmode:dword;
  107.                   ; return eax - number of channel, if eax=-1 then no free channel
  108.  
  109.     push  ebx ecx
  110.     mov   ebx, [ssmix_channels]
  111.     mov   ecx, SSMIX_CHANNEL_COUNT
  112.   .channel_loop:
  113.     mov   eax, [ebx]
  114.     cmp   eax, SSMIX_CHANMODE_FREE
  115.     je    .find_free_channel
  116.     add   ebx, 32
  117.     dec   ecx
  118.     jnz   .channel_loop
  119.     mov   eax, -1
  120.     jmp   .end
  121.   .find_free_channel:
  122.     mov   eax, [esp+28]   ; ðåæèì âîñïðîèçâåäåíèÿ
  123.     mov   [ebx], eax
  124.     mov   eax, [esp+20]   ; ãðîìêîñòü ëåâîãî êàíàëà
  125.     imul  eax, [ssmix_volumeL]
  126.     sar   eax, 7
  127.     mov   [ebx+4], eax
  128.     mov   eax, [esp+24]   ; ãðîìêîñòü ïðàâîãî êàíàëà
  129.     imul  eax, [ssmix_volumeR]
  130.     sar   eax, 7
  131.     mov   [ebx+8], eax
  132.     mov   eax, [esp+12]   ; íà÷àëî òðåêà
  133.     mov   [ebx+16], eax
  134.     mov   [ebx+20], eax
  135.     mov   eax, [esp+16]   ; êîíåö òðåêà
  136.     mov   [ebx+24], eax
  137.     mov   eax, SSMIX_CHANNEL_COUNT
  138.     sub   eax, ecx
  139.   .end:
  140.     pop   ecx ebx
  141.  
  142.     ret   20
  143.  
  144.  
  145. ; îñòàíîâèòü òðåê ïî íîìåðó êàíàëà
  146. ssmix_stoptrack:    ; stdcall
  147.                     ; numchannel: dword
  148.     push  eax ebx
  149.     mov   ebx, [esp+12]
  150.     cmp   ebx, 0
  151.     jl    .end
  152.     cmp   ebx, SSMIX_CHANNEL_COUNT
  153.     jge   .end
  154.     shl   ebx, 5
  155.     add   ebx, [ssmix_channels]
  156.     mov   eax, SSMIX_CHANMODE_FREE
  157.     mov   [ebx], eax
  158.   .end:
  159.     pop   ebx eax
  160.  
  161.     ret   4
  162.  
  163.  
  164. ; îñòàíîâèòü âñå òðåêè
  165. ssmix_stopalltracks:
  166.  
  167.     push  eax ebx ecx
  168.     mov   eax, SSMIX_CHANMODE_FREE
  169.     mov   ebx, [ssmix_channels]
  170.     mov   ecx, SSMIX_CHANNEL_COUNT
  171.   .channel_loop:
  172.     mov   [ebx], eax
  173.     add   ebx, 32
  174.     dec   ecx
  175.     jnz   .channel_loop
  176.     pop   ecx ebx eax
  177.  
  178.     ret
  179.  
  180.  
  181. ; ïîòîê ìèêøåðà
  182. ssmix_thread_proc:
  183.  
  184.     stdcall  _InitSound@4, ssmix_driver_version
  185.     test eax, eax
  186.     jz  @f
  187.     if DEBUG
  188.        print "ssmix. Cannot load sound driver"
  189.     end if
  190.     jmp  .end
  191.   @@:
  192.  
  193.     mov  ecx, [ssmix_driver_version]
  194.     cmp  cx, SOUND_VERSION
  195.     jae  @f
  196.     shr  ecx, 16
  197.     cmp  ecx, SOUND_VERSION
  198.     jbe  @f
  199.     if DEBUG
  200.        print "ssmix. Sound version mismatch"
  201.     end if
  202.     jmp  .end
  203.   @@:
  204.  
  205.     stdcall _CreateBuffer@12, PCM_2_16_11+PCM_RING, 0, ssmix_hbuffer
  206.     test eax, eax
  207.     jz  @f
  208.     if DEBUG
  209.        print "ssmix. create buffer error"
  210.     end if
  211.     jmp  .end
  212.   @@:
  213.  
  214.     stdcall _GetBufferSize@8, [ssmix_hbuffer], ssmix_buffer_size
  215.     test eax, eax
  216.     jz  @f
  217.     if DEBUG
  218.        print "ssmix. getbuffersize procedure error"
  219.     end if
  220.     jmp  .destroy_buffer
  221.   @@:
  222.  
  223.     mov  ecx, [ssmix_buffer_size]
  224.     shr  ecx, 1
  225.     mov  [ssmix_buffer_size], ecx
  226.     if DEBUG
  227.         print "ssmix. buffer size"
  228.         dph  ecx
  229.         newline
  230.     end if
  231.  
  232.     ; âûäåëèòü ïàìÿòü äëÿ áóôôåðà âîñïðîèçâåäåíèÿ
  233.     mov  eax, 68
  234.     mov  ebx, 12
  235.     mov  ecx, [ssmix_buffer_size]
  236.     int  0x40
  237.     test eax, eax
  238.     jnz  @f
  239.     if DEBUG
  240.        print "ssmix. malloc memory error"
  241.     end if
  242.     jmp  .destroy_buffer
  243.   @@:
  244.     mov  [ssmix_pbuffer], eax
  245.  
  246.     stdcall _PlayBuffer@8, [ssmix_hbuffer], 0
  247.     test eax, eax
  248.     jz   @f
  249.     if DEBUG
  250.        print "ssmix. playbuffer error"
  251.     end if
  252.     jmp  .free_buffer_memory
  253.   @@:
  254.  
  255. ; öèêë âîñïðîèçâåäåíèÿ
  256.   .mixloop:
  257. ; ïîëó÷èòü äàííûå ñîáûòèÿ îò äðàéâåðà
  258.     mov  eax, 68
  259.     mov  ebx, 14
  260.     mov  ecx, ssmix_driver_notify_struct
  261.     int  0x40
  262. ; ïðîâåðêà íà code
  263.     mov  eax, [ssmix_driver_notify_struct]
  264.     cmp  eax, 0xFF000001
  265.     jne  .mixloop
  266. ; ïðîâåðêà íà stream
  267.     mov  eax, [ssmix_driver_notify_struct+8]
  268.     cmp  eax, [ssmix_hbuffer]
  269.     jne  .mixloop
  270. ; ïîëó÷èòü ñìåùåíèå â áóôôåðå
  271.     mov  eax, [ssmix_driver_notify_struct+12]
  272.     mov  [ssmix_buffer_offset], eax
  273. ; öèêë çàïîëíåíèÿ áóôôåðà
  274.     mov  ebx, [ssmix_pbuffer]
  275.     mov  ecx, [ssmix_buffer_size]
  276.     shr  ecx, 2
  277.   .fill_buffer_loop:
  278.     push  ebx ecx
  279. ; öèêë ñìåøèâàíèÿ êàíàëîâ
  280.     mov   esi, 0    ; ñóììà äëÿ ëåâîãî ñòåðåîêàíàëà
  281.     mov   edi, 0    ; ñóììà äëÿ ïðàâîãî ñòåðåîêàíàëà
  282.     mov   edx, [ssmix_channels]
  283.     mov   ecx, SSMIX_CHANNEL_COUNT
  284.   .channel_loop:
  285.     mov   eax, [edx]
  286.     cmp   eax, SSMIX_CHANMODE_FREE
  287.     je    .channel_end
  288.     cmp   eax, SSMIX_CHANMODE_WAITRESET
  289.     je    .channel_end
  290.     push  ecx
  291. ; ñìåøèâàíèå êàíàëîâ ñ ó÷åòîì ãðîìêîñòè
  292.     mov   ebx, [edx+4]
  293.     mov   ecx, [edx+16]
  294.     movsx eax, word [ecx]
  295.     imul  eax, ebx
  296.     add   esi, eax
  297.     mov   ebx, [edx+8]
  298.     movsx eax, word [ecx+2]
  299.     imul  eax, ebx
  300.     add   edi, eax
  301. ; ïðîâåðêà íà çàâåðøåíèå òðåêà
  302.     add   ecx, 4
  303.     cmp   ecx, [edx+24]
  304.     jb    .notrackend
  305.     mov   eax, [edx]
  306.     cmp   eax, SSMIX_CHANMODE_SINGLE
  307.     jne    @f
  308.     mov   ebx, SSMIX_CHANMODE_FREE
  309.     mov   [edx], ebx
  310.     jmp   .notrackend
  311.   @@:
  312.     cmp   eax, SSMIX_CHANMODE_REPEAT
  313.     jne    @f
  314.     mov   ecx, [edx+20]
  315.     jmp   .notrackend
  316.   @@:
  317.     cmp   eax, SSMIX_CHANMODE_SINGLE_WITHOUT_RESET
  318.     jne    @f
  319.     mov   ebx, SSMIX_CHANMODE_WAITRESET
  320.     mov   [edx], ebx
  321.     jmp   .notrackend
  322.   @@:
  323.   .notrackend:
  324.     mov   [edx+16], ecx
  325.     pop   ecx
  326.   .channel_end:
  327.     add   edx, 32
  328.     dec   ecx
  329.     jnz   .channel_loop
  330. ; íîðìàëèçàöèÿ ñòåðåîêàíàëîâ
  331.     sar   esi, 7
  332.     cmp   esi, 0x7FFF
  333.     jle   @f
  334.     mov   esi, 0x7FFF
  335.   @@:
  336.     cmp   esi, -0x8000
  337.     jge   @f
  338.     mov   esi, -0x8000
  339.   @@:
  340.     sar   edi, 7
  341.     cmp   edi, 0x7FFF
  342.     jle   @f
  343.     mov   edi, 0x7FFF
  344.   @@:
  345.     cmp   edi, -0x8000
  346.     jge   @f
  347.     mov   edi, -0x8000
  348.   @@:
  349. ; ñîõðàíåíèå ðåçóëüòàòà â áóôôåðå ìèêøåðà
  350.     shl   edi, 16
  351.     add   esi, edi
  352.     pop   ecx ebx
  353.     mov  [ebx], esi
  354.     add  ebx, 4
  355.     dec  ecx
  356.     jnz  .fill_buffer_loop
  357. ; óñòàíîâêà áóôôåðà äðàéâåðà
  358.     stdcall _SetBuffer@16, [ssmix_hbuffer], [ssmix_pbuffer], [ssmix_buffer_offset], [ssmix_buffer_size]
  359.     cmp  [ssmix_state], 1
  360.     je   .mixloop
  361.  
  362. ; îñâîáîäèòü ïàìÿòü áóôôåðà âîñïðîèçâåäåíèÿ
  363.   .free_buffer_memory:
  364.     mov  eax, 68
  365.     mov  ebx, 13
  366.     mov  ecx, [ssmix_pbuffer]
  367. ; óíè÷òîæèòü áóôôåð äðàéâåðà
  368.   .destroy_buffer:
  369.     stdcall _DestroyBuffer@4, [ssmix_hbuffer]
  370.  
  371. ; çàâåðøèòü ðàáîòó ïîòîêà
  372.   .end:
  373.     call  ssmix_free
  374.     mov   eax, -1
  375.     int   0x40
  376.  
  377.     ;ret
  378.  
  379.  
  380. ;=================================================================================
  381.  
  382. align 4
  383. _InitSound@4:       ;p_ver:dword
  384.  
  385.            push ebx
  386.            push ecx
  387.  
  388.            mov eax, 68
  389.            mov ebx, 16
  390.            mov ecx, ssmix_szInfinity
  391.            int 0x40
  392.            mov [ssmix_hSound], eax
  393.            test eax, eax
  394.            jz .fail
  395.  
  396.            mov eax, 68
  397.            mov ebx, 16
  398.            mov ecx, ssmix_szSound
  399.            int 0x40
  400.            mov [ssmix_hrdwSound], eax
  401.  
  402.            lea eax, [esp+12]   ;p_ver
  403.            xor ebx, ebx
  404.  
  405.            push 4              ;.out_size
  406.            push eax            ;.output
  407.            push ebx            ;.inp_size
  408.            push ebx            ;.input
  409.            push SRV_GETVERSION ;.code
  410.            push [ssmix_hSound]       ;.handle
  411.  
  412.            mov eax, 68
  413.            mov ebx, 17
  414.            mov ecx, esp        ;[handle]
  415.            int 0x40
  416.            add esp, 24
  417.            pop ecx  
  418.            pop ebx
  419.            ret 4
  420. .fail:
  421.            or eax, -1
  422.            pop ecx  
  423.            pop ebx
  424.            ret 4
  425.  
  426.  
  427. align 4
  428. _CreateBuffer@12:   ;format:dword,size:dword,p_str:dword
  429.  
  430.            push ebx
  431.            push ecx
  432.            lea eax, [esp+20]   ;p_str
  433.            lea ebx, [esp+12]   ;format
  434.  
  435.            push 4              ;.out_size
  436.            push eax            ;.output
  437.            push 8              ;.inp_size
  438.            push ebx            ;.input
  439.            push SND_CREATE_BUFF;.code
  440.            push [ssmix_hSound]       ;.handle
  441.  
  442.            mov eax, 68
  443.            mov ebx, 17
  444.            mov ecx, esp
  445.            int 0x40
  446.            add esp, 24       ;io_cintrol
  447.            pop ecx
  448.            pop ebx
  449.            ret 12
  450.  
  451. align 4
  452. _DestroyBuffer@4:     ;str:dword
  453.  
  454.            push ebx
  455.            push ecx
  456.  
  457.            xor eax, eax
  458.            lea ebx, [esp+12]   ;[stream]
  459.  
  460.            push eax            ;.out_size
  461.            push eax            ;.output
  462.            push 4              ;.inp_size
  463.            push ebx            ;.input
  464.            push SND_DESTROY_BUFF;.code
  465.            push [ssmix_hSound]       ;.handle
  466.  
  467.            mov eax, 68
  468.            mov ebx, 17
  469.            mov ecx, esp        ;[handle]
  470.            int 0x40
  471.            add esp, 24
  472.            pop ecx
  473.            pop ebx
  474.            ret 4
  475.  
  476. align 4
  477. _GetBufferSize@8:      ;str:dword, p_size:dword
  478.            
  479.            push ebx
  480.            push ecx
  481.            
  482.            lea eax, [esp+16]
  483.            lea ebx, [esp+12]   ;[stream]
  484.  
  485.            push 4              ;.out_size
  486.            push eax            ;.output
  487.            push 4              ;.inp_size
  488.            push ebx            ;.input
  489.            push SND_GETBUFFSIZE;.code
  490.            push dword [ssmix_hSound] ;.handle
  491.  
  492.            mov eax, 68
  493.            mov ebx, 17
  494.            mov ecx, esp
  495.            int 0x40
  496.            add esp, 24
  497.            pop ecx
  498.            pop ebx
  499.            ret 8
  500.  
  501. align 4
  502. _SetBuffer@16:   ;str:dword, src:dword, offs:dword, size:dword
  503.  
  504.            push ebx
  505.            push ecx
  506.            
  507.            xor eax, eax
  508.            lea ebx, [esp+12]   ;[stream]
  509.  
  510.            push eax            ;.out_size
  511.            push eax            ;.output
  512.            push 16             ;.inp_size
  513.            push ebx            ;.input
  514.            push SND_SETBUFF    ;.code
  515.            push dword [ssmix_hSound] ;.handle
  516.  
  517.            mov eax, 68
  518.            mov ebx, 17
  519.            mov ecx, esp
  520.            int 0x40
  521.            add esp, 24
  522.            pop ecx
  523.            pop ebx
  524.            ret 16
  525.            
  526. align 4
  527. _PlayBuffer@8:          ;str:dword,flags:dword
  528.  
  529.            push ebx
  530.            push ecx
  531.  
  532.            xor eax, eax
  533.            lea ebx, [esp+12]   ;[stream]
  534.  
  535.            push eax            ;.out_size
  536.            push eax            ;.output
  537.            push 8              ;.inp_size
  538.            push ebx            ;.input
  539.            push SND_PLAY       ;.code
  540.            push dword [ssmix_hSound] ;.handle
  541.  
  542.            mov eax, 68
  543.            mov ebx, 17
  544.            mov ecx, esp
  545.            int 0x40
  546.            add esp, 24
  547.            pop ecx
  548.            pop ebx
  549.            ret 8
  550.  
  551.  
  552.  
  553. ; ========================= data  =====================================
  554.  
  555. ssmix_hSound      dd ?
  556. ssmix_hrdwSound   dd ?
  557.  
  558. ssmix_szInfinity  db 'INFINITY',0
  559. ssmix_szSound     db 'SOUND',0
  560.  
  561. ssmix_channels dd 0
  562. ssmix_thread_stack dd 0
  563. ssmix_state dd 0
  564. ssmix_volumeL dd ?
  565. ssmix_volumeR dd ?
  566. ssmix_driver_version dd ?
  567. ssmix_hbuffer dd ?
  568. ssmix_pbuffer dd 0
  569. ssmix_buffer_size dd ?
  570. ssmix_buffer_offset dd ?
  571. ssmix_driver_notify_struct rd 6   ; ñòêóêòóðà ñîáûòèÿ îò äðàéâåðà