hschumann2/TempleOS-Source-Code
0838
1 2U0 PsmNoteDel(PsmNote *tmpn)3{4 Free(tmpn->word);5 Free(tmpn);6}7 8PsmNote *PsmNoteCopy(PsmNote *tmpn)9{10 PsmNote *tmpn1=MAllocIdent(tmpn);11 if (tmpn->word)12 tmpn1->word=StrNew(tmpn->word);13 else14 tmpn1->word=NULL;15 return tmpn1;16}17 18U0 PsmSongDel(PsmNote *head)19{20 PsmNote *tmpn,*tmpn1;21 tmpn=head->next;22 while (tmpn!=head) {23 tmpn1=tmpn->next;24 PsmNoteDel(tmpn);25 tmpn=tmpn1;26 }27 QueInit(head);28}29 30U0 PsmCutToClip()31{32 PsmNote *tmpn,*tmpn1;33 PsmSongDel(&psm.clip);34 tmpn=psm.head.next;35 while (tmpn!=&psm.head) {36 tmpn1=tmpn->next;37 if (tmpn->flags&PSMF_SEL) {38 if (psm.cur_note==tmpn)39 psm.cur_note=tmpn->next;40 QueRem(tmpn);41 tmpn->flags&=~PSMF_SEL;42 QueIns(tmpn,psm.clip.last);43 }44 tmpn=tmpn1;45 }46}47 48U0 PsmPasteClip()49{50 PsmNote *tmpn,*tmpn1;51 tmpn=psm.clip.next;52 while (tmpn!=&psm.clip) {53 tmpn1=PsmNoteCopy(tmpn);54 QueIns(tmpn1,psm.cur_note->last);55 tmpn=tmpn->next;56 }57}58 59U0 PsmCopyToClip()60{61 PsmNote *tmpn,*tmpn1;62 PsmSongDel(&psm.clip);63 tmpn=psm.head.next;64 while (tmpn!=&psm.head) {65 if (tmpn->flags&PSMF_SEL) {66 tmpn->flags&=~PSMF_SEL;67 tmpn1=PsmNoteCopy(tmpn);68 QueIns(tmpn1,psm.clip.last);69 }70 tmpn=tmpn->next;71 }72}73 74PsmNote *PsmFindNote(I64 x,I64)75{76 PsmNote *tmpn=psm.head.next;77 PsmRecalcNoteXY;78 x+=PSM_NOTE_SPACING/2;79 while (x>tmpn->next->x && tmpn!=&psm.head)80 tmpn=tmpn->next;81 return tmpn;82}83 84U8 *PsmMusicSetOctave(U8 *st,I64 *psm_octave)85{86 while ('0'<=*st<='9')87 *psm_octave=*st++ -'0';88 return st;89}90 91U8 *PsmMusicSetNoteLen(U8 *st,F64 *psm_duration)92{93 Bool cont=TRUE;94 do {95 switch (*st++) {96 case 'w': *psm_duration=4.0; break;97 case 'h': *psm_duration=2.0; break;98 case 'q': *psm_duration=1.0; break;99 case 'e': *psm_duration=0.5; break;100 case 's': *psm_duration=0.25; break;101 case 't': *psm_duration=2.0* *psm_duration/3.0; break;102 case '.': *psm_duration=1.5* *psm_duration; break;103 default:104 st--;105 cont=FALSE;106 }107 } while (cont);108 return st;109}110 111U0 PsmLoadSongStr(U8 *st,I64 *psm_octave,F64 *psm_duration)112{113 PsmNote *tmpn,*tmpn1;114 I64 note,i=0;115 while (*st) {116 tmpn=CAlloc(sizeof(PsmNote));117 while (*st && !('A'<=*st<='G') && *st!='R') {118 if (*st=='M') {119 tmpn1=CAlloc(sizeof(PsmNote));120 tmpn1->type=PSMT_METER;121 st++;122 if ('1'<=*st<='9')123 tmpn1->meter_top=*st++-'0';124 else125 tmpn1->meter_top=4;126 if (*st=='/')127 st++;128 if ('1'<=*st<='9')129 tmpn1->meter_bottom=*st++-'0';130 else131 tmpn1->meter_bottom=4;132 PsmSetWidth(tmpn1);133 QueIns(tmpn1,psm.head.last);134 }135 while (*st=='(') {136 Bts(&tmpn->flags,PSMf_TIE);137 st++;138 }139 st=PsmMusicSetOctave(st,psm_octave);140 st=PsmMusicSetNoteLen(st,psm_duration);141 }142 if (!*st) {143 PsmNoteDel(tmpn);144 break;145 }146 note=*st++-'A';147 if (note<7) {148 note=music.note_map[note];149 if (*st=='b') {150 Bts(&tmpn->flags,PSMf_FLAT);151 note--;152 st++;153 if (note<0) //Ab154 note=11;155 else if (note==2) //Cb156 *psm_octave-=1;157 } else if (*st=='#') {158 Bts(&tmpn->flags,PSMf_SHARP);159 note++;160 st++;161 if (note>11) //G#162 note=0;163 else if (note==3) //B#164 *psm_octave+=1;165 }166 tmpn->ona=Note2Ona(note,*psm_octave);167 } else168 tmpn->ona=ONA_REST;169 if (*psm_duration<=2*.25/3)170 i=0;171 else if (*psm_duration<=.25)172 i=1;173 else if (*psm_duration<=2*.5/3)174 i=2;175 else if (*psm_duration<=.5)176 i=3;177 else if (*psm_duration<=2.0/3)178 i=4;179 else if (*psm_duration<=.5*1.5)180 i=5;181 else if (*psm_duration<=1.0)182 i=6;183 else if (*psm_duration<=1.5)184 i=7;185 else if (*psm_duration<=2.0)186 i=8;187 else if (*psm_duration<=3.0)188 i=9;189 else if (*psm_duration<=4.0)190 i=10;191 else192 i=11;193 tmpn->duration=i;194 tmpn->type=PSMT_NOTE;195 PsmSetWidth(tmpn);196 QueIns(tmpn,psm.cur_note->last);197 }198}199 200U0 PsmLoadSong(U8 *filename,I64 *psm_octave,F64 *psm_duration)201{202 U8 *st;203 PsmNote *tmpn;204 CCmpCtrl *cc=CmpCtrlNew(MStrPrint("#include \"%s\"",filename));205 if (FileOcc("incomplete",filename,""))206 psm.incomplete_entry->checked=TRUE;207 else208 psm.incomplete_entry->checked=FALSE;209 while (Lex(cc)) {210 if (cc->token==TK_IDENT)211 if (!StrCmp(cc->cur_str,"Play")) {212 if (Lex(cc)=='(')213 if (Lex(cc)==TK_STR) {214 tmpn=psm.head.last;215 st=LexExtStr(cc);216 PsmLoadSongStr(st,psm_octave,psm_duration);217 if (cc->token==',') {218 if (Lex(cc)==TK_STR) {219 st=LexExtStr(cc);220 do {221 do tmpn=tmpn->next;222 while (tmpn!=&psm.head && tmpn->type==PSMT_METER);223 if (tmpn!=&psm.head)224 tmpn->word=StrNew(st);225 st+=StrLen(st)+1;226 } while (*st);227 }228 }229 }230 } else if (!StrCmp(cc->cur_str,"music") &&231 Lex(cc)=='.' && Lex(cc)==TK_IDENT) {232 if (!StrCmp(cc->cur_str,"tempo")) {233 if (Lex(cc)=='=' && Lex(cc)==TK_F64) {234 music.tempo=cc->cur_f64-0.0005;235 tempo_state.tempo=Round(TEMPO_RANGE*(music.tempo-0.5)/4.4);236 }237 } else if (!StrCmp(cc->cur_str,"stacatto_factor")) {238 if (Lex(cc)=='=' && Lex(cc)==TK_F64) {239 music.stacatto_factor=cc->cur_f64-0.0005;240 tempo_state.stacatto=241 Round(TEMPO_RANGE*(music.stacatto_factor-0.12)/0.88);242 }243 }244 }245 }246 CmpCtrlDel(cc);247}248 249U8 *PsmCvtSong()250{251 PsmNote *tmpn;252 U8 *st,*src,*dst;253 I64 i,ona,note,octave,last_octave,last_duration;254 255 i=0;256 tmpn=psm.head.next;257 last_octave=I64_MIN;258 last_duration=-1;259 while (tmpn!=&psm.head) {260 dst=&tmpn->ascii;261 if (tmpn->type==PSMT_METER) {262 *dst++='M';263 *dst++=tmpn->meter_top+'0';264 *dst++='/';265 *dst++=tmpn->meter_bottom+'0';266 } else {267 if (tmpn->ona!=ONA_REST) {268 ona=tmpn->ona;269 if (Bt(&tmpn->flags,PSMf_SHARP))270 ona--;271 if (Bt(&tmpn->flags,PSMf_FLAT))272 ona++;273 octave=Ona2Octave(ona);274 note =Ona2Note (ona);275 note=music.note_map[*LstSub(note,psm_note_lst)-'A'];276 }277 if (Bt(&tmpn->flags,PSMf_TIE))278 *dst++='(';279 if (octave!=last_octave && tmpn->ona!=ONA_REST) {280 *dst++=octave+'0';281 last_octave=octave;282 }283 if (tmpn->duration!=last_duration) {284 src=LstSub(tmpn->duration,psm_duration_lst);285 *dst++=src[0];286 if (src[1])287 *dst++=src[1];288 last_duration=tmpn->duration;289 }290 if (tmpn->ona!=ONA_REST) {291 src=LstSub(note,psm_note_lst);292 *dst++=src[0];293 if (src[1])294 *dst++=src[1];295 else if (Bt(&tmpn->flags,PSMf_FLAT))296 *dst++='b';297 else if (Bt(&tmpn->flags,PSMf_SHARP))298 *dst++='#';299 } else300 *dst++='R';301 }302 *dst++=0;303 i+=StrLen(tmpn->ascii);304 tmpn=tmpn->next;305 }306 307 st=MAlloc(i+1);308 dst=st;309 tmpn=psm.head.next;310 while (tmpn!=&psm.head) {311 StrCpy(dst,tmpn->ascii);312 dst+=StrLen(tmpn->ascii);313 tmpn=tmpn->next;314 }315 *dst++=0;316 return st;317}318 319U8 *PsmSaveSong(U8 *dirname,U8 *full_filename)320{321 CDoc *doc=DocNew(full_filename);322 Bool has_words;323 PsmNote *tmpn,*tmpn1;324 F64 measure_len=4,two_measure_left=2*measure_len;325 I64 ch;326 U8 *ptr;327 328 Free(PsmCvtSong); //set tmpn->ascii;329 330 music.tempo=4.4*tempo_state.tempo/TEMPO_RANGE+0.5;331 music.stacatto_factor=0.88*tempo_state.stacatto/TEMPO_RANGE+0.12;332 333 has_words=FALSE;334 tmpn=psm.head.next;335 while (tmpn!=&psm.head) {336 if (PsmHasWords(tmpn->word)) has_words=TRUE;337 tmpn=tmpn->next;338 }339 if (psm.incomplete_entry->checked)340 DocPrint(doc,"//0 incomplete\n");341 else if (has_words)342 DocPrint(doc,"//0 has words\n");343 else344 DocPrint(doc,"//0 no nothing\n");345 346 DocPrint(doc,347 "U0 Song()\n"348 "{\n"349 " Fs->task_end_cb=&SndTaskEndCB;\n"350 " MusicSettingsRst;\n"351 " music.tempo=%6.3f;\n"352 " music.stacatto_factor=%6.3f;\n"353 " try {\n"354 " while (!ScanKey) {\n"355 "\tPlay(\"",music.tempo+0.0005,music.stacatto_factor+0.0005);356 357 tmpn=psm.head.next;358 tmpn1=tmpn;359 has_words=FALSE;360 while (tmpn!=&psm.head) {361 DocPrint(doc,"%s",tmpn->ascii);362 if (PsmHasWords(tmpn->word)) has_words=TRUE;363 if (tmpn->type==PSMT_METER) {364 measure_len=tmpn->meter_top*4.0/tmpn->meter_bottom;365 two_measure_left=0;366 } else367 two_measure_left-=psm_durations[tmpn->duration];368 tmpn=tmpn->next;369 if (two_measure_left<0.001 && tmpn!=&psm.head) {370 if (has_words) {371 DocPrint(doc,"\",\n\t\t\"");372 while (tmpn1!=tmpn) {373 if (tmpn1->type!=PSMT_METER) {374 if (ptr=tmpn1->word) {375 while (ch=*ptr) {376 if (ch==CH_SPACE)377 *ptr=CH_SHIFT_SPACE;378 ptr++;379 }380 DocPrint(doc,"%Q\\0",tmpn1->word);381 } else382 DocPrint(doc,"%c\\0",CH_SHIFT_SPACE);383 }384 tmpn1=tmpn1->next;385 }386 }387 DocPrint(doc,"\");\n"388 "\tPlay(\"");389 two_measure_left=2*measure_len;390 tmpn1=tmpn;391 has_words=FALSE;392 }393 }394 if (has_words) {395 DocPrint(doc,"\",\n\t\t\"");396 while (tmpn1!=tmpn) {397 if (tmpn1->type!=PSMT_METER) {398 if (ptr=tmpn1->word) {399 while (ch=*ptr) {400 if (ch==CH_SPACE)401 *ptr=CH_SHIFT_SPACE;402 ptr++;403 }404 DocPrint(doc,"%Q\\0",tmpn1->word);405 } else406 DocPrint(doc,"%c\\0",CH_SHIFT_SPACE);407 }408 tmpn1=tmpn1->next;409 }410 }411 DocPrint(doc,"\");\n"412 " }\n"413 " } catch\n"414 " PutExcept;\n"415 " Snd;\n"416 "}\n"417 "\n"418 "Song;\n");419 DocRecalc(doc);420 if (full_filename)421 Free(full_filename);422 else423 StrPrint(doc->filename.name,"%s/Tmp.HC.Z",dirname);424 DocWrite(doc,TRUE);425 full_filename=StrNew(doc->filename.name);426 DocDel(doc);427 return full_filename;428}429 