Logicielsmoto.com http://www.logicielsmoto.com/phpBB/ |
|
Conversion K7->WAV pour MO http://www.logicielsmoto.com/phpBB/viewtopic.php?f=3&t=551 |
Page 1 sur 1 |
Auteur: | Prehisto [ 24 Fév 2017, 10:23 ] |
Sujet du message: | Conversion K7->WAV pour MO |
Je reposte ici le programme pour convertir les fichiers MO K7 en fichier WAV présent sur le sujet http://www.logicielsmoto.com/phpBB/viewtopic.php?f=13&t=516, afin de le mettre éventuellement à jour. Pulkomandy, libre à toi d'y joindre ton programme pour MO6. Usage: k5towav [--modified] <filename> --modified : modifie la forme du signal pour essayer de corriger les erreurs de lecture (optionnel) <filename> : le nom d'un fichier K5. Le fichier WAV sera sauvé dans le même répertoire sous le même nom avec le suffixe ".wav" (16 bits/44100Hz) Le makefile : Code: CC=gcc CFLAGS= -W -Wall -Werror -O2 all : k5towav Le programme k5towav : Code: /*--------------------------------------------------------*/ /* k5towav (c) Prehisto feb 2015 */ /* To convert MO K7 file to WAV file */ /*--------------------------------------------------------*/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #ifndef TRUE # define TRUE 1 #endif #ifndef FALSE # define FALSE 0 #endif /* WAV constants */ #define WAVE_HEADER_SIZE 0x2c #define WAVE_RIFF_CHUNK_SIZE 4 #define WAVE_FORMAT_CHUNK_SIZE 16 #define WAVE_FORMAT_PCM 1 #define WAVE_FORMAT_CHANNELS 1 #define WAVE_FORMAT_SAMPLESPERSEC 44100 #define WAVE_FORMAT_BLOCKALIGN 2 #define WAVE_FORMAT_AVGBYTEPERSEC WAVE_FORMAT_SAMPLESPERSEC*WAVE_FORMAT_BLOCKALIGN #define WAVE_FORMAT_BITPERSAMPLE 16 /* Sample parameters */ #define CYCLES_PER_FRAME 19968 #define MICROSEC_PER_FRAME 20000 #define MICROSEC_PER_SEC 1000000 #define CURRENT_VALUE_DEFAULT 0x7fff static int flag_modified = FALSE; static int current_value = CURRENT_VALUE_DEFAULT; static double remain = 0; static int cycles = 0; static void write_gap (int length, FILE *file) { int i; for (i=0; i<length; i++) { fputc (current_value&0xff, file ); fputc ((current_value>>8)&0xff, file ); } } static void write_motoroff (FILE *file) { write_gap (WAVE_FORMAT_SAMPLESPERSEC/2, file); } static void write_motoron (FILE *file) { write_gap (WAVE_FORMAT_SAMPLESPERSEC, file); } static void write_data_gap (FILE *file) { /* Must have time to do at least : 4+2 NEXT LDA ,X+ 4+2 STA ,U+ 4+1 LEAY -1,U 3 BNE NEXT ... a bit more! */ write_gap (WAVE_FORMAT_SAMPLESPERSEC/8, file); } static void write_signal (FILE *file) { int i; double size = ((((double)cycles*(double)MICROSEC_PER_FRAME) /(double)CYCLES_PER_FRAME) *(double)WAVE_FORMAT_SAMPLESPERSEC) /(double)MICROSEC_PER_SEC; size += remain-(double)((int)remain); remain = size; /* write signal */ for (i=0; i<(int)size; i++) { fputc (current_value&0xff, file ); fputc ((current_value>>8)&0xff, file ); } /* invert signal */ current_value=~current_value; cycles = 0; } static void write_byte_standard (char byte, FILE *file) { int bit; /* 4 LF1AF STA <$2045 2 LDB #$08 */ cycles += 4+2; for (bit=0x80; bit>0; bit>>=1) { /* 7 LF1B3 BSR LF1CB 2 LF1CB LDA #$40 4+0 EORA ,U 4+0 STA ,U */ cycles += 7+2+4+4; write_signal (file); /* 5 RTS 3 LDX #$002D 7 BSR LF1A2 4+1 LF1A2 LEAX -$01,X 3 BNE LF1A2 2 CLRA 5 RTS 3 LDX #$0032 6 ASL <$2045 3 BCC LF1C5 */ cycles += 5+3+7+(0x2d*(4+1+3))+2+5+3+6+3; if (((int)byte & bit) == 0) { /* 7 LF1C5 BSR LF1A2 4+1 LF1A2 LEAX -$01,X 3 BNE LF1A2 2 CLRA 5 RTS */ cycles += 7+(0x32*(4+1+3))+2+5; } else { /* 7 BSR LF1CB 2 LF1CB LDA #$40 4+0 EORA ,U 4+0 STA ,U */ cycles += 7+2+4+4; write_signal (file); /* 5 RTS 4+1 LEAX -$03,X 7 LF1C5 BSR LF1A2 4+1 LF1A2 LEAX -$01,X 3 BNE LF1A2 2 CLRA 5 RTS */ cycles += 5+4+1+7+((0x32-3)*(4+1+3))+2+5; } /* 2 DECB 3 BNE LF1B3 */ cycles += 5; } /* 5 RTS */ cycles += 5; } static void write_byte_modified (char byte, FILE *file) { int bit; /* 4 LF1AF STA <$2045 2 LDB #$08 */ cycles += 4+2; for (bit=0x80; bit>0; bit>>=1) { /* 7 LF1B3 BSR LF1CB 2 LF1CB LDA #$40 4+0 EORA ,U 4+0 STA ,U */ cycles += 7+2+4+4; write_signal (file); cycles += 269; if (((int)byte & bit) == 1) { write_signal (file); } cycles += 564; /* 2 DECB 3 BNE LF1B3 */ cycles += 5; } /* 5 RTS */ cycles += 5; } static void write_byte (char byte, FILE *file) { if (flag_modified == FALSE) write_byte_standard (byte, file); else write_byte_modified (byte, file); } #define STOCK_LENGTH 40 #define MOTOR_STOPS_AFTER_THIS_BLOCK 0x01 #define MOTOR_STOPS_AFTER_DATA_BLOCK 0x02 static void convert_file (FILE *bin_file, FILE *wav_file) { static char stock[STOCK_LENGTH]; static size_t length = 0; static size_t size = 0; static int motor_status = 0; char dcmoto_mark1[] = "DCMOTO\1\1\1\1\1\1\1\1\1\1\x3c\x5a"; char dcmoto_mark2[] = "\xdc\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\x3c\x5a"; char basic_mark[] = "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\x3c\x5a"; do { if ((length < STOCK_LENGTH) && (feof (bin_file) == 0)) { size = fread(stock+length, 1, STOCK_LENGTH-length, bin_file); length += size; } if (length > 19) { if ((memcmp (dcmoto_mark1, stock, 18) == 0) || (memcmp (dcmoto_mark2, stock, 18) == 0) || (memcmp (basic_mark, stock, 18) == 0)) { if (motor_status != 0) { write_motoroff (wav_file); motor_status &= ~MOTOR_STOPS_AFTER_THIS_BLOCK; } memset (stock, 0x01, 6); cycles = 0; remain = 0; if (stock[18] == '\0') { write_motoron (wav_file); motor_status &= ~MOTOR_STOPS_AFTER_DATA_BLOCK; if ((length > (18+2+0x0d)) && (stock[18+2+0x0d] != '\0')) { motor_status |= MOTOR_STOPS_AFTER_DATA_BLOCK; } motor_status |= MOTOR_STOPS_AFTER_THIS_BLOCK; } else { if ((motor_status & MOTOR_STOPS_AFTER_DATA_BLOCK) != 0) { write_motoron (wav_file); } else { write_data_gap (wav_file); } if (stock[18] == '\xff') { motor_status &= ~MOTOR_STOPS_AFTER_DATA_BLOCK; motor_status |= MOTOR_STOPS_AFTER_THIS_BLOCK; } else { motor_status &= ~MOTOR_STOPS_AFTER_THIS_BLOCK; } } } } cycles += 4+2+7; /* For preparing data to be written */ write_byte (*stock, wav_file); cycles += 6+3; /* For the loop */ memmove (stock, stock+1, STOCK_LENGTH-1); length--; } while (length > 0); } static void write_le4 (int value, FILE *file) { fputc( value&0xff, file ); fputc( (value>>8)&0xff, file ); fputc( (value>>16)&0xff, file ); fputc( (value>>24)&0xff, file ); } static void write_le2 (int value, FILE *file) { fputc( value&0xff, file ); fputc( (value>>8)&0xff, file ); } static void write_id (char *id, FILE *file) { int size = fwrite (id, 1, 4, file); (void)size; } static void update_wav_header (char *filename) { FILE *file; struct stat st; stat( filename, &st ); file = fopen (filename, "rb+"); if (file != NULL) { write_id ("RIFF", file); write_le4 ((int)st.st_size-WAVE_RIFF_CHUNK_SIZE, file); write_id ("WAVE", file); write_id ("fmt ", file); write_le4 (WAVE_FORMAT_CHUNK_SIZE, file); write_le2 (WAVE_FORMAT_PCM, file); write_le2 (WAVE_FORMAT_CHANNELS, file); write_le4 (WAVE_FORMAT_SAMPLESPERSEC, file); write_le4 (WAVE_FORMAT_AVGBYTEPERSEC, file); write_le2 (WAVE_FORMAT_BLOCKALIGN, file); write_le2 (WAVE_FORMAT_BITPERSAMPLE, file); write_id ("data", file); write_le4 ((int)st.st_size-WAVE_HEADER_SIZE, file); fclose (file); } } static void write_wav (char *bin_name, char *wav_name) { int i; FILE *bin_file; FILE *wav_file; bin_file = fopen (bin_name, "rb"); if (bin_file != NULL) { wav_file = fopen (wav_name, "wb"); if (wav_file != NULL) { /* Create WAV header gap */ for (i=0; i<WAVE_HEADER_SIZE; i++) { fputc (0x00, wav_file); } /* Write WAV data */ write_motoron (wav_file); convert_file (bin_file, wav_file); write_motoroff (wav_file); fclose (wav_file); update_wav_header (wav_name); } else { printf ("*** Can not write file %s\n", wav_name); } fclose (bin_file); } else { printf ("*** Can not read file %s\n", bin_name); } } static int info (void) { printf ("k5towav (c) Prehisto feb 2015\n"); printf (" Usage : k5towav [--modified] <filename>\n"); return EXIT_FAILURE; } int main (int argc, char *argv[]) { int i; char bin_name[300] = ""; char wav_name[300] = ""; for (i=1; i<argc; i++) { if (argv[i][0] == '-') { if (strcmp (argv[i], "--modified") == 0) { flag_modified = TRUE; } else { printf ("*** option '%s' unknown\n", argv[i]); return info (); } } else { if (*bin_name == '\0') { strcpy(bin_name, argv[i]); } else { return info (); } } } sprintf (wav_name, "%s.wav", bin_name); write_wav (bin_name, wav_name); return EXIT_SUCCESS; } EDIT 20 fév 2015 15:56 : Le programme reconnaît maintenant quelques repères DCMOTO. Mais, à part corriger les bugs, je n'irai pas plus loin. Ce programme est juste un exemple. EDIT 20 fév 2015 19:47 : Correction de bug. MICROSEC_PER_FRAME était incrémenté par 10 pour le calcul de 'size' dans write_signal() , ce qui était inutile. Juste un reste de test. EDIT 21 fév 2015 21:51 : Simplification du code. EDIT 21 fév 2015 22:53 : Correction d'offset, d'une condition et de la compilation. EDIT 22 fév 2015 18:27 : Simplification du code. |
Auteur: | PulkoMandy [ 24 Fév 2017, 19:48 ] |
Sujet du message: | Re: Conversion K7->WAV pour MO |
Ma version n'a pas bougé: http://pulkomandy.tk/projects/thomson/b ... /k5towav.c Pour rappel, les modifications que j'avais éffectuées: - Passage de 44.100kHz a 11.025kHz pour réduire la taille des fichiers - Doublage de la vitesse pour écrire dans le format du MO6 (2 fois plus rapide que le MO5) - Reconaissance de "DCMO6" dans l'en-tête des fichiers (marquage ajouté sur certains fichiers de dcmoto.free.fr) - Augmentation du délai pour un "motor off", car ma configuration ne permet pas de détecter l'arrêt du moteur du lecteur de cassettes. |
Auteur: | gilles [ 26 Fév 2017, 15:00 ] |
Sujet du message: | Re: Conversion K7->WAV pour MO |
avec cette méthode pas mal de fichiers .K7 ne vont pas marcher (et historiquement c'est de ma faute). Les premières K7 MO5 converties avec le cable LEP vers port série ne sont pas alignées sur un octet, pour la synchro on retrouve donc soit 010101 soit autrechose comme 020202 etc... on peut aussi retrouver des erreurs de synchro plus ou moins volontaires... (cette méthode permet de charger correctement pulsar II dans les toutes premières versions de mon emu MO5 en activant le mode "real K7'). l'émulateur fonctionne avec parceque c'est le routine de lecture d'un bit qui a été patché en ROM et pas la routine pour un octet. http://www.alternative-system.com/speci ... sfert.html Pour ces fichiers là il faudrait d'abord les reconvertir avec un outil pour recaler sur les octets... j'ai ca dans un coin... |
Page 1 sur 1 | Heures au format UTC + 1 heure |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |