comparison tools/xm2jss.c @ 2476:90eec3e1f85f

Use DMResource I/O instead of stdio for writing JSSMOD module.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 27 Apr 2020 18:33:18 +0300
parents b9734859db5c
children 7151597d8ec6
comparison
equal deleted inserted replaced
2475:b9734859db5c 2476:90eec3e1f85f
508 508
509 #undef JSFOREACHNOTE1 509 #undef JSFOREACHNOTE1
510 #undef JSFOREACHNOTE2 510 #undef JSFOREACHNOTE2
511 511
512 512
513 static BOOL jssMODWriteEnvelope(FILE *outFile, JSSEnvelope *env, const char *name, const int ninst) 513 static BOOL jssMODWriteEnvelope(DMResource *outFile, const JSSEnvelope *env, const char *name, const int ninst)
514 { 514 {
515 BOOL ok = 515 BOOL ok =
516 dm_fwrite_byte(outFile, env->flags) && 516 dmf_write_byte(outFile, env->flags) &&
517 dm_fwrite_byte(outFile, env->npoints) && 517 dmf_write_byte(outFile, env->npoints) &&
518 dm_fwrite_byte(outFile, env->sustain) && 518 dmf_write_byte(outFile, env->sustain) &&
519 dm_fwrite_byte(outFile, env->loopS) && 519 dmf_write_byte(outFile, env->loopS) &&
520 dm_fwrite_byte(outFile, env->loopE); 520 dmf_write_byte(outFile, env->loopE);
521 521
522 for (int i = 0; ok && i < env->npoints; i++) 522 for (int i = 0; ok && i < env->npoints; i++)
523 { 523 {
524 ok = 524 ok =
525 dm_fwrite_le16(outFile, env->points[i].frame) && 525 dmf_write_le16(outFile, env->points[i].frame) &&
526 dm_fwrite_le16(outFile, env->points[i].value); 526 dmf_write_le16(outFile, env->points[i].value);
527 } 527 }
528 528
529 if (!ok) 529 if (!ok)
530 { 530 {
531 JSSERROR(DMERR_FWRITE, ok, 531 JSSERROR(DMERR_FWRITE, ok,
537 } 537 }
538 538
539 539
540 /* Save a JSSMOD file 540 /* Save a JSSMOD file
541 */ 541 */
542 int jssSaveJSSMOD(FILE *outFile, JSSModule *module, int patMode, int flags8, int flags16) 542 int jssSaveJSSMOD(DMResource *outFile, const JSSModule *module,
543 const int patMode, const int flags8, const int flags16)
543 { 544 {
544 JSSMODHeader jssH; 545 JSSMODHeader jssH;
545 const size_t patBufSize = 512*1024; // 256kB pattern buffer 546 const size_t patBufSize = 512*1024; // 256kB pattern buffer
546 Uint8 *patBuf; 547 Uint8 *patBuf;
547 size_t totalSize; 548 size_t totalSize;
580 jssH.defSpeed = module->defSpeed; 581 jssH.defSpeed = module->defSpeed;
581 jssH.defTempo = module->defTempo; 582 jssH.defTempo = module->defTempo;
582 jssH.patMode = patMode; 583 jssH.patMode = patMode;
583 584
584 // Write header 585 // Write header
585 if (!dm_fwrite_str(outFile, jssH.idMagic, sizeof(jssH.idMagic)) || 586 if (!dmf_write_str(outFile, jssH.idMagic, sizeof(jssH.idMagic)) ||
586 !dm_fwrite_byte(outFile, jssH.idVersion) || 587 !dmf_write_byte(outFile, jssH.idVersion) ||
587 588
588 !dm_fwrite_le16(outFile, jssH.defFlags) || 589 !dmf_write_le16(outFile, jssH.defFlags) ||
589 !dm_fwrite_le16(outFile, jssH.intVersion) || 590 !dmf_write_le16(outFile, jssH.intVersion) ||
590 !dm_fwrite_le16(outFile, jssH.norders) || 591 !dmf_write_le16(outFile, jssH.norders) ||
591 !dm_fwrite_le16(outFile, jssH.npatterns) || 592 !dmf_write_le16(outFile, jssH.npatterns) ||
592 !dm_fwrite_le16(outFile, jssH.nextInstruments) || 593 !dmf_write_le16(outFile, jssH.nextInstruments) ||
593 !dm_fwrite_le16(outFile, jssH.ninstruments) || 594 !dmf_write_le16(outFile, jssH.ninstruments) ||
594 !dm_fwrite_le16(outFile, jssH.defRestartPos) || 595 !dmf_write_le16(outFile, jssH.defRestartPos) ||
595 596
596 !dm_fwrite_byte(outFile, jssH.nchannels) || 597 !dmf_write_byte(outFile, jssH.nchannels) ||
597 !dm_fwrite_byte(outFile, jssH.defSpeed) || 598 !dmf_write_byte(outFile, jssH.defSpeed) ||
598 !dm_fwrite_byte(outFile, jssH.defTempo) || 599 !dmf_write_byte(outFile, jssH.defTempo) ||
599 !dm_fwrite_byte(outFile, jssH.patMode)) 600 !dmf_write_byte(outFile, jssH.patMode))
600 { 601 {
601 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, 602 JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
602 "Error writing JSSMOD header!\n"); 603 "Error writing JSSMOD header!\n");
603 } 604 }
604 605
618 } 619 }
619 620
620 if (tmp == jsetNotSet) 621 if (tmp == jsetNotSet)
621 tmp = 0xffff; 622 tmp = 0xffff;
622 623
623 if (!dm_fwrite_le16(outFile, tmp)) 624 if (!dmf_write_le16(outFile, tmp))
624 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, 625 JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
625 "Could not write JSSMOD orders list entry #%d (%d).\n", 626 "Could not write JSSMOD orders list entry #%d (%d).\n",
626 index, tmp); 627 index, tmp);
627 628
628 totalSize += sizeof(Uint16); 629 totalSize += sizeof(Uint16);
694 dmMsg(3, " - Pattern %d size %" DM_PRIu_SIZE_T " bytes\n", 695 dmMsg(3, " - Pattern %d size %" DM_PRIu_SIZE_T " bytes\n",
695 index, dataSize); 696 index, dataSize);
696 697
697 totalSize += dataSize + sizeof(JSSMODPattern); 698 totalSize += dataSize + sizeof(JSSMODPattern);
698 699
699 if (!dm_fwrite_le32(outFile, dataSize) || 700 if (!dmf_write_le32(outFile, dataSize) ||
700 !dm_fwrite_le16(outFile, pattern->nrows) || 701 !dmf_write_le16(outFile, pattern->nrows) ||
701 !dm_fwrite_le16(outFile, pattern->nmap)) 702 !dmf_write_le16(outFile, pattern->nmap))
702 { 703 {
703 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, 704 JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
704 "Error writing JSSMOD pattern header #%d.\n", 705 "Error writing JSSMOD pattern header #%d.\n",
705 index); 706 index);
706 } 707 }
707 708
708 if (pattern->nmap != pattern->nchannels) 709 if (pattern->nmap != pattern->nchannels)
709 { 710 {
710 if (!dm_fwrite_str(outFile, pattern->map, 711 if (!dmf_write_str(outFile, pattern->map,
711 sizeof(pattern->map[0]) * pattern->nmap)) 712 sizeof(pattern->map[0]) * pattern->nmap))
712 { 713 {
713 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, 714 JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
714 "Error writing JSSMOD channel map for pattern #%d.\n", 715 "Error writing JSSMOD channel map for pattern #%d.\n",
715 index); 716 index);
716 } 717 }
717 } 718 }
718 719
719 if (!dm_fwrite_str(outFile, patBuf, dataSize)) 720 if (!dmf_write_str(outFile, patBuf, dataSize))
720 { 721 {
721 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, 722 JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
722 "Error writing JSSMOD pattern data #%d.\n", 723 "Error writing JSSMOD pattern data #%d.\n",
723 index); 724 index);
724 } 725 }
743 index); 744 index);
744 } 745 }
745 746
746 // Misc data 747 // Misc data
747 BOOL ok = 748 BOOL ok =
748 dm_fwrite_byte(outFile, einst->nsamples) && 749 dmf_write_byte(outFile, einst->nsamples) &&
749 dm_fwrite_byte(outFile, einst->vibratoType) && 750 dmf_write_byte(outFile, einst->vibratoType) &&
750 dm_fwrite_le16(outFile, einst->vibratoSweep) && 751 dmf_write_le16(outFile, einst->vibratoSweep) &&
751 dm_fwrite_le16(outFile, einst->vibratoDepth) && 752 dmf_write_le16(outFile, einst->vibratoDepth) &&
752 dm_fwrite_le16(outFile, einst->vibratoRate) && 753 dmf_write_le16(outFile, einst->vibratoRate) &&
753 dm_fwrite_le16(outFile, einst->fadeOut); 754 dmf_write_le16(outFile, einst->fadeOut);
754 755
755 // Sample number for note(s) 756 // Sample number for note(s)
756 for (int i = 0; ok && i < jsetNNotes; i++) 757 for (int i = 0; ok && i < jsetNNotes; i++)
757 { 758 {
758 int snum = einst->sNumForNotes[i]; 759 int snum = einst->sNumForNotes[i];
759 Uint32 tmp = (snum != jsetNotSet) ? snum + 1 : 0; 760 Uint32 tmp = (snum != jsetNotSet) ? snum + 1 : 0;
760 ok = dm_fwrite_le32(outFile, tmp); 761 ok = dmf_write_le32(outFile, tmp);
761 } 762 }
762 763
763 // Envelopes 764 // Envelopes
764 if (!ok || 765 if (!ok ||
765 !jssMODWriteEnvelope(outFile, &einst->volumeEnv, "volume", index) || 766 !jssMODWriteEnvelope(outFile, &einst->volumeEnv, "volume", index) ||
786 inst->convFlags = (inst->flags & jsf16bit) ? flags16 : flags8; 787 inst->convFlags = (inst->flags & jsf16bit) ? flags16 : flags8;
787 if (inst->data != NULL) 788 if (inst->data != NULL)
788 inst->convFlags |= jsampHasData; 789 inst->convFlags |= jsampHasData;
789 790
790 // Write instrument header 791 // Write instrument header
791 if (!dm_fwrite_le32(outFile, inst->size) || 792 if (!dmf_write_le32(outFile, inst->size) ||
792 !dm_fwrite_le32(outFile, inst->loopS) || 793 !dmf_write_le32(outFile, inst->loopS) ||
793 !dm_fwrite_le32(outFile, inst->loopE) || 794 !dmf_write_le32(outFile, inst->loopE) ||
794 !dm_fwrite_le16(outFile, inst->flags) || 795 !dmf_write_le16(outFile, inst->flags) ||
795 !dm_fwrite_le16(outFile, inst->C4BaseSpeed) || 796 !dmf_write_le16(outFile, inst->C4BaseSpeed) ||
796 !dm_fwrite_le16(outFile, inst->ERelNote) || 797 !dmf_write_le16(outFile, inst->ERelNote) ||
797 !dm_fwrite_le16(outFile, inst->EFineTune) || 798 !dmf_write_le16(outFile, inst->EFineTune) ||
798 !dm_fwrite_le16(outFile, inst->EPanning) || 799 !dmf_write_le16(outFile, inst->EPanning) ||
799 !dm_fwrite_byte(outFile, inst->volume) || 800 !dmf_write_byte(outFile, inst->volume) ||
800 !dm_fwrite_byte(outFile, inst->convFlags)) 801 !dmf_write_byte(outFile, inst->convFlags))
801 { 802 {
802 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, 803 JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
803 "Error writing JSSMOD instrument #%d.\n", 804 "Error writing JSSMOD instrument #%d.\n",
804 index); 805 index);
805 } 806 }
839 JSSERROR(res, res, 840 JSSERROR(res, res,
840 "Error encoding sample for instrument #%d: %s\n", 841 "Error encoding sample for instrument #%d: %s\n",
841 index, dmErrorStr(res)); 842 index, dmErrorStr(res));
842 } 843 }
843 844
844 if (!dm_fwrite_str(outFile, inst->data, bsize)) 845 if (!dmf_write_str(outFile, inst->data, bsize))
845 { 846 {
846 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, 847 JSSERROR(DMERR_FWRITE, DMERR_FWRITE,
847 "Error writing JSSMOD sample data for instrument #%d.\n", 848 "Error writing JSSMOD sample data for instrument #%d.\n",
848 index); 849 index);
849 } 850 }
1294 } 1295 }
1295 1296
1296 1297
1297 int main(int argc, char *argv[]) 1298 int main(int argc, char *argv[])
1298 { 1299 {
1299 DMResource *inFile = NULL; 1300 DMResource *inFile = NULL, *outFile = NULL;
1300 FILE *outFile = NULL;
1301 JSSModule *src = NULL, *dst = NULL; 1301 JSSModule *src = NULL, *dst = NULL;
1302 int res = DMERR_OK; 1302 int res = DMERR_OK;
1303 1303
1304 dmInitProg("xm2jss", "XM to JSSMOD converter", "0.8", NULL, NULL); 1304 dmInitProg("xm2jss", "XM to JSSMOD converter", "0.8", NULL, NULL);
1305 dmVerbosity = 0; 1305 dmVerbosity = 0;
1391 } 1391 }
1392 else 1392 else
1393 dst = src; 1393 dst = src;
1394 1394
1395 // Write output file 1395 // Write output file
1396 if ((outFile = fopen(optOutFilename, "wb")) == NULL) 1396 if ((res = dmf_open_stdio(optOutFilename, "wb", &outFile)) != DMERR_OK)
1397 { 1397 {
1398 res = dmGetErrno();
1399 dmErrorMsg("Error creating output file '%s': %s\n", 1398 dmErrorMsg("Error creating output file '%s': %s\n",
1400 optOutFilename, dmErrorStr(res)); 1399 optOutFilename, dmErrorStr(res));
1401 goto out; 1400 goto out;
1402 } 1401 }
1403 1402
1404 dmMsg(1, "Writing JSSMOD-format file [patMode=0x%04x, samp8=0x%02x, samp16=0x%02x]\n", 1403 dmMsg(1, "Writing JSSMOD-format file [patMode=0x%04x, samp8=0x%02x, samp16=0x%02x]\n",
1405 optPatternMode, optSampMode8, optSampMode16); 1404 optPatternMode, optSampMode8, optSampMode16);
1406 1405
1407 res = jssSaveJSSMOD(outFile, dst, optPatternMode, optSampMode8, optSampMode16); 1406 res = jssSaveJSSMOD(outFile, dst, optPatternMode, optSampMode8, optSampMode16);
1408 1407
1409 fclose(outFile); 1408 dmf_close(outFile);
1410 1409
1411 if (res != 0) 1410 if (res != 0)
1412 { 1411 {
1413 dmErrorMsg( 1412 dmErrorMsg(
1414 "Error while saving JSSMOD file: %s\n" 1413 "Error while saving JSSMOD file: %s\n"