Partage
  • Partager sur Facebook
  • Partager sur Twitter

[résolu] f.seekp(5, std::ios::beg);

Créer le poids d'un fichier audio

9 mai 2024 à 15:25:49

Bonjour,

Depuis presque deux semaines j'essaie désespérément de modifier le poids des fichiers audio que je génère.

Je n'y arrive pas, est-ce que quelqu'un peu m'aider ?

voici mon code :

		f.seekp(0, std::ios::end);  //je me mets à la fin du fichier audio
		int ou = f.tellp();//je récupère le poids du fichier	
		f.clear();
				f.seekp(5, std::ios::beg);// je place le curseur à la première adresse du poids du fichier le 5,6,7,8
		f<< "0x" << std::setfill('0') << std::setw(2) << std::hex << ou;
		f.seekp(41, std::ios::beg);//je place le curseur à la deuxième adresse à modifier 41,42,43,44
		f<< "0x" << std::setfill('0') << std::setw(2) << std::hex << ou;

c'est dans une fonction que j'ouvre comme ça

std::string const f1("audiojo.wav");
std::ofstream f (f1.c_str(), std::ios::binary | std::ios::app | std::ios::in | std::ios::out | std::ios::ate);
	if(!f) {

et mes includes sont

#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <bits/stdc++.h>
#include <fstream>
#include <string>
#include <iomanip>
#include <stdio.h>
//#include <format>
#include <sstream>



Le résultat controler avec ghex est que j'écris à la fin et non pas aux positions indiquées

-
Edité par pierrejocelynleonraoulandre 9 mai 2024 à 22:49:43

  • Partager sur Facebook
  • Partager sur Twitter
9 mai 2024 à 15:38:14

Donc... Tu ouvres un fichier qui est censé être en binaire (le .wav est pas un format texte), tu écris du texte dedans, et tu t'étonnes que ça fasse pas ce à quoi tu t'attends ?

EDIT:

Le plus rigolo, c'est que tu l'ouvres bien avec std::ios::binary

-
Edité par dragonjoker 9 mai 2024 à 15:39:07

  • Partager sur Facebook
  • Partager sur Twitter

Si vous ne trouvez plus rien, cherchez autre chose.

9 mai 2024 à 16:26:00

Bonjour, merci pour la réponse.

Avez-vous une proposition de solution ?

Concernant la conversion en binaire avant, il y avait format, mais cette technique de conversion n'est plus en c++, c'est pourquoi j'utilise :

f<< "0x" << std::setfill('0') << std::setw(2) << std::hex << ou;

Le role de cette ligne de code est de convertir en premier en hexa, puis d'ajouter l'écriture au bon format wav du fichier avec le 2x0 devant

A aucun moment j'ai essayer d'écrire un int comme imaginé, de toute façon, le problème est que je n'écris pas à la bonne adresse, ce n'est pas l'écriture dans un mauvais format.

-
Edité par pierrejocelynleonraoulandre 9 mai 2024 à 16:29:30

  • Partager sur Facebook
  • Partager sur Twitter
9 mai 2024 à 17:08:22

Ecris des octets dedans (avec ofstream::write). Pas du texte (<<)

Et "0x02" c'est du texte. Contrairement à 0x02, encore égal à 2, 002, 0b00000010...

-
Edité par lmghs 9 mai 2024 à 17:09:19

  • Partager sur Facebook
  • Partager sur Twitter
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
9 mai 2024 à 19:37:56

Merci pour la réponse concernant la technique pour écrire les exa, mais actuellement mon problème c'est que j'écris à la fin du fichier avec f.seekp.

Je vais étudier comment fonctionne ofstream::write

Mais sincèrement j'ai des doutes sur vos affirmations.

J'ai créé une application qui génère des fichiers audio, elle fonctionne très bien, il ne me manque qu'à modifier le poids car actuellement j'utilise un poids lourd pour éviter que le fichier audio soit coupé. et j'utilise cette technique (<<)

De vous donner cette précision, me fait penser à une autre solution possible pour l'écriture, mon problème reste le positionnement.

Est-ce que quelqu'un peut répondre à la question sans tenir compte de ma manière d'écrire les exa ?

Cordialement

-
Edité par pierrejocelynleonraoulandre 9 mai 2024 à 20:22:35

  • Partager sur Facebook
  • Partager sur Twitter
9 mai 2024 à 20:11:49

Parce que tu ouvres ton fichier avec `std::ios::app`

> seek to the end of stream before each write

https://en.cppreference.com/w/cpp/io/ios_base/openmode

-
Edité par jo_link_noir 9 mai 2024 à 20:13:01

  • Partager sur Facebook
  • Partager sur Twitter
9 mai 2024 à 21:24:31

Merci pour la réponse, si c'est l'origine du problème, je vais changer de technique et fermé l'appli pour  ajouter une appli qui corrigera l'entête du fichier ou carrément écrira l'entête entière à la fin. Je suis obligé d'utiliser cette fonction, car l'application ajoute à la demande le nombre de formes acoustiques.

Si cela fonctionne je reviendrais mettre en résolu

En détail si cela intéresse, mon appli pour compositeur est composé d'une appli qui crée des formes en format texte, puis d'une appli qui transforme ces formes dans un fichier wav, il me suffit d'ajouter l'appli qui corrige l'entête après. Dès que j'ai fini j'injecte dans le git du projet

Cordialement

-
Edité par pierrejocelynleonraoulandre 9 mai 2024 à 21:31:23

  • Partager sur Facebook
  • Partager sur Twitter
10 mai 2024 à 23:18:23

Et voila le code qui va bien pour info :

	if(!f) {
		std::cerr << "Impossible d'ouvrir le fichier en écriture !" << std::endl;
		//return 1;
	}
    f.seekp(0, std::ios::end);  //je me mets à la fin du fichier audio 
 
  
    int poids = f.tellp();//je récupère le poids du fichier
             
            if (poids > (65536) )
            {
            int a,b,c,d,k=0,j=0;
            a = poids % (256);            
            for (int i = 0; i < poids; i=i+65536) {  k++;}
            c=k-1;
            d =  poids % (65536);
            for (int i = 0; i < d; i=i+256) {  j++;}
            b=j-1;
            f.seekp(4, std::ios::beg);//je me place ou il faut remplacer
            f<<tabn[a];
            f.seekp(5, std::ios::beg);//je me place ou il faut remplacer
            f<<tabn[b];
            f.seekp(6, std::ios::beg);//je me place ou il faut remplacer
            f<<tabn[c];
            f.seekp(40, std::ios::beg);//je me place ou il faut remplacer
            f<<tabn[a];
            f.seekp(41, std::ios::beg);//je me place ou il faut remplacer
            f<<tabn[b];
            f.seekp(42, std::ios::beg);//je me place ou il faut remplacer
            f<<tabn[c];
            }
            if (poids < 65536)
            {
            int a,b,j=0;
            a= poids % (256);
            for (int i = 0; i < poids; i=i+256) {  j++;}
            b=j-1;
            f.seekp(4, std::ios::beg);//je me place ou il faut remplacer
            f<<tabn[a];
            f.seekp(5, std::ios::beg);//je me place ou il faut remplacer
            f<<tabn[b];
            f.seekp(40, std::ios::beg);//je me place ou il faut remplacer
            f<<tabn[a];
            f.seekp(41, std::ios::beg);//je me place ou il faut remplacer
            f<<tabn[b];
             for (int i = 0; i < poids; i=i+256) {  j++;}
             b=j;
            }

    f.close();
  }          

C'est poussé dans le git du projet

  • Partager sur Facebook
  • Partager sur Twitter
11 mai 2024 à 0:23:57

Je ne vois pas comment cela pourrait bien fonctionner avec des variables non initialisées. Tu devrais vraiment configurer ton compilateur.

De plus, tu utilises les API type texte qui font plus que simplement écrire ce qui est demandé. Comme l'a dit @lmghs, tu devrais utiliser write() ce qui donne

char data[] { /*mettre les octets à écrire ici*/ };
f.write(data, sizeof(data));

Au passage, std::filesystem::file_size donne la taille du fichier. Il n'est pas nécessaire de déplacer le curseur avec seekp à chaque fois: il avance du nombre d'octet écrit.

for (int i = 0; i &lt; poids; i=i+256) { j++;} -> j += poids / 256;

Ton code est très mal indenté.

  • Partager sur Facebook
  • Partager sur Twitter
11 mai 2024 à 8:03:10

Mille mercis pour les précieuses informations, je vais regarder plus au moment.

En détail si cela intéresse. le code fonctionne très bien, il est donné en entier dans le GIT

En 1993 j'ai créé mon propre système mathématique construit sur l'idée que chaque évènement possédait sa base de temps, ceci afin de pouvoir exercer mon métier de régleur. De manière à prouver la puissance de l'outil, j'ai créé bien plus tard un générateur vidéo en javascript. Depuis peu à la retraite, je viens de finir de créer une appli qui permet de composer de la musique, voix humaine compris. Ce générateur est construit sur un format audio ultra léger que j'ai créé. Pour que celui-ci soit compréhensible, j'ai utilisé un format texte, ou chaque onde est représenté par 4 valeurs.

