📄 blib_sound.c
字号:
/** SmallBASIC RTL - SOUND** 2000-05-27, Nicholas Christopoulos** This program is distributed under the terms of the GPL v2.0 or later* Download the GNU Public License (GPL) from www.gnu.org*/#include "sys.h"#include "str.h"#include "kw.h"#include "panic.h"#include "var.h"#include "blib.h"#include "pproc.h"static int tones[] ={//c c# d d# e f f# g g# a a# b65, 69, 73, 78, 82, 87, 93, 98, 104, 110, 116, 123,131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247,262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494,523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988,1046, 1109, 1175, 1245, 1318, 1397, 1480, 1568, 1661, 1760, 1865, 1976,2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951,4186, 4435, 4699, 4978, 5274, 5587, 5919, 6271, 6645, 7040, 7459, 7902,0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, };static int O=2, bg=0, vol = 75;static int period, duration, pitch = 440;static double L=4.0, T=240.0, M=1.0, TM=1.0;//// BEEP//void cmd_beep(){ dev_beep();}//// SOUND frq, dur [, vol]//void cmd_sound(){ int frq = 440, ms = 250, vol = 100; frq = par_getint(); if ( !prog_error ) { par_getcomma(); if ( !prog_error ) { ms = par_getint(); if ( !prog_error ) { if ( code_peek() == kwTYPE_SEP ) { par_getcomma(); if ( !prog_error ) vol = par_getint(); } if ( !prog_error ) dev_sound(frq, ms, vol, 0); } } }}//void cmd_play_reset(){ O=2; bg=0; vol = 75; period = 0; duration = 0; pitch = 440; L=4.0; T=240.0; M=1.0; TM=1.0;}//// PLAY str-cmds//#define CPLERR(c,a) { if ( (c) ) { rt_raise((a)); tmp_free(str); return; } }void cmd_play(){ char *p; var_t var; int oct, n = 0; int calc_time_f = 1; char *str, *s; double TmpL; par_getstr(&var); if ( prog_error ) return; str = (char *) tmp_alloc(var.size+1); // copy without spaces p = var.ptr; s = str; while ( *p ) { if ( *p > 32 ) *s ++ = to_upper(*p); p ++; } *s = '\0'; v_free(&var); // run p = str; while ( *p ) { // if ( dev_events(0) < 0 ) break; // if ( calc_time_f ) { period = (4.0 / L) * (60000 / T) * TM; duration = M * period; calc_time_f = 0; } switch ( *p ) { /* * Volume */ case 'V': n = 0; while ( is_digit(*(p+1)) ) { p ++; n = (n*10)+(*p-'0'); } CPLERR((n < 0 || n > 100), "PLAY: V0-100"); vol = n; break; /* * Octaves */ case '<': if ( O > 0 ) O --; break; case '>': if ( O < 6 ) O ++; break; case 'O': O = -1; if ( is_digit(*(p+1)) ) { p ++; O = *p - '0'; } CPLERR((O<0||O>6),"PLAY: O0-6"); break; /* * Time */ case 'L': n = 0; while ( is_digit(*(p+1)) ) { p ++; n = (n * 10) + (*p - '0'); } CPLERR((n < 1 || n > 64),"PLAY: L1-64"); L = n; calc_time_f = 1; break; case 'T': n = 0; while ( is_digit(*(p+1)) ) { p ++; n = (n*10)+(*p-'0'); } CPLERR((n < 45 || n > 255), "PLAY: T32-255"); T = n; calc_time_f = 1; break; case 'M': p ++; switch ( *p ) { case 'S': M = 0.5; break; case 'N': M = 3.0/4.0; break; case 'L': M = 1.0; break; case 'F': bg = 0; break; case 'B': bg = 1; break; default: rt_raise("PLAY: M%c UNSUPPORTED", *p); v_free(&var); } calc_time_f = 1; break; /* * Pause */ case 'P': n = 0; while ( is_digit(*(p+1)) ) { p ++; n = (n*10)+(*p-'0'); } /// if ( *(p+1) == '.' ) { p ++; TM = 1.5; } else TM = 1.0; CPLERR((n<1||n>64),"PLAY: P1-64"); period = (4.0 / n) * (60000 / T) * TM; dev_sound(0, period, vol, bg); calc_time_f = 1; break; /* * Play N */ case 'N': n = 0; while ( is_digit(*(p+1)) ) { p ++; n = (n*10)+(*p-'0'); } CPLERR((n < 0 || n > 84), "PLAY: N0-84"); if ( n ) { oct = n / 12;// pitch = tones[n - oct * 12] * (1 << oct); pitch = tones[n]; } if ( n == 0 ) dev_sound(0, period, vol, bg); else { dev_sound(pitch, duration, vol, bg); if ( duration < period ) dev_sound(0, period-duration, vol, bg); } calc_time_f = 1; break; /* * Play note */ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': switch ( *p ) { case 'A': n = 13; break; case 'B': n = 15; break; case 'C': n = 4; break; case 'D': n = 6; break; case 'E': n = 8; break; case 'F': n = 9; break; case 'G': n = 11; break; } /// if ( *(p+1) == '-' || *(p+1) == '+' || *(p+1) == '#' ) { p ++; if ( *p == '-' ) n --; else n ++; } /// if ( is_digit(*(p+1)) ) { TmpL = 0; while ( is_digit(*(p+1)) ) { p ++; TmpL = (TmpL * 10) + (*p - '0'); } calc_time_f = 1; } else TmpL = L; /// if ( *(p+1) == '.' ) { p ++; TM = 1.5; } else TM = 1.0; period = (4.0 / TmpL) * (60000 / T) * TM; duration = M * period; ///// pitch = tones[n] * (1 << O); pitch = tones[(n-4) + O*12]; dev_sound(pitch, duration, vol, bg); if ( duration < period ) dev_sound(0, period-duration, vol, bg); break; default: rt_raise("PLAY: '%c' UNSUPPORTED", *p); tmp_free(str); return; } // next if ( *p ) p ++; } tmp_free(str);}#undef CPLERR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -