Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria
Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria
vivo X300 Pro rappresenta un'evoluzione misurata della serie fotografica del produttore cinese, con un sistema di fotocamere migliorato, chipset Dimensity 9500 di ultima generazione e l'arrivo dell'interfaccia OriginOS 6 anche sui modelli internazionali. La scelta di limitare la batteria a 5.440mAh nel mercato europeo, rispetto ai 6.510mAh disponibili altrove, fa storcere un po' il naso
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo
Lenovo Legion Go 2 è la nuova handheld PC gaming con processore AMD Ryzen Z2 Extreme (8 core Zen 5/5c, GPU RDNA 3.5 16 CU) e schermo OLED 8,8" 1920x1200 144Hz. È dotata anche di controller rimovibili TrueStrike con joystick Hall effect e una batteria da 74Wh. Rispetto al dispositivo che l'ha preceduta, migliora ergonomia e prestazioni a basse risoluzioni, ma pesa 920g e costa 1.299€ nella configurazione con 32GB RAM/1TB SSD e Z2 Extreme
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti
A re:Invent 2025, AWS mostra un’evoluzione profonda della propria strategia: l’IA diventa una piattaforma di servizi sempre più pronta all’uso, con agenti e modelli preconfigurati che accelerano lo sviluppo, mentre il cloud resta la base imprescindibile per governare dati, complessità e lock-in in uno scenario sempre più orientato all’hybrid cloud
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 19-03-2020, 17:29   #1
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
[C] Editor/Player file midi

ciao,
qualche anno fa avevo scritto un player di file midi che funziona abbastanza bene oggi, con la storia del coronavirus, volevo sitemarlo per tentare di creare una sorta di editor col quale sistemare alcuni miei file midi ma ho un problema ed in effetti, credo non mi sia mai stato insegnato come risolvere un problema del genere.
I file midi sono file binari strutturati in un certo modo ed io leggo byte a byte i dati dal disco con un semplice
c = fgetc(fp);
e poi in base al valore del byte, decido con un
if(c == xD10) .......
se leggere il successivo byte oppure tornare indietro di un certo numero di byte per fare ulteriori controlli.
A distanza di tempo e forse colto dalla fretta, oggi ho un sorgente con una miriade di c=fgetc(fp); ed if(c == 0x??) il quale rende molto complesso fare delle modifiche; per questo vi chiedo qual'è la strategia migliore per rendere il programma più compatto e leggibile.
Vi posto una piccolissima parte del codice in modo che possiate capire qual'è il problema