Par habitude, j'écris tout directement avec un éditeur texte (à un moment vi ), cela me permet de garder le contrôle sur les associations d'idées.

Avant de commencer à ajuster les indentations et améliorer les codes je dois

Finir d'injecter les générateurs de fichiers en format texte sur le GIT

Ensuite, je dois expliquer comment fonctionne l'outil pour les compositeurs

ensuite, je dois largement commenter le code pour expliquer ce que je fais,

et à la fin, je m'occupera de mettre aux noremes les indentations.

Cordialement

-
Edité par pierrejocelynleonraoulandre 11 mai 2024 à 8:06:21

  • Partager sur Facebook
  • Partager sur Twitter
11 mai 2024 à 14:15:34

Je rajouterai qu'il est préférable d'utiliser des fonctions de type host_to_network (format network =~big endian) (ou host to little?) pour convertir des nombres en représentation interne (host) vers le format attendu (en général, le format big endian est le plus courant en réseau ou dans des fichiers -- pour diverses raisons historiques techniques et humaines).

Pourquoi ces fonctions? Beaucoup plus clair (une fonction bien nommée qui factorise un boulot qui obscurcirait localement le code autrement), et efficace (pas de conversion ni de triturage d'ordre s'il est détecté que le nombre est stocké en interne dans le même format que celui dans lequel il sera écrit).

