home *** CD-ROM | disk | FTP | other *** search
/ FreeWare Collection 3 / FreeSoftwareCollection3pd199x-jp.img / pao / t_os / sound / src / pmb.c < prev    next >
Text File  |  1980-01-02  |  26KB  |  918 lines

  1. /*
  2. **    < High C V1.4  &  386ASM V2.0 >
  3. **
  4. **    PMBファイルで音を出します。
  5. **
  6. **    1990.08.29 : CREATE
  7. **    1990.08.31 : FINISH
  8. **
  9. **    < HISTORY >
  10. **    1990.08.29 : CREATE
  11. **
  12. **    < note > : TABS = 4
  13. **
  14. **    Programed by Y.Hirata ( Nifty ID : NAB03321 )
  15. **
  16. */
  17.  
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <snd.h>
  22. #include <fmc.h>
  23. #include <dos.h>
  24. #include <msdos.cf>
  25. #include "pmb.h"
  26.  
  27. #define        SworkSize    16384                        /*  サウンド用作業域サイズ    */
  28. char    Swork[SworkSize];                            /*  サウンド用作業域        */
  29.  
  30. char    Pmbfile[128] ;                                /*  PCM 音色ファイル        */
  31.  
  32. int        Pmbsize ;                                    /*  PCM 音色データサイズ    */
  33. char    *Pmbdata ;                                    /*  PCM 音色格納領域    */
  34. char    Pmbflg = FALSE ;                            /*  PCM 音色 READ フラグ    */
  35.  
  36. int        Inst1 = 0 ;                                    /*  キーボード上段用        */
  37. int        Inst2 = 0 ;                                    /*  キーボード下段用        */
  38.  
  39. int        Pan1 = 64 ;                                    /*  キーボード上段            */
  40. int        Pan2 = 64 ;                                    /*  キーボード下段            */
  41.  
  42. int        ValNote1 = 0 ;                                /*  キーボード上段音程用    */
  43. int        ValNote2 = 0 ;                                /*  キーボード下段音程用    */
  44.  
  45. typedef struct {
  46.     char    _reserved[21] ;                    /*  reserved area            */
  47.     char    _attrib ;                        /*  attribute byte            */
  48.     ushort    _ftime ;                         /*  time of file            */
  49.     ushort    _fdate ;                        /*  date of file            */
  50.     ulong    _fsize ;                        /*  file size                */
  51.     char    d_name[13] ;                    /*  packed file name        */
  52. } DIR ;
  53.  
  54. /*************************  DTAの設定  ************************************/
  55. void setdta( p )
  56. DIR *p ;
  57. {
  58.     Registers.AX.LH.H = 0x1a ;
  59.     Registers.DX.R = (uint)p ;
  60.     Registers.DS.R = getds() ;
  61.     calldos() ;
  62. }
  63.  
  64. /*******************  最初に一致するファイル名の検索  ************************/
  65. int firstsearch( path,attr,dta )
  66. char    *path ;
  67. int        attr ;
  68. DIR        *dta ;
  69. {
  70.     setdta( dta ) ;
  71.     Registers.AX.LH.H = 0x4e ;
  72.     Registers.CX.R = attr ;                        /*  ファイルの種類    */
  73.     Registers.DX.R = (uint)path ;                /*  ファイル名        */
  74.     Registers.DS.R = getds() ;
  75.     calldos();
  76.     if ( (Registers.Flags & 0x0001) != 0 )
  77.         return ( FALSE ) ;
  78.     else
  79.         return ( TRUE ) ;                    /*  成功ならば 真 でreturn    */
  80. }
  81.  
  82. /***************************  ファイルサイズ取得  ****************************/
  83. int getfsize()
  84. {
  85.     DIR        dta ;
  86.     ushort    attr=0 ;
  87.  
  88.     if ( firstsearch( Pmbfile,attr,&dta ) ) {        /*  最初のエントリ    */
  89.         Pmbsize = dta._fsize ;
  90.         return( dta._fsize ) ;
  91.     } else {                                    /*  ファイルが見つからない    */
  92.         return( -1 ) ;
  93.     }
  94. }
  95.  
  96. /***************************  PMB DATA の読込み  *****************************/
  97. void pmb_load()
  98. {
  99.     FILE *fp;
  100.  
  101.     getfsize() ;
  102.     Pmbdata = malloc( Pmbsize ) ;                /*  PMB データ格納領域確保    */
  103.     if ( Pmbdata == NULL ) {
  104.         Pmbflg = FALSE ;
  105.         printf("<pmb_load> malloc error!\n") ;
  106.     } else {
  107.         fp = fopen( Pmbfile,"rb" ) ;
  108.         fread( Pmbdata,1,Pmbsize,fp ) ;
  109.         fclose( fp ) ;
  110.     }
  111. }
  112.  
  113. /******************************************************************************
  114.     KEY_test : マトリクスからキーが押されているかどうかをチェックする。
  115. ******************************************************************************/
  116. int        KEY_test( char *matrix, char keyadrs )
  117. /*    *matrix : キーマトリクス情報( 16 バイト )                                        */
  118. /*    keyadrs : キーアドレス                                                        */
  119. {
  120.     unsigned char    testbit ;
  121.     int        c ;
  122.  
  123.     testbit = 0x01 ;
  124.     for ( c=0; c<(keyadrs%8); c++ ) testbit <<= 1 ;
  125.     if ( (matrix[keyadrs/8] & testbit) == testbit ) return( TRUE ) ;
  126.  
  127.     return( 0 ) ;
  128. }
  129.  
  130. /****************************  1つ上の音色に変更  ****************************/
  131. void inst_change_up( int kyb1, int kyb2 )
  132. /*    kyb  : キーボードの上/下段フラグ                                                */
  133. {
  134.     char    matrix[16] ;                            /*  キーマトリクス取得用        */
  135.     char    keyrepflg ;                                /*  キーリピート用フラグ        */
  136.     char    name[9] ;                                /*  FMBインスト名            */
  137.  
  138.     if ( !Pmbflg ) {
  139.         printf("\x1b[33m") ;
  140.         printf("☆☆☆  音色の変更はできません!  ☆☆☆") ;
  141.         printf("\x1b[m\n") ;
  142.         return ;
  143.     }
  144.  
  145.     keyrepflg = FALSE ;                                /*  キーリピートフラグ・クリア        */
  146.     do {
  147.  
  148.         if ( kyb1 == KYB_UPPER || kyb2 == KYB_UPPER ) {        /*  キーボード上段    */
  149.             if ( Inst1 == 31 )
  150.                 Inst1 = 0 ;
  151.             else
  152.                 Inst1 ++ ;
  153.             SND_inst_change( 64,Inst1 ) ;
  154.             SND_inst_change( 65,Inst1 ) ;
  155.             SND_inst_change( 66,Inst1 ) ;
  156.             SND_inst_change( 67,Inst1 ) ;
  157.             printf("キーボード上段の音色を変更しました。") ;
  158.             printf("(INST:%03d)",Inst1) ;
  159.             strncpy( name,&Pmbdata[8+Inst1*128],8 ) ;
  160.             name[8] = '\0' ;
  161.             printf(" < %s >\n",name) ;
  162.         }
  163.  
  164.         if ( kyb1 == KYB_LOWER || kyb2 == KYB_LOWER ) {        /*  キーボード下段    */
  165.             if ( Inst2 == 31 )
  166.                 Inst2 = 0 ;
  167.             else
  168.                 Inst2 ++ ;
  169.             SND_inst_change( 68,Inst2 ) ;
  170.             SND_inst_change( 69,Inst2 ) ;
  171.             SND_inst_change( 70,Inst2 ) ;
  172.             SND_inst_change( 71,Inst2 ) ;
  173.             printf("キーボード下段の音色を変更しました。") ;
  174.             printf("(INST:%03d)",Inst2) ;
  175.             strncpy( name,&Pmbdata[8+Inst2*128],8 ) ;
  176.             name[8] = '\0' ;
  177.             printf(" < %s >\n",name) ;
  178.         }
  179.  
  180.         if ( keyrepflg ) {
  181.             SOFT_timer( KEY_repeat ) ;
  182.         } else {
  183.             SOFT_timer( KEY_wait ) ;
  184.             keyrepflg = TRUE ;
  185.         }
  186.  
  187.          KYB_clrbuf() ;                                /*  キーバッファ・クリア            */
  188.         KYB_matrix( matrix ) ;                        /*  キーマトリクス取得            */
  189.  
  190.     } while ( KEY_test( matrix,KEY_UP ) ) ;
  191.  
  192.     printf("\n") ;
  193. }
  194.  
  195. /****************************  1つ下の音色に変更  ****************************/
  196. void inst_change_down( int kyb1, int kyb2 )
  197. /*    kyb  : キーボードの上/下段フラグ                                                */
  198. {
  199.     char    matrix[16] ;                            /*  キーマトリクス取得用        */
  200.     char    keyrepflg ;                                /*  キーリピート用フラグ        */
  201.     char    name[9] ;                                /*  FMBインスト名            */
  202.  
  203.     if ( !Pmbflg ) {
  204.         printf("\x1b[33m") ;
  205.         printf("☆☆☆  音色の変更はできません!  ☆☆☆") ;
  206.         printf("\x1b[m\n") ;
  207.         return ;
  208.     }
  209.  
  210.     keyrepflg = FALSE ;                                /*  キーリピートフラグ・クリア        */
  211.     do {
  212.  
  213.         if ( kyb1 == KYB_UPPER || kyb2 == KYB_UPPER ) {        /*  キーボード上段    */
  214.             if ( Inst1 == 0 )
  215.                 Inst1 = 31 ;
  216.             else
  217.                 Inst1 -- ;
  218.             SND_inst_change( 64,Inst1 ) ;
  219.             SND_inst_change( 65,Inst1 ) ;
  220.             SND_inst_change( 66,Inst1 ) ;
  221.             SND_inst_change( 67,Inst1 ) ;
  222.             printf("キーボード上段の音色を変更しました。") ;
  223.             printf("(INST:%03d)",Inst1) ;
  224.             strncpy( name,&Pmbdata[8+Inst1*128],8 ) ;
  225.             name[8] = '\0' ;
  226.             printf(" < %s >\n",name) ;
  227.         }
  228.  
  229.         if ( kyb1 == KYB_LOWER || kyb2 == KYB_LOWER ) {        /*  キーボード下段    */
  230.             if ( Inst2 == 0 )
  231.                 Inst2 = 31 ;
  232.             else
  233.                 Inst2 -- ;
  234.             SND_inst_change( 68,Inst2 ) ;
  235.             SND_inst_change( 69,Inst2 ) ;
  236.             SND_inst_change( 70,Inst2 ) ;
  237.             SND_inst_change( 71,Inst2 ) ;
  238.             printf("キーボード下段の音色を変更しました。") ;
  239.             printf("(INST:%03d)",Inst2) ;
  240.             strncpy( name,&Pmbdata[8+Inst2*128],8 ) ;
  241.             name[8] = '\0' ;
  242.             printf(" < %s >\n",name) ;
  243.         }
  244.  
  245.         if ( keyrepflg ) {
  246.             SOFT_timer( KEY_repeat ) ;
  247.         } else {
  248.             SOFT_timer( KEY_wait ) ;
  249.             keyrepflg = TRUE ;
  250.         }
  251.  
  252.          KYB_clrbuf() ;                                /*  キーバッファ・クリア            */
  253.         KYB_matrix( matrix ) ;                        /*  キーマトリクス取得            */
  254.  
  255.     } while ( KEY_test( matrix,KEY_DOWN ) ) ;
  256.  
  257.     printf("\n") ;
  258. }
  259.  
  260. /***************************  1つ右に音源定位変更  ***************************/
  261. void pan_change_right( int kyb1, int kyb2 )
  262. /*    kyb  : キーボードの上/下段フラグ                                                */
  263. {
  264.     char    matrix[16] ;                            /*  キーマトリクス取得用        */
  265.     char    keyrepflg ;                                /*  キーリピート用フラグ        */
  266.  
  267.     keyrepflg = FALSE ;                                /*  キーリピートフラグ・クリア        */
  268.     do {
  269.  
  270.         if ( kyb1 == KYB_UPPER || kyb2 == KYB_UPPER ) {        /*  キーボード上段    */
  271.             if ( Pan1 < 127 ) {
  272.                 if ( Pan1 == 96 ) {
  273.                     Pan1 = 127 ;
  274.                 } else {
  275.                     Pan1 += 32 ;
  276.                 }
  277.                 /*  PCM 音源の場合 :
  278.                      000~007, 008~015, 016~023, 024~031, 032~039,
  279.                     040~047, 048~055, 056~071, 072~079, 080~087,
  280.                     088~095, 096~103, 104~111, 112~119, 120~127
  281.                     の 15段階設定可能                                        */
  282.                 /*  しかし、ここでは 5段階にしている。                        */
  283.                 SND_pan_set( 64,Pan1 ) ;
  284.                 SND_pan_set( 65,Pan1 ) ;
  285.                 SND_pan_set( 66,Pan1 ) ;
  286.                 SND_pan_set( 67,Pan1 ) ;
  287.                 if ( Pan1 == 64 ) {
  288.                     printf("\x1b[36m") ;
  289.                     printf("キーボード上段の音源定位を中央に変更しました。  ") ;
  290.                     printf("\x1b[m") ;
  291.                 } else {
  292.                     printf("キーボード上段の音源定位を右よりに変更しました。") ;
  293.                 }
  294.                 printf("(PAN:%d)\n",Pan1) ;
  295.             } else {
  296.                 printf("\x1b[33m") ;
  297.                 printf("キーボード上段の音源定位は、右いっぱいです。") ;
  298.                 printf("\x1b[m") ;
  299.                 printf("(PAN:%d)\n",Pan1) ;
  300.             }
  301.         }
  302.  
  303.         if ( kyb1 == KYB_LOWER || kyb2 == KYB_LOWER ) {        /*  キーボード下段    */
  304.             if ( Pan2 < 127 ) {
  305.                 if ( Pan2 == 96 ) {
  306.                     Pan2 = 127 ;
  307.                 } else {
  308.                     Pan2 += 32 ;
  309.                 }
  310.                 /*  PCM 音源の場合 :
  311.                      000~007, 008~015, 016~023, 024~031, 032~039,
  312.                     040~047, 048~055, 056~071, 072~079, 080~087,
  313.                     088~095, 096~103, 104~111, 112~119, 120~127
  314.                     の 15段階設定可能                                        */
  315.                 /*  しかし、ここでは 5段階にしている。                        */
  316.                 SND_pan_set( 68,Pan2 ) ;
  317.                 SND_pan_set( 69,Pan2 ) ;
  318.                 SND_pan_set( 70,Pan2 ) ;
  319.                 SND_pan_set( 71,Pan2 ) ;
  320.                 if ( Pan2 == 64 ) {
  321.                     printf("\x1b[36m") ;
  322.                     printf("キーボード下段の音源定位を中央に変更しました。  ") ;
  323.                     printf("\x1b[m") ;
  324.                 } else {
  325.                     printf("キーボード下段の音源定位を右よりに変更しました。") ;
  326.                 }
  327.                 printf("(PAN:%d)\n",Pan2) ;
  328.             } else {
  329.                 printf("\x1b[33m") ;
  330.                 printf("キーボード下段の音源定位は、右いっぱいです。") ;
  331.                 printf("\x1b[m") ;
  332.                 printf("(PAN:%d)\n",Pan2) ;
  333.             }
  334.         }
  335.  
  336.         if ( keyrepflg ) {
  337.             SOFT_timer( KEY_repeat ) ;
  338.         } else {
  339.             SOFT_timer( KEY_wait ) ;
  340.             keyrepflg = TRUE ;
  341.         }
  342.  
  343.          KYB_clrbuf() ;                                /*  キーバッファ・クリア            */
  344.         KYB_matrix( matrix ) ;                        /*  キーマトリクス取得            */
  345.  
  346.     } while ( KEY_test( matrix,KEY_RIGHT ) ) ;
  347.  
  348.     printf("\n") ;
  349. }
  350.  
  351. /***************************  1つ左に音源定位変更  ***************************/
  352. void pan_change_left( int kyb1, int kyb2 )
  353. /*    kyb  : キーボードの上/下段フラグ                                                */
  354. {
  355.     char    matrix[16] ;                            /*  キーマトリクス取得用        */
  356.     char    keyrepflg ;                                /*  キーリピート用フラグ        */
  357.  
  358.     keyrepflg = FALSE ;                                /*  キーリピートフラグ・クリア        */
  359.     do {
  360.  
  361.         if ( kyb1 == KYB_UPPER || kyb2 == KYB_UPPER ) {        /*  キーボード上段    */
  362.             if ( Pan1 > 0 ) {
  363.                 if ( Pan1 == 127 ) {
  364.                     Pan1 = 96 ;
  365.                 } else {
  366.                     Pan1 -= 32 ;
  367.                 }
  368.                 /*  PCM 音源の場合 :
  369.                      000~007, 008~015, 016~023, 024~031, 032~039,
  370.                     040~047, 048~055, 056~071, 072~079, 080~087,
  371.                     088~095, 096~103, 104~111, 112~119, 120~127
  372.                     の 15段階設定可能                                        */
  373.                 /*  しかし、ここでは 5段階にしている。                        */
  374.                 SND_pan_set( 64,Pan1 ) ;
  375.                 SND_pan_set( 65,Pan1 ) ;
  376.                 SND_pan_set( 66,Pan1 ) ;
  377.                 SND_pan_set( 67,Pan1 ) ;
  378.                 if ( Pan1 == 64 ) {
  379.                     printf("\x1b[36m") ;
  380.                     printf("キーボード上段の音源定位を中央に変更しました。  ") ;
  381.                     printf("\x1b[m") ;
  382.                 } else {
  383.                     printf("キーボード上段の音源定位を左よりに変更しました。") ;
  384.                 }
  385.                 printf("(PAN:%d)\n",Pan1) ;
  386.             } else {
  387.                 printf("\x1b[33m") ;
  388.                 printf("キーボード上段の音源定位は、左いっぱいです。") ;
  389.                 printf("\x1b[m") ;
  390.                 printf("(PAN:%d)\n",Pan1) ;
  391.             }
  392.         }
  393.  
  394.         if ( kyb1 == KYB_LOWER || kyb2 == KYB_LOWER ) {        /*  キーボード下段    */
  395.             if ( Pan2 > 0 ) {
  396.                 if ( Pan2 == 127 ) {
  397.                     Pan2 = 96 ;
  398.                 } else {
  399.                     Pan2 -= 32 ;
  400.                 }
  401.                 /*  PCM 音源の場合 :
  402.                      000~007, 008~015, 016~023, 024~031, 032~039,
  403.                     040~047, 048~055, 056~071, 072~079, 080~087,
  404.                     088~095, 096~103, 104~111, 112~119, 120~127
  405.                     の 15段階設定可能                                        */
  406.                 /*  しかし、ここでは 5段階にしている。                        */
  407.                 SND_pan_set( 68,Pan2 ) ;
  408.                 SND_pan_set( 69,Pan2 ) ;
  409.                 SND_pan_set( 70,Pan2 ) ;
  410.                 SND_pan_set( 71,Pan2 ) ;
  411.                 if ( Pan2 == 64 ) {
  412.                     printf("\x1b[36m") ;
  413.                     printf("キーボード下段の音源定位を中央に変更しました。  ") ;
  414.                     printf("\x1b[m") ;
  415.                 } else {
  416.                     printf("キーボード下段の音源定位を左よりに変更しました。") ;
  417.                 }
  418.                 printf("(PAN:%d)\n",Pan2) ;
  419.             } else {
  420.                 printf("\x1b[33m") ;
  421.                 printf("キーボード下段の音源定位は、左いっぱいです。") ;
  422.                 printf("\x1b[m") ;
  423.                 printf("(PAN:%d)\n",Pan2) ;
  424.             }
  425.  
  426.         }
  427.  
  428.         if ( keyrepflg ) {
  429.             SOFT_timer( KEY_repeat ) ;
  430.         } else {
  431.             SOFT_timer( KEY_wait ) ;
  432.             keyrepflg = TRUE ;
  433.         }
  434.  
  435.          KYB_clrbuf() ;                                /*  キーバッファ・クリア            */
  436.         KYB_matrix( matrix ) ;                        /*  キーマトリクス取得            */
  437.  
  438.     } while ( KEY_test( matrix,KEY_LEFT ) ) ;
  439.  
  440.     printf("\n") ;
  441. }
  442.  
  443. /*******************************  初期設定  **********************************/
  444. void init()
  445. {
  446.     char    bankname[8] ;
  447.     char    name[9] ;
  448.     int        ret ;
  449.  
  450.     printf("\nキーボードを操作すると、PMB ファイルの音色で演奏できます♪\n") ;
  451.  
  452.     printf("\n8重和音まで対応しています♪\n") ;
  453.     printf("カーソルキーの上下で音色を変更できます♪") ;
  454.     printf(" ( SHIFT+ で上段のみ, CTRL+ で下段のみ )\n") ;
  455.     printf("カーソルキーの右左で定位を変更できます♪") ;
  456.     printf(" ( SHIFT+ で上段のみ, CTRL+ で下段のみ )\n") ;
  457.     printf("PFキーで、音程を変更できます♪ ( PF1 ~ PF9 : PF5 が標準 )\n") ;
  458.     printf("取消キーで、全ての発音を停止できます。\n") ;
  459.     printf("終了は、") ;
  460.     printf("\x1b[36mBREAKキー\x1b[m") ;
  461.     printf(" です!\n") ;
  462.  
  463.     SND_init( Swork ) ;                                /*  サウンド初期化            */
  464.  
  465.     ret = SND_pcm_bank_load( Pmbfile,bankname ) ;    /*  PCMバンクロード            */
  466.     switch ( ret ) {
  467.         case 0 :
  468.             printf("\nPCM 音源の音色は、") ;
  469.             printf("\x1b[36m%s \x1b[m",Pmbfile) ;
  470.             printf("のデータを使用します。\n") ;
  471.             pmb_load() ;
  472.             Pmbflg = TRUE ;
  473.             break ;
  474.         case 1 :
  475.             printf("\nPMBファイル") ;
  476.             printf(" < \x1b[33m%s\x1b[m > ",Pmbfile) ;
  477.             printf("が見つかりません!\n") ;
  478.             printf("\x1b[33m") ;
  479.             printf("☆☆☆  強制終了します!  ☆☆☆") ;
  480.             printf("\x1b[m\n") ;
  481.             break ;
  482.         case 2 :
  483.             printf("\nPMBファイル") ;
  484.             printf(" < \x1b[33m%s\x1b[m > ",Pmbfile) ;
  485.             printf("の読み込みに失敗しました!\n") ;
  486.             printf("\x1b[33m") ;
  487.             printf("☆☆☆  強制終了します!  ☆☆☆") ;
  488.             printf("\x1b[m\n") ;
  489.             break ;
  490.         default :
  491.             printf("\n\x1b[31m") ;
  492.             printf("ERROR \x1b[m: SND_pcm_bank_load = %d\n",ret) ;
  493.     }
  494.     printf("\n") ;
  495.  
  496. /*
  497. **    PCM 各チャンネルの音色を初期設定する
  498. */
  499.     SND_inst_change( 64,0 ) ;
  500.     SND_inst_change( 65,0 ) ;
  501.     SND_inst_change( 66,0 ) ;
  502.     SND_inst_change( 67,0 ) ;
  503.     SND_inst_change( 68,0 ) ;
  504.     SND_inst_change( 69,0 ) ;
  505.     SND_inst_change( 70,0 ) ;
  506.     SND_inst_change( 71,0 ) ;
  507.  
  508.     SND_elevol_mute( 0x0001 ) ;                        /*  PCM 音源のみミュート解除*/
  509.     SND_elevol_all_mute( -1 ) ;                        /*  全ミュートの解除        */
  510.  
  511.     KYB_clic( 1 ) ;                                    /*  キークリック音なし        */
  512.  
  513.     if ( Pmbflg ) {
  514.         printf("キーボード上段の音色は、") ;
  515.         strncpy( name,&Pmbdata[8],8 ) ;
  516.         name[8] = '\0' ;
  517.         printf(" < %s > ",name) ;
  518.         printf("(INST:000) です♪\n") ;
  519.         printf("キーボード下段の音色は、") ;
  520.         strncpy( name,&Pmbdata[8],8 ) ;
  521.         name[8] = '\0' ;
  522.         printf(" < %s > ",name) ;
  523.         printf("(INST:000) です♪\n") ;
  524.  
  525.         printf("\n'\x1b[36mド\x1b[m' (C=60) の位置は、") ;
  526.         printf("\x1b[36mW\x1b[m と \x1b[36m>\x1b[m です♪\n") ;
  527.         printf("\n") ;
  528.     }
  529.  
  530. }
  531.  
  532. /*************************  キーボード操作による音制御  *************************/
  533. void key_play( char *matrix, char keyadrs )
  534. /*    *matrix : キーマトリクス情報( 16 バイト )                                        */
  535. /*    keyadrs : キーアドレス                                                        */
  536. {
  537.     /*  PCM のチャンネルは 64 ~ 71    */
  538.     static int    chan1=64 ;                            /*  キーボード上段のチャンネル    */
  539.     static int    chan2=68 ;                            /*  キーボード下段のチャンネル    */
  540.     static int    channel[128] ;                        /*  各キーでのON時FMチャンネル    */
  541.     static char    keymake[128] = {                    /*  キー MAKE 状態か?    */
  542.                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  543.                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  544.                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  545.                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  546.                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  547.                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  548.                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  549.                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  550.                                 } ;
  551.     int        ret ;
  552.  
  553.     if ( chan1 > 67 ) chan1 = 64 ;
  554.     if ( chan2 > 71 ) chan2 = 68 ;
  555.  
  556.     if ( Key_inf[keyadrs] == KYB_UPPER ) {            /*  キーボード 上段        */
  557.         if ( KEY_test( matrix,keyadrs ) ) {            /*  キー MAKE                */
  558.             if ( !keymake[keyadrs] ) {                /*  キー BREAK -> MAKE    */
  559.                 SND_key_off( chan1 ) ;
  560.                 ret = SND_key_on( chan1,Key_note[keyadrs]+ValNote1,127 ) ;
  561.                 if ( ret ) {
  562.                     if ( Key_note[keyadrs]+ValNote1 > 60 ) {
  563.                         printf("音が高すぎて発音できません。(NOTE=%d)\n",
  564.                             Key_note[keyadrs]+ValNote1) ;
  565.                     } else {
  566.                         printf("音が低すぎて発音できません。(NOTE=%d)\n",
  567.                             Key_note[keyadrs]+ValNote1) ;
  568.                     }
  569.                 } else {
  570.                     channel[keyadrs] = chan1 ;
  571.                     chan1 ++ ;
  572.                     keymake[keyadrs] = TRUE ;
  573.                 }
  574.             }
  575.         } else if ( keymake[keyadrs] ) {        /*  キー BREAK        */
  576.             SND_key_off( channel[keyadrs] ) ;
  577.             keymake[keyadrs] = FALSE ;
  578.         }
  579.     } else if ( Key_inf[keyadrs] == KYB_LOWER ) {    /*  キーボード 下段        */
  580.         if ( KEY_test( matrix,keyadrs ) ) {            /*  キー MAKE                */
  581.             if ( !keymake[keyadrs] ) {                /*  キー BREAK -> MAKE    */
  582.                 SND_key_off( chan2 ) ;
  583.                 ret = SND_key_on( chan2,Key_note[keyadrs]+ValNote2,127 ) ;
  584.                 if ( ret ) {
  585.                     if ( Key_note[keyadrs]+ValNote2 > 60 ) {
  586.                         printf("音が高すぎて発音できません。(NOTE=%d)\n",
  587.                             Key_note[keyadrs]+ValNote2) ;
  588.                     } else {
  589.                         printf("音が低すぎて発音できません。(NOTE=%d)\n",
  590.                             Key_note[keyadrs]+ValNote2) ;
  591.                     }
  592.                 } else {
  593.                     channel[keyadrs] = chan2 ;
  594.                     chan2 ++ ;
  595.                     keymake[keyadrs] = TRUE ;
  596.                 }
  597.             }
  598.         } else if ( keymake[keyadrs] ) {        /*  キー BREAK        */
  599.             SND_key_off( channel[keyadrs] ) ;
  600.             keymake[keyadrs] = FALSE ;
  601.         }
  602.     }
  603.  
  604. }
  605.  
  606. /*******************************  音程の変更  ********************************/
  607. void note_change( char *matrix )
  608. /*    *matrix : キーマトリクス情報( 16 バイト )                                        */
  609. {
  610.     if ( KEY_test( matrix,KEY_PF1 ) ) {
  611.         if ( KEY_test( matrix,KEY_SHIFT ) ||
  612.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  613.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  614.             ValNote1 = -48 ;
  615.             printf("キーボード上段の音程を標準より4つ下げました。(C=12)\n") ;
  616.         }
  617.  
  618.         if ( KEY_test( matrix,KEY_CTRL ) ||
  619.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  620.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  621.             ValNote2 = -48 ;
  622.             printf("キーボード下段の音程を標準より4つ下げました。(C=12)\n") ;
  623.         }
  624.  
  625.         printf("\n") ;
  626.  
  627.     } else if ( KEY_test( matrix,KEY_PF2 ) ) {
  628.         if ( KEY_test( matrix,KEY_SHIFT ) ||
  629.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  630.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  631.             ValNote1 = -36 ;
  632.             printf("キーボード上段の音程を標準より3つ下げました。(C=24)\n") ;
  633.         }
  634.  
  635.         if ( KEY_test( matrix,KEY_CTRL ) ||
  636.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  637.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  638.             ValNote2 = -36 ;
  639.             printf("キーボード下段の音程を標準より3つ下げました。(C=24)\n") ;
  640.         }
  641.  
  642.         printf("\n") ;
  643.  
  644.     } else if ( KEY_test( matrix,KEY_PF3 ) ) {
  645.         if ( KEY_test( matrix,KEY_SHIFT ) ||
  646.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  647.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  648.             ValNote1 = -24 ;
  649.             printf("キーボード上段の音程を標準より2つ下げました。(C=36)\n") ;
  650.         }
  651.  
  652.         if ( KEY_test( matrix,KEY_CTRL ) ||
  653.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  654.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  655.             ValNote2 = -24 ;
  656.             printf("キーボード下段の音程を標準より2つ下げました。(C=36)\n") ;
  657.         }
  658.  
  659.         printf("\n") ;
  660.  
  661.     } else if ( KEY_test( matrix,KEY_PF4 ) ) {
  662.         if ( KEY_test( matrix,KEY_SHIFT ) ||
  663.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  664.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  665.             ValNote1 = -12 ;
  666.             printf("キーボード上段の音程を標準より1つ下げました。(C=48)\n") ;
  667.         }
  668.  
  669.         if ( KEY_test( matrix,KEY_CTRL ) ||
  670.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  671.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  672.             ValNote2 = -12 ;
  673.             printf("キーボード下段の音程を標準より1つ下げました。(C=48)\n") ;
  674.         }
  675.  
  676.         printf("\n") ;
  677.  
  678.     } else if ( KEY_test( matrix,KEY_PF5 ) ) {
  679.         if ( KEY_test( matrix,KEY_SHIFT ) ||
  680.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  681.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  682.             ValNote1 = 0 ;
  683.             printf("\x1b[36m") ; 
  684.             printf("キーボード上段の音程を標準にしました♪\x1b[m(C=60)\n") ;
  685.         }
  686.  
  687.         if ( KEY_test( matrix,KEY_CTRL ) ||
  688.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  689.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  690.             ValNote2 = 0 ;
  691.             printf("\x1b[36m") ; 
  692.             printf("キーボード下段の音程を標準にしました♪\x1b[m(C=60)\n") ;
  693.         }
  694.  
  695.         printf("\n") ;
  696.  
  697.     } else if ( KEY_test( matrix,KEY_PF6 ) ) {
  698.         if ( KEY_test( matrix,KEY_SHIFT ) ||
  699.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  700.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  701.             ValNote1 = 12 ;
  702.             printf("キーボード上段の音程を標準より1つ上げました。(C=72)\n") ;
  703.         }
  704.  
  705.         if ( KEY_test( matrix,KEY_CTRL ) ||
  706.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  707.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  708.             ValNote2 = 12 ;
  709.             printf("キーボード下段の音程を標準より1つ上げました。(C=72)\n") ;
  710.         }
  711.  
  712.         printf("\n") ;
  713.  
  714.     } else if ( KEY_test( matrix,KEY_PF7 ) ) {
  715.         if ( KEY_test( matrix,KEY_SHIFT ) ||
  716.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  717.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  718.             ValNote1 = 24 ;
  719.             printf("キーボード上段の音程を標準より2つ上げました。(C=84)\n") ;
  720.         }
  721.  
  722.         if ( KEY_test( matrix,KEY_CTRL ) ||
  723.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  724.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  725.             ValNote2 = 24 ;
  726.             printf("キーボード下段の音程を標準より2つ上げました。(C=84)\n") ;
  727.         }
  728.  
  729.         printf("\n") ;
  730.  
  731.     } else if ( KEY_test( matrix,KEY_PF8 ) ) {
  732.         if ( KEY_test( matrix,KEY_SHIFT ) ||
  733.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  734.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  735.             ValNote1 = 36 ;
  736.             printf("キーボード上段の音程を標準より3つ上げました。(C=96)\n") ;
  737.         }
  738.  
  739.         if ( KEY_test( matrix,KEY_CTRL ) ||
  740.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  741.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  742.             ValNote2 = 36 ;
  743.             printf("キーボード下段の音程を標準より3つ上げました。(C=96)\n") ;
  744.         }
  745.  
  746.         printf("\n") ;
  747.  
  748.     } else if ( KEY_test( matrix,KEY_PF9 ) ) {
  749.         if ( KEY_test( matrix,KEY_SHIFT ) ||
  750.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  751.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  752.             ValNote1 = 48 ;
  753.             printf("キーボード上段の音程を標準より4つ上げました。(C=108)\n") ;
  754.         }
  755.  
  756.         if ( KEY_test( matrix,KEY_CTRL ) ||
  757.             ( !KEY_test( matrix,KEY_SHIFT ) &&
  758.                  !KEY_test( matrix,KEY_CTRL ) ) ) {
  759.             ValNote2 = 48 ;
  760.             printf("キーボード下段の音程を標準より4つ上げました。(C=108)\n") ;
  761.         }
  762.  
  763.         printf("\n") ;
  764.  
  765.     }
  766.  
  767. }
  768.  
  769. /********************************  プレイ開始  *********************************/
  770. void play_start()
  771. {
  772.     char    matrix[16] ;                            /*  キーマトリクス取得用        */
  773.     int        c ;
  774.  
  775. /*
  776. **    キー操作開始
  777. */
  778.     do {
  779.  
  780.          KYB_clrbuf() ;                                /*  キーバッファ・クリア            */
  781.         KYB_matrix( matrix ) ;                        /*  キーマトリクス取得            */
  782.  
  783. /*
  784. **    音色の変更( 1つ上の音色 )
  785. */
  786.         if ( KEY_test( matrix,KEY_UP ) ) {
  787.         
  788.             if ( KEY_test( matrix,KEY_SHIFT ) ) {            /*  キーボード上段    */
  789.                 inst_change_up( KYB_UPPER,KYB_DUMMY ) ;
  790.             }
  791.             if ( KEY_test( matrix,KEY_CTRL ) ) {            /*  キーボード下段    */
  792.                 inst_change_up( KYB_DUMMY,KYB_LOWER ) ;
  793.             }
  794.             if ( !KEY_test( matrix,KEY_SHIFT ) &&
  795.                     !KEY_test( matrix,KEY_CTRL ) ) {        /*  上下段とも    */
  796.                 inst_change_up( KYB_UPPER,KYB_LOWER ) ;
  797.             }
  798.  
  799. /*
  800. **    音色の変更( 1つ下の音色 )
  801. */
  802.         } else if ( KEY_test( matrix,KEY_DOWN ) ) {
  803.  
  804.             if ( KEY_test( matrix,KEY_SHIFT ) ) {            /*  キーボード上段    */
  805.                 inst_change_down( KYB_UPPER,KYB_DUMMY ) ;
  806.             }
  807.             if ( KEY_test( matrix,KEY_CTRL ) ) {            /*  キーボード下段    */
  808.                 inst_change_down( KYB_DUMMY,KYB_LOWER ) ;
  809.             }
  810.             if ( !KEY_test( matrix,KEY_SHIFT ) &&
  811.                     !KEY_test( matrix,KEY_CTRL ) ) {        /*  上下段とも    */
  812.                 inst_change_down( KYB_UPPER,KYB_LOWER ) ;
  813.             }
  814.  
  815. /*
  816. **    定位の変更( 1つ右の定位 )
  817. */
  818.         } else if ( KEY_test( matrix,KEY_RIGHT ) ) {
  819.  
  820.             if ( KEY_test( matrix,KEY_SHIFT ) ) {            /*  キーボード上段    */
  821.                 pan_change_right( KYB_UPPER,KYB_DUMMY ) ;
  822.             }
  823.             if ( KEY_test( matrix,KEY_CTRL ) ) {            /*  キーボード下段    */
  824.                 pan_change_right( KYB_DUMMY,KYB_LOWER ) ;
  825.             }
  826.             if ( !KEY_test( matrix,KEY_SHIFT ) &&
  827.                     !KEY_test( matrix,KEY_CTRL ) ) {        /*  上下段とも    */
  828.                 pan_change_right( KYB_UPPER,KYB_LOWER ) ;
  829.             }
  830.  
  831. /*
  832. **    定位の変更( 1つ左の定位 )
  833. */
  834.         } else if ( KEY_test( matrix,KEY_LEFT ) ) {
  835.  
  836.             if ( KEY_test( matrix,KEY_SHIFT ) ) {            /*  キーボード上段    */
  837.                 pan_change_left( KYB_UPPER,KYB_DUMMY ) ;
  838.             }
  839.             if ( KEY_test( matrix,KEY_CTRL ) ) {            /*  キーボード下段    */
  840.                 pan_change_left( KYB_DUMMY,KYB_LOWER ) ;
  841.             }
  842.             if ( !KEY_test( matrix,KEY_SHIFT ) &&
  843.                     !KEY_test( matrix,KEY_CTRL ) ) {        /*  上下段とも    */
  844.                 pan_change_left( KYB_UPPER,KYB_LOWER ) ;
  845.             }
  846.  
  847. /*
  848. **    発音の強制停止
  849. */
  850.         } else if ( KEY_test( matrix,KEY_UNDO ) ) {
  851.             SND_pcm_abort() ;
  852.  
  853. /*
  854. **    キーボード操作で音を出す
  855. */
  856.         } else {
  857.             note_change( matrix ) ;                        /*  音程の変更チェック    */
  858.  
  859.             for ( c=0; c<NKYBINF; c++ ) {
  860.                 key_play( matrix,c ) ;
  861.             }
  862.  
  863.         }
  864.  
  865.     } while ( !KEY_test( matrix,KEY_BREAK ) ) ;    /*  BREAKキーが押されるまで    */
  866.  
  867. }
  868.  
  869. /*********************************  メイン  **********************************/
  870. void main( int ac, char *av[] )
  871. {
  872.     int        endp ;
  873.  
  874.     printf("PMB.EXP  v0.50  (c) パオパオ 1990.            ") ;
  875.     printf("<< Copyright (C) Y.Hirata 1990. >>\n") ;
  876.  
  877.     if ( ac > 1 ) {                                    /*  引数あり            */
  878.         strcpy( Pmbfile,av[1] ) ;
  879.         endp = strlen( Pmbfile ) ;
  880.         if ( strchr( Pmbfile,'.' ) == NULL ) {        /*  ファイル拡張子なし        */
  881.             strcat( Pmbfile,".PMB" ) ;
  882.         } else {
  883.             if ( strcmp( Pmbfile+endp-4,".PMB" ) &&
  884.                     strcmp( Pmbfile+endp-4,".pmb" ) ) {
  885.                 printf("\x1b[31mERROR\x1b[m : FILE NAME ( %s ) - ",Pmbfile) ;
  886.                 printf(".PMB ファイル しか指定できません!\n") ;
  887.                 exit( 1 ) ;
  888.             }
  889.         }
  890.     } else {                                        /*  引数なし            */
  891.         strcpy( Pmbfile,PMB_FILE ) ;
  892.     }
  893.  
  894.     INT23_init() ;                                    /*  ^C マスク設定            */
  895.  
  896.     init() ;                                        /*  各種初期設定        */
  897.  
  898.     if ( Pmbflg )
  899.         play_start() ;                                /*  プレイ開始            */
  900.  
  901. close:
  902.  
  903.     if ( Pmbflg ) {
  904.         free( Pmbdata ) ;
  905.     }
  906.  
  907.     KYB_clic( 0 ) ;                                    /*  キークリック音あり        */
  908.      KYB_clrbuf() ;                                    /*  キーバッファ・クリア            */
  909.  
  910.     SND_end() ;                                        /*  サウンド終了            */
  911.  
  912.     INT23_end() ;                                    /*  ^C マスク解除            */
  913.  
  914.     printf("\nプログラムを終了します。\n") ;
  915.  
  916. }
  917.  
  918.