Codice:
		if(c >= 0xC0 && c <= 0xCF)
		{
			c = fgetc(fp);

			if(c <= 127) // verifico
			{
				fseek(fp, -2, SEEK_CUR); // riavvolgo

				//canale
				Phrase[contaeventi++] = fgetc(fp);
				//nota
				Phrase[contaeventi++] = fgetc(fp);
				//delta-time
				Phrase[contaeventi++] = fgetc(fp);
				// ulteriore byte di delta time
				if(Phrase[contaeventi-1] > 127){
					c = fgetc(fp);
					Phrase[contaeventi-1] = Phrase[contaeventi-1] + c; }
				c = 0;
			}
			else
			{
				fseek(fp, -2, SEEK_CUR);
				c = fgetc(fp);
			}

grazie
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 20-03-2020, 10:12   #2
Kaya
Senior Member
 
Iscritto dal: Apr 2005
Messaggi: 3276
Se il problema è la compattezza, potresti modificare il modo di identare il codice mettendo sulla stessa linea determinati elementi.
Ad esempio:
Codice:
if(c >= 0xC0 && c <= 0xCF){
	c = fgetc(fp);
	if(c <= 127) { // verifico
		fseek(fp, -2, SEEK_CUR); //riavvolgo 			
		Phrase[contaeventi++] = fgetc(fp); //canale
		Phrase[contaeventi++] = fgetc(fp); //notea
		Phrase[contaeventi++] = fgetc(fp); //delta-time
		if(Phrase[contaeventi-1] > 127){ // ulteriore byte di delta time
			c = fgetc(fp);
			Phrase[contaeventi-1] = Phrase[contaeventi-1] + c;
		}
		c = 0;
		} else {
			fseek(fp, -2, SEEK_CUR);
			c = fgetc(fp);
		}
}
Così risulta più compatto.
In alternativa potresi usare lo switch o inglobare in specifiche funzioni il codice per ogni caso.
Altre idee non mi vengono in questo momento.
Kaya è offline   Rispondi citando il messaggio o parte di esso
Old 20-03-2020, 12:21   #3
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
grazie per la risposta, però mi chiedevo se esistono metodi più compatti per evitare di scrivere miriadi di if() etc.....

Poi magari non esiste nulla e si fa per forza così, io un metodo più intelligente non l'ho trovato.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 21-03-2020, 20:18   #4
Volutomitra
Member
 
Iscritto dal: Feb 2006
Messaggi: 134
Io, che scrivo firmware, quando devo fare parsing di dati con formato noto vado quasi sempre di macchina a stati finiti. Quindi, per semplificare, uno switch con tutti i vari casi che cambiano in base a quello che devi leggere in quel punto del file.

Non conosco esattamente il formato MIDI, ma suppongo ci si adatti senza problemi. Può essere un'idea?
Volutomitra è offline   Rispondi citando il messaggio o parte di esso
Old 21-03-2020, 21:31   #5
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
Quote:
Originariamente inviato da Volutomitra Guarda i messaggi
Io, che scrivo firmware, quando devo fare parsing di dati con formato noto vado quasi sempre di macchina a stati finiti. Quindi, per semplificare, uno switch con tutti i vari casi che cambiano in base a quello che devi leggere in quel punto del file.

Non conosco esattamente il formato MIDI, ma suppongo ci si adatti senza problemi. Può essere un'idea?
grandissimo, mi serviva proprio una informazione del genere.
Io invece ho scritto una miriade di if() e fseek() per tornare sui miei passi se mi trovo davanti dati sbagliati.
Così facendo mi sono accoro che se devo fare una modifica c'è da impazzire.

un esempio?

Codice:
		if(c == 0xFF)
		{
			c = fgetc(fp);

			if(c >= 0x01 && c <= 0x07 || c == 0x7F)
			{
				lff = fgetc(fp); // numero di byte da leggere

				for( i = 0; i <= lff; i++)
				        c = fgetc(fp);

				if(c > 127)
				        c = fgetc(fp);
				c = 0;
			}
			else
			{
				fseek(fp, -2, SEEK_CUR);// se non trovo quello che cerco riavvolgo il file di 2 bytes
				c = fgetc(fp);
			} // end else
		}
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2020, 13:21   #6
Volutomitra
Member
 
Iscritto dal: Feb 2006
Messaggi: 134
Provo a tradurre il tuo pezzo di codice (non sapendo cosa succede prima e dopo). Ovviamente potrei avere commesso qualche errore, è giusto per farti capire cosa intendo.

Dal codice posso immaginare che in quel punto tu ti aspetti come primo valore nel buffer un byte 0xFF, quindi farei una cosa del genere:

Codice:
// inizializzazione stato
state = WAIT_FOR_FF;

....

// nella funzione di parsing:

while (ho_roba_da_leggere) {
  c = fgetc(fp);

  switch (state) {
    case WAIT_FOR_FF:
      if (0xFF == c) {
        state = WAIT_FOR_SOMETHING_ELSE;
      }
      break;

    case WAIT_FOR_SOMETHING_ELSE:
       if ((c >= 0x01 && c <= 0x07) || (0x7F == c)) {
         state = READ_LENGTH;
       } else {
	 state = GO_BACK_TWO_BYTES;
       }
       break;

    case READ_LENGTH:
       lff = fgetc(fp); // numero di byte da leggere
       state = READ_DATA;
       break;

    case GO_BACK_TWO_BYTES:
      fseek(fp, -2, SEEK_CUR);
      state = DO_SOMETHING; // non so cosa succede a questo punto
      break;

    case READ_DATA:
      if (++i > lff) {
        state = READ_NEXT_STUFF;
       }
       break;

    case READ_NEXT_STUFF:
      if (c > 127) {
        state = READ_OTHER_STUFF;
      }
      break;

    case READ_OTHER_STUFF:
      // non dovrebbe fare niente qui, solo saltare al prossimo stato
      state = MOVE_ON;
      break;

    case MOVE_ON:
      // fai qualcosa
      c = 0; //???? non so a cosa serve
      break;
  }
}
Vedi tu
Volutomitra è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2020, 13:29   #7
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
la tua idea mi è chiarissima ma ti chiedo: secondo te, meglio attraverso un unico switch oppure, creare una moltitudine di funzioni ognuna specializzata nel leggere una parte del file midi?
Più che altro è riuscire ad avere codice che si può manutentare senza ammattire.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2020, 14:58   #8
Volutomitra
Member
 
Iscritto dal: Feb 2006
Messaggi: 134
Quote:
Originariamente inviato da misterx Guarda i messaggi
la tua idea mi è chiarissima ma ti chiedo: secondo te, meglio attraverso un unico switch oppure, creare una moltitudine di funzioni ognuna specializzata nel leggere una parte del file midi?
Più che altro è riuscire ad avere codice che si può manutentare senza ammattire.
beh, credo che alla tua domanda non ci sia una risposta corretta. Molto dipende da come uno è abituato a scrivere il codice oppure se si tratta di un lavoro in team ovviamente da quali sono le linee guida.
E' una scelta molto personale. Io sono abituato a ragione per FSM, ma è anche deformazione professionale

Forse la scelta più corretta potrebbe essere quella di restare sulla FSM ed eventualmente usare funzioni nei casi più complessi. Ma ti ripeto, è una scelta molto personale...
Volutomitra è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2020, 15:28   #9
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
Quote:
Originariamente inviato da Volutomitra Guarda i messaggi
beh, credo che alla tua domanda non ci sia una risposta corretta. Molto dipende da come uno è abituato a scrivere il codice oppure se si tratta di un lavoro in team ovviamente da quali sono le linee guida.
E' una scelta molto personale. Io sono abituato a ragione per FSM, ma è anche deformazione professionale

Forse la scelta più corretta potrebbe essere quella di restare sulla FSM ed eventualmente usare funzioni nei casi più complessi. Ma ti ripeto, è una scelta molto personale...
grazie 1000
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 24-03-2020, 15:00   #10
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
cha pastrocchio sto formato midi, come si fa ad usare ad esempio En in contesti diversi?

risolto!!!!

Ultima modifica di misterx : 26-03-2020 alle 16:43.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 03-04-2020, 10:29   #11
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
qualcuno ha avuto a che fare col parsing del formato midi?
Sono alle prese con la durata delle note.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 03-04-2020, 18:03   #12
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2782
Non ho esperienza con il formato midi ma di parser so qualcosa, qual è il problema?
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 08-04-2020, 17:10   #13
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
grazie per la tua partecipazione ma credo di aver risolto quasi tutti i problemi relativi al parsing.

Ora ho un problema di rappresentazione grafica legata agli eventi.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 11-04-2020, 08:42   #14
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
ma secondo voi, che sapete già dell'esistenza dei file midi multitraccia, se dovessi intercalare tra di loro le tracce, come si potrebbe fare dato che durante la lettura ho lunghezze delle stesse diverse?
Provo graficamente per farvi capire:
|----traccia 1------|----------------------traccia 2------------------|-------------------------------------------------traccia 3-----------------------------------------------------|

volendole invece tenere separate dato che ogni '-' rappresenta una certa quantità di tempo, non sarebbe complesso mantenere n array ma tutti della stessa lunghezza ?
Avrei un abbondate spreco di memoria in quanto, quando devo eseguire le tracce avrei:

Codice:
|000000000000000000000000000000000000000000000----traccia 1------00000000000000000000000000000000000000000000000|
|000000000000000000000000000----------------------traccia 2------------------00000000000000000000000000000000000|
|-------------------------------------------------traccia 3-----------------------------------------------------|
lo 0 rappresenta una sorta di allineamento degli array/tracce dove non esistono note da suonare, ma dato che il tempo è comune non vedo altra strada.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 17-04-2020, 22:30   #15
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
ma secondo voi, scrivere una 50ina di metodi per gestire i file midi in luogo di una unica funzione piena di if, che benefici può portare in termini di manutenibilita'?
Di primo acchito penso molti. Se allo stato attuale, apro il file una sola volta, ne individuo le varie parti ed alcune le memorizzo in un array per poterle suonare, cosa accadrebbe viceversa, aprirlo n volte in luogo di una sola volta per fare il riconoscimento delle sue parti attraverso metodi in luogo di tanti if?

esempio

GetMidiHeader();
GetMidiTrachNumber();
GetMidiEvent();
..........
..........
...........

Ultima modifica di misterx : 18-04-2020 alle 11:13.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2020, 20:06   #16
Volutomitra
Member
 
Iscritto dal: Feb 2006
Messaggi: 134
Quote:
Originariamente inviato da misterx Guarda i messaggi
ma secondo voi, che sapete già dell'esistenza dei file midi multitraccia, se dovessi intercalare tra di loro le tracce, come si potrebbe fare dato che durante la lettura ho lunghezze delle stesse diverse?
Provo graficamente per farvi capire:
|----traccia 1------|----------------------traccia 2------------------|-------------------------------------------------traccia 3-----------------------------------------------------|

volendole invece tenere separate dato che ogni '-' rappresenta una certa quantità di tempo, non sarebbe complesso mantenere n array ma tutti della stessa lunghezza ?
Avrei un abbondate spreco di memoria in quanto, quando devo eseguire le tracce avrei:

Codice:
|000000000000000000000000000000000000000000000----traccia 1------00000000000000000000000000000000000000000000000|
|000000000000000000000000000----------------------traccia 2------------------00000000000000000000000000000000000|
|-------------------------------------------------traccia 3-----------------------------------------------------|
lo 0 rappresenta una sorta di allineamento degli array/tracce dove non esistono note da suonare, ma dato che il tempo è comune non vedo altra strada.
Magari hai già risolto... Ma invece di riempire l'array con dati inutili non conviene una struttura con una variabile che indica il ritardo di partenza e l'array con i dati veri e priori?

Quote:
Originariamente inviato da misterx Guarda i messaggi
ma secondo voi, scrivere una 50ina di metodi per gestire i file midi in luogo di una unica funzione piena di if, che benefici può portare in termini di manutenibilita'?
Di primo acchito penso molti. Se allo stato attuale, apro il file una sola volta, ne individuo le varie parti ed alcune le memorizzo in un array per poterle suonare, cosa accadrebbe viceversa, aprirlo n volte in luogo di una sola volta per fare il riconoscimento delle sue parti attraverso metodi in luogo di tanti if?

esempio

GetMidiHeader();
GetMidiTrachNumber();
GetMidiEvent();
..........
..........
...........
Divide et impera è sempre valido come concetto direi
Volutomitra è offline   Rispondi citando il messaggio o parte di esso
Old 20-04-2020, 20:23   #17
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
per quanto riguarda le tracce non ho ancora risolto.
A quanto ne ho capito, un file midi è una sorta di file temporale, come una pista di registratore e la ricostruzione va fatta segundo la linea temporale.
Ma che sistema del cavolo, poi magari c'è una strada banale.

Hanno messo le tracce in sequenza ed ognuna ha lunghezze diversa.

Ultima modifica di misterx : 21-04-2020 alle 20:25.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 22-04-2020, 10:45   #18
Volutomitra
Member
 
Iscritto dal: Feb 2006
Messaggi: 134
Quote:
Originariamente inviato da misterx Guarda i messaggi
per quanto riguarda le tracce non ho ancora risolto.
A quanto ne ho capito, un file midi è una sorta di file temporale, come una pista di registratore e la ricostruzione va fatta segundo la linea temporale.
Ma che sistema del cavolo, poi magari c'è una strada banale.

Hanno messo le tracce in sequenza ed ognuna ha lunghezze diversa.
Premesso che di formato MIDI ne so praticamente nulla e di musica siamo più o meno lì, ma non è che la durata ti sembra diversa perché comunque la durata delle diverse note è diversa?

Per tentare di farmi capire, supponi di avere una traccia con 10 note con durata 100ms e una con 5 note di durata 200ms... Il numero di note è diverso ma la durata della traccia è uguale.

Non so se è questo il caso, ma immagino avrai una serie di parametri tipo bpm e cose simili all'interno del file...
Volutomitra è offline   Rispondi citando il messaggio o parte di esso
Old 28-04-2020, 18:15   #19
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
Quote:
Originariamente inviato da Volutomitra Guarda i messaggi
Premesso che di formato MIDI ne so praticamente nulla e di musica siamo più o meno lì, ma non è che la durata ti sembra diversa perché comunque la durata delle diverse note è diversa?

Per tentare di farmi capire, supponi di avere una traccia con 10 note con durata 100ms e una con 5 note di durata 200ms... Il numero di note è diverso ma la durata della traccia è uguale.

Non so se è questo il caso, ma immagino avrai una serie di parametri tipo bpm e cose simili all'interno del file...
scusa ma ho impiegato un pochino a risponderti perchè sono ancora in fase studio

Codice:
DT		|4D|54|72|6B
---------------------------- traccia 1
00		|90|3C|64
200		|80|3C|64
00		|FF|2F|00|
---------------------------- traccia 2
		|4D|54|72|6B
600		|90|3C|64
200		|80|3C|64
00		|FF|2F|00|
---------------------------- traccia 3
		|4D|54|72|6B
C00		|90|3C|64
200		|80|3C|64
00		|FF|2F|00|
---------------------------- traccia 4
		|4D|54|72|6B
1200            |90|3C|64
200		|80|3C|64
00		|FF|2F|00|
DT = delta time ed è la distanza di tempo che intercorre tra un evento e l'altro.
200 ho scoperto che è la durata della nota da 2/4 cioè 1/2. Se uso note da 1/4 il valore da 200 scende a 100.
Il numero esadecimale sopra al 200 è il delta time di quanto sono spaziate le varie note:
0
600
C00
1200

Attraverso queste informazioni, e considerando che le note 3C sono su tracce diverse, si deve costruire un array per traccia, tenendo in considerazione i delta time e successivamente inviare tali valori alla scheda audio.
Considera che quando invio i dati alla scheda audio si deve inviare un int alla volta.
FIo a quando la traccia è una la soluzione è banale, con n brancolo nel buio.

Ultima modifica di misterx : 28-04-2020 alle 18:30.
misterx è offline   Rispondi citando il messaggio o parte di esso
Old 07-05-2020, 19:55   #20
misterx
Senior Member
 
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3739
sto cercando un esempio C++ di conversione dal formato midi 1 al formato 0 ma non trovo un cavolo di esempio. Si trovano librerie ma a me interessa l'implementazione, ho una parte ostica da risolvere.
Magari chi programma in ambiente Linux sa darmi una dritta in questo senso, per Windows non trovo nulla.
Nemmeno per Python, usa metodi di classi dove il codice effettivo dei metodi non viene mostrato
misterx è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria Recensione vivo X300 Pro: è ancora lui il...
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'...
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti AWS re:Invent 2025: inizia l'era dell'AI-as-a-Se...
Cos'è la bolla dell'IA e perché se ne parla Cos'è la bolla dell'IA e perché se...
BOOX Palma 2 Pro in prova: l'e-reader diventa a colori, e davvero tascabile BOOX Palma 2 Pro in prova: l'e-reader diventa a ...
Tutti gli sconti Apple su Amazon: tornan...
Altro che entry-level: due smartwatch Am...
Roscosmos ha posticipato (ancora) il lan...
Isar Aerospace si prepara al secondo lan...
Tory Bruno è entrato in Blue Orig...
Fujifilm lancia la cartuccia per archivi...
Dreame H15 Mix: la soluzione 7-in-1 per ...
AirPods Pro 3 in forte sconto su Amazon:...
36 offerte Amazon, molte appena partite:...
2 caricatori multipli eccezionali: da 28...
OLED e 360 Hz a un prezzo senza preceden...
Roborock Q10 S5+ a un prezzo molto conve...
Upgrade PC a prezzo ridotto: le migliori...
Sono i 6 smartphone migliori su Amazon: ...
Google Pixel 9a a 361€, mai così ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 14:43.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v