Seul hic, d'une machine à l'autre POSIX (https://man7.org/linux/man-pages/man3/endian.3.html) ou windows, ce ne sont pas les mêmes noms... Après quelqu'un s'est amusé à produire une version portable: https://gist.github.com/panzi/6856583 (manquerait juste une version C++ qui fournit un seul nom surchargé et c'est le bonheur!)

  • Partager sur Facebook
  • Partager sur Twitter
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
12 mai 2024 à 11:55:41

Bonjour,

Il faut tenir compte de l'historique.

Les évènements font que j'ai choisit un format léger 8bits (seulement 256 positions,) pour montrer les lois physiques, c'est directement issus des jeunes druides qui tiraient la branche du chêne pour montrer l'hystérésis, et qui est resté dans notre manière d'agencer les idées. Il se trouve que c'est du little endian.

Comme ce qui nous rend humain, est la création, j'ai apporté un outil pour pouvoir créer, faire de l'art, découvrir, je suis entrain de mettre sur la page des captures d'écran en ajustant les sonorités de démo.

Le tout est sur un GIT, chacun peut créer sa branche en respectant la licence GNU, pour moi une fois les explications et les indentations finies, je regarderai un format audio du libre, mais rien n'empêche que chacun adapte pour une utilisation qui lui va, comme créer son propre instrument de musique piloter avec des rayons lumineux, ou encore mieux des focales qui reprenne l'analogique , les équilibres des lois qu'apporte l'outil ici présenté.

En d'autres mots, oui c'est important, mais je ne suis qu'une feuille porté par le vent et le sol est trop proche pour que j'envisage de long trajets.

Cordialement

  • Partager sur Facebook
  • Partager sur Twitter
15 mai 2024 à 21:11:00

Bonjour,

Pour ceux que ça intéresse pour tester, l'archive complète est là https://www.letime.net/son/ap/audiojo.tar.gz

L'application permet de transmettre des compositions musicales de quelques octets sous mon format qui génère des Mo en ogg stéréo

Chaque compositeur peut créer ses formes particulière en créant son propre générateur texte ou même directement avec un tableur, ou plus simplement utiliser un des générateurs déjà fourni.

Sur le git, il est possible de faire un fork car ma spécialité, c'est régleur, phénomènes physiques, technologies pour les utiliser, et langage machine avec goto, pas vraiment le c++

Cordialement

  • Partager sur Facebook
  • Partager sur Twitter
16 mai 2024 à 21:14:25

Bonjour, comme dit, j'ai relu et cherché à comprendre la proposition de "lmghs" .

J'ai hésité à répondre mais je pense devoir le faire car je pense que le vital, l'essentielle de ma démarche n'est pas entendue.

Je suis persuadé qu'un anglo-saxon, un arabe ou même un chinois ne peut pas comprendre ce que je fais, car son langage ne lui permet pas d'associer les idées à la française. Associer les idées à la française, c'est parler français, c'est percevoir le monde avec des concepts. Le format audio que je présente, ce sont des formes particulières qui suivent les lois physiques, quand j'écris un nombre, ce n'est pas un notion de quantité, ce n'est pas la de manière de l'écrire (big endian), ce n'est un adressage, ce n'est pas ..., quand j'écris un nombre c'est un symbole qui représente un concept qui permet de produire une forme sonore particulière. Parler à la française, c'est utiliser une étincelle, qui change de forme à chaque dimension qu'elle traverse pour allumer le feu qui réchauffe notre coeur. Il n'y a pas de compression, il n'y a pas de conversion. Il y a un faible souffle qui augmente en traversant les régions et les lois physiques pour s'appeler Mistral. Mon fauteuil est la culture française descendante des celtes, et mon coussin sont les encyclopédies descendants de 1789. Comprenez que c'est l'homme qui s'adapte à son environnement et comme l'a déjà fait windows en abandonnant 98 (le seul vrai windows) cet O.S. s'adaptera en copiant à nouveau pour survivre. Je ne peux, ni ne veux aller contre cette évidence.

Cordialement

  • Partager sur Facebook
  • Partager sur Twitter
17 mai 2024 à 1:37:02

Bonsoir,
Je pourrais parler aussi de métier VS technique. Le métier peut être hyper compliqué. Très bien. Jusqu'à un moment où "j'ai une information que je veux encoder d'une certaine façon". Là, les petites mains de la technique que nous sommes, on comprend bien mieux ce que les gens du métier imaginent.

Et on ne parle que de ça. Le reste, je ne juge pas et cela ne m'intéresse pas.

A voir le code final (?) où je vois un nombre qui est décomposé à la main en octets qui sont ensuite écrits à la queue leu-leu. Je vois un code inutilement alambiqué quand on connait ce que le langage et les pratiques nous offrent.

Le pourquoi? Le comment? Ce ne m’intéresse pas. Je vois un code informatique, et je fais des propositions de simplifications pour une maintenance future. On peut prendre ou ignorer.

Après j'avoue avoir fait un peu d'interprétation faute de vision de ce qu'est tabn[]. En m'appuyant sur https://fr.wikipedia.org/wiki/Waveform_Audio_File_Format#En-t%C3%AAte_de_fichier_WAV j'en déduis qu'en positions 4-7 on stocke la taille - 8 en little endian.

Soit

// uint32_t est pile le bon type exact à employer pour stocker des entiers non signés de taille 4
std::uint32_t size = ... tellg/std::filesystem::file_size(filename) qui va bien - 8;
// en vrai il faudrait vérifier que la taille tient bien sur 32 bits

f.seekp(4, std::ios::beg); 
auto encoded_size = host_to_little(size);
f.write(reinterpet_cast<char const*>(&encoded_size), sizeof(encoded_size));


avec dans ma boite à outils host_to_little() qui est une surcharge des fonctions host_to_little pour les formats unsigned_int 16, 32 et 64 bits.

Si maintenant tabn[] ne correspond pas à l'information de taille à mettre en position 4 comme renseigné dans le format sur wikipédia. Au temps pour moi.

PS: EDIT: Faux, je disais une bêtise:  <<<"f << char(13 ou  10)" ça va vraiment faire n'importe quoi. Ou pourquoi il faut utiliser write!>>>
binary nous protège à priori. Au temps pour moi

PPS: les boucles i = 0 à taille en pas de N, ca se réécrit "taille > 0 ? (taille-1) / N +1 : 0". Plus besoin d'enlever le 1 à la fin avec la formule mathématique. Par contre, attention au cas 0. On sent que si d est nul et que l'on fait -1 après on va avoir des soucis. Je fais le pari de la doc, et que c'est bien la taille - 8 en little endian que l'on veut, et que du coup, la version simplifiée sera bien plus simple et exempte de bug.

EDIT2: je ne dis pas que la solution que je propose est une évidence. Elle est plus un kata/réflexe conditionné/gamme-de-solfège chez les initiés habitués à manipuler des formats de données "binaires".

-
Edité par lmghs 17 mai 2024 à 12:19:56

  • Partager sur Facebook
  • Partager sur Twitter
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
18 mai 2024 à 8:48:30

@pierrejocelynleonraoulandre

Je m'intéresse à ce qui touche au son et à la musqiue.

J'ai réussi à compiler tes sources. Mais l'utilisation est un peu obscure. Que faut-il faire après ? Qu'est-ce que ton logiciel est censé produire exactement ?

  • Partager sur Facebook
  • Partager sur Twitter
30 mai 2024 à 22:44:07

Bonjour,

Merci pour la réponse.

L'application est utilisable en l'état, elle est très puissante mais demande un apprentissage. En fait les sons se manipule comme la langue française, ce ne sont que des équilibres entres différentes formes.

Nous pouvons modifier ces formes avec un fichier texte qui se nomme audio.jo, il est composée de 200 ondes.

Ensuite nous avons 5 sortes de constructeurs qui traduisent les formes dessinée, en fichier audio aux standard des normes imposées, une fois que nous avons fini notre composition, il faut cliquer sur le bouton finaliser pour créer l'entête du fichier audio.

Ensuite nous utilisons le lecteur audio sox qui permet d'ajouter différents effets.

Le but de cet application est que chacun puisse créer son propre instrument de musique et transmettre sa musique avec seulement quelques dizaines d'octets qui vont générer des Mo au format ogg. Tout est modifiable par exemple dans execu nous pouvons modifier la valeur de j et ainsi choisir le nombre d'onde dessiner, nous pouvons ouvrir n'importe laquelle des app qui dessine les 200 ondes et la modifier, nous pouvons modifier le fichier audio.jo pour ajouter des front fort qui produiront une consonne en générant un son de voyelle ... c'est un outil pour créateur compositeur, accessoirement le curieux peut y découvrir les lois physiques ou un système mathématique que j'ai créé en 1993, mais l'important est de s'amuser et passer un bon moment.

Cet outil permet d'associer les idées à la française au travers des sons (c'est pas la peine de chercher à traduire en anglais c'est impossible, leur langue ne permet pas d'exprimer les subtilités entre les équilibres). Je vais y ajouter des boites à rythme pour pouvoir les mixer avec la sortie 9, et je dois reprendre wav 5 qui produit des signaux carrés, ça peut-être utile, mais comme c'est pas voulu, je vais reprendre cette partie du code.

