Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -2719,5 +2719,53 @@ * The stack contains one or more items, of which the first (bottom) one is a string: Concatenates all of them together, which can be strings, numbers (treated as unsigned), or classes. All formatting codes of strings will be stripped, so that the result will be a unformatted string. + +=== MML sound effects === + +The MML sound effects are similar to ZZT and MegaZeux. It is a string +consisting of the commands listed below (case-insensitive): + +A B C D E F G + Play a note of the current length and octave; notes outside of the range + of a 88-key piano are not valid, but the quarter tones are possible. It + can be followed by zero or more of the following signs: + ! flat + , half flat + ' half sharp + # sharp + +X + Play a silenced rest of the current note length. + +W H Q I S T Z + Set the note length to one of the predefined note lengths, where W means + a whole note, the other letters are successively half until Z which means + a sixty-fourth note, which is the shortest possible note. + +. + Multiply note length by 3/2. + +0 1 2 3 4 5 6 7 + Set the octave to a specified number. Note that notes lower than A are + not valid for octave zero. + +- + Low octave. + ++ + High octave. + +L + Set note length to a following number of sixty-fourth notes. + +N + Play a note with the following note number, and the current length. The + note number 0 is the lowest piano note, and then each next key on the + piano is 2 more than the previous one (odd numbers are used for quarter + tones that are not on a standard piano). Numbers 190 and higher are used + for overtone notes; subtract 188 for the overtone number (although note + that overtone numbers 0 and 1 are not usable). + +(Note that this is not the same as standard MML.) Index: config.doc ================================================================== --- config.doc +++ config.doc @@ -28,14 +28,16 @@ .audio.mmlTempo Define the number of quarter notes per minute. The default is 120. .audio.mmlTuning The MML tuning of the A4 note, in Hz. The default is 440 Hz, but some - people do not like that tuning, so you can change it. + people do not like that tuning, so you can change it. This setting only + affects 24-TET sounds, and not overtone-based sounds. .audio.mmlVolume - MML volume, from 0 to 1; fractions are allowed. The default value is 1. + MML volume, from 0 to 1; fractions are allowed. The default value is + approximately one third. .audio.rate Sample rate to use for audio, in hertz. In order for audio to work at all, this value must be set. Index: puzzleset.doc ================================================================== --- puzzleset.doc +++ puzzleset.doc @@ -41,11 +41,12 @@ The DEP lumps are dependent pictures; each one references one or more IMG lumps, and specifies how to modify them to produce the new picture (e.g. by rotating, mirroring, changing colours, etc). The WAV lumps are sound effects. Each is a RIFF WAVE file; it must be of -a type which can be loaded by SDL. (This is currently not used.) +a type which can be loaded by SDL. Lumps can also be WZV if it is a +compressed audio file, but compressed audio is not currently implemented. The PICEDIT.CFG lump stores the configuration for the picture editor. It can safely be deleted. Index: sound.c ================================================================== --- sound.c +++ sound.c @@ -18,11 +18,11 @@ Uint8*data; Uint32 len; // length in bytes } WaveSound; static Uint8 sound_on; -static Sint16 mmlvolume=9001; +static Sint16 mmlvolume=10000; static SDL_AudioSpec spec; static WaveSound*standardsounds; static Uint16 nstandardsounds; static WaveSound*usersounds; static Uint16 nusersounds; @@ -259,11 +259,12 @@ mmltuning=malloc(256*sizeof(Uint32)); if(!mmltuning) fatal("Allocation failed\n"); optionquery[2]=Q_mmlTuning; if(v=xrm_get_resource(resourcedb,optionquery,optionquery,3)) f=strtod(v,0); else f=440.0; f*=0x80000000U/(double)spec.freq; - for(i=0;i<256;i++) mmltuning[i]=f*pow(2.0,(i-96)/24.0); + for(i=0;i<190;i++) mmltuning[i]=f*pow(2.0,(i-96)/24.0); + for(i=0;i<64;i++) mmltuning[i+190]=(((long long)(i+2))<<37)/spec.freq; optionquery[2]=Q_mmlTempo; if(v=xrm_get_resource(resourcedb,optionquery,optionquery,3)) i=strtol(v,0,10); else i=120; // Convert quarter notes per minute to samples per sixty-fourth note mmltempo=(spec.freq*60)/(i*16); } @@ -321,15 +322,19 @@ mmlpos=1; mmltime=mmlsound[1]*mmltempo; } void set_sound_effect(Value v1,Value v2) { - static const unsigned char*const builtin[4]={ + static const unsigned char*const builtin[8]={ "s.g", "scdefgab+c-bagfedc-c", - "i1c+c+c+c+c+c+c", + "i1c+c+c+c+c+c+cx", "-cc'c#d,dd'd#ee'ff'f#", + "sn190n191n192n193n194n195n196n197n198n199n200n201n202n203n204n205n206n207n208n209n210", + "z+c-gec-gec", + "t+c-gec", + "tc-c+d-d+e-e+f-f+g-g", }; const unsigned char*s; if(!sound_on) return; if(!v2.t && !v2.u && (mmlpos || wavesound)) return; SDL_LockAudio(); @@ -353,11 +358,11 @@ if(s=value_string_ptr(v1)) set_mml(s); break; case TY_FOR: // (only used for the sound test) if(!mmlvolume) break; - set_mml(builtin[v1.u&3]); + set_mml(builtin[v1.u&7]); break; } SDL_UnlockAudio(); } @@ -387,11 +392,11 @@ if(mmltuning) printf("mmltempo=%d; mmlvolume=%d; mmltuning[96]=%d\n",(int)mmltempo,(int)mmlvolume,(int)mmltuning[96]); for(i=0;iw-16)/240?:1; scrmax=(nitems+columns-1)/columns; set_cursor(XC_arrow); redraw: SDL_FillRect(screen,0,0x02);