11
votes

Réelle génération de son de bas niveau en C #?

Quelqu'un sait un moyen raisonnable de créer une onde sonore arbitraire en C # et de le lire des haut-parleurs?

Ce problème revient à tous les jours et puis depuis des années, je finis toujours à l'abandonner après beaucoup d'échec sans trouver une solution.

Ce que je veux faire, c'est comme un visual inverse, c'est-à-dire que je ne veux pas générer des "chiffres" du son, je veux générer du son des nombres.

J'aime obtenir une fonction que je fournis avec la fréquence d'échantillonnage, la taille des échantillons et les données sonores (une gamme d'entiers par exemple), et générerait le fichier WAV approprié de celui-ci (la lecture sonore en temps réel serait idéale, Mais je serais plus que ravi de cela aussi).

Je sais que les spécifications du fichier WAV sont sur l'interweb et ont fait plusieurs tentatives de création de la fonction ci-dessus, ont eu un certain succès pour les basses fréquences, mais une fois que je commençais à jouer avec des bits par échantillon, etc., il devient un énorme, mess incontrôlable.

N'est-ce pas déjà fait de quelque manière que ce soit? Cela ne me dérangerait pas ce qu'il utilise, tant qu'il y a un wrapper géré .NET pour cela (et je peux y accéder à partir des vs les plus récents à temps). XNA ne prend pas en charge l'audio de faible niveau de cette manière. A également trouvé plusieurs exemples qui prétendent atteindre quelque chose de similaire, mais ils ne travaillent pas du tout ou font quelque chose de totalement différent.

merci.


0 commentaires

3 Réponses :


2
votes

FMOD peut faire des échantillons de charges de la mémoire et a un emballage C #.


1 commentaires

D'accord, j'ai juste eu beaucoup de choses à venir alors ne pouvait pas expérimenter cela beaucoup encore, je suis désolé. FMOD peut définitivement le faire, mais il a une terrible emballage gérée automatiquement générée automatiquement. Il y a un exemple spécifique de faire cela avec certains paramètres, mais c'est une douleur à modifier ces paramètres et que cela oblige les développeurs à utiliser du code dangereux partout. Merci d'avoir souligné la pensée, quand j'aurai plus de temps, je leur demanderai pourquoi je ne pouvais pas utiliser plus de 2 octets par exemple.



8
votes

Cela avait l'air intéressant de sorte que j'ai assommé une simple application qui:

  • crée les échantillons pendant deux secondes d'une tonalité pure (440Hz a).
  • les convertit en une matrice d'octet au format de fichier WAV.
  • joue le son en passant le tableau d'octets à l'API PlaySound.
  • inclut également le code pour enregistrer les données WAV dans un fichier WAV.

    Vous pouvez facilement modifier la fréquence d'échantillonnage, la fréquence de tonalité et la durée de l'échantillon. Le code est très moche et inefficace spatial mais cela fonctionne. Ce qui suit est une application de ligne de commande complète: xxx


4 commentaires

Cela a l'air vraiment génial et je me sens vraiment honte mais je n'avais pas le temps de vraiment jouer avec ça. Une seule question: est-il facile de faire 4 octets par échantillon?


Vous pouvez en faire 4 octets par échantillon, mais je ne sais pas si Windows le jouera. Cela pourrait, je ne sais tout simplement pas. Quoi qu'il en soit, si vous souhaitez que cela change, toutes les références à la taille de la taille de (int), modifiez le type d'échantillon sur Int, modifiez le facteur de mise à l'échelle (short.maxvalue) sur INT.MAXValue et corrigez la boucle qui remplit l'octet tableau pour ajouter quatre octets par échantillon. Mais je serais surpris de bien vouloir entendre une différence.


Merci beaucoup pour cela. Comment puis-je ajouter des fonctionnalités d'arrêt (et peut-être une pause) ici? Je suppose que j'aurais besoin d'un ouvrier d'arrière-plan pour que le reste de l'interface graphique soit libre pour la commission. À quel type de code un "stop son" ressemble-t-il?


@DANW: playsound est une API très simple qui vient de jouer un son. Si vous voulez un contrôle plus sophistiqué, tel que la pause et l'arrêt, vous avez besoin d'une API différente. Il existe plusieurs API Win32 qui feraient le travail, mais aucun d'entre eux n'a d'emballage .NET intégré. Naudio est une bibliothèque audio open source .NET. J'ai entendu de bonnes choses à ce sujet, mais je ne l'ai jamais utilisée.



2
votes

Comment jouer à partir d'un tableau ci-dessous

    PlayerEx pl = new PlayerEx();

    private static void PlayArray(PlayerEx pl)
    {
        double fs = 8000; // sample freq
        double freq = 1000; // desired tone
        short[] mySound = new short[4000];
        for (int i = 0; i < 4000; i++)
        {
            double t = (double)i / fs; // current time
            mySound[i] = (short)(Math.Cos(t * freq) * (short.MaxValue));
        }
        IntPtr format = AudioCompressionManager.GetPcmFormat(1, 16, (int)fs);
        pl.OpenPlayer(format);
        byte[] mySoundByte = new byte[mySound.Length * 2];
        Buffer.BlockCopy(mySound, 0, mySoundByte, 0, mySoundByte.Length);
        pl.AddData(mySoundByte);
        pl.StartPlay();
    }


0 commentaires