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

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