Il est certain que le code peut et doit être améliorer car je reprend une multitude de fois les mêmes fonctions, mais ce n'est pas encore d'actualité.

Cordialement

P.S.

Bonjour, je lis ce matin la réponse de lmghs, il est certain que l’acquis induit notre perception, je n'impose pas une méthode, je sais très bien que l'appli reprends une multitude de fois les mêmes codes et qu'il faudrait créer  plusieurs petites classes qui le rendrait beaucoup plus simple et diviserait le poids par au moins 2, mais au moment ma démarche est d'ajouter à la version graphique sous qt une boite à rythme pour rendre l'appli plus ludique.

Il ne faut pas oublier que mon but est que chacun puisse créer son propre outil, ses propres sonorutés, en manipulant le fichier texte audio.jo, en modifiant les générateurs de fichiers textes, en modifiant les traducteurs de formes en wav, et en associant ses formes en jouant sur la valeur J (nombre d'ondes généré) pour créer ses propre tempo. Le mieux est l'ennemi du bien dans l'absolu se trouve la mort, l'immobilité, la vie est mouvement, en donnant un code batard cela permet à chacun de le faire évoluer à son sentiment. Le vital est qu'il fonctionne et apporte un moment de plaisir.

Il en reste pas moins que vos informations m'ont grandement aidé, sur plusieurs niveaux, cela m'a permis de passer plusieurs étapes et de trouver plusieurs informations indispensables à la version graphique sur laquelle je travaille en ce moment qui est indiquée dans un message voisin.

Le vrai est qu'un outil qui sert à tout ne sert à rien, pas d'absolu en science ou en technologie, le bien est de récupérer les codes qui intéressent les améliorer pour créer son propre enfant adapté à son usage, et d'aller chercher plaisirs et gloire à sa convenance.

-
Edité par pierrejocelynleonraoulandre 31 mai 2024 à 8:37:05

  • Partager sur Facebook
  • Partager sur Twitter