2010-01-14 3 views
16

नोट: मैं "ऑडियो फ़ाइल foo.bar पढ़ना और इसे खेलना नहीं चाहता हूं।"क्या जावा ने ऑडियो _synthesis_ के लिए पुस्तकालयों में बनाया है?

मैं प्रोग्राम पर तकनीकी रूप से फ्लाई पर ऑडियो फाइलें उत्पन्न करना चाहता हूं और उन्हें खेलना चाहता हूं।

क्या जावा ने इसके लिए पुस्तकालयों में बनाया है, या यह सिस्टम-निर्भर पुस्तकालयों में पड़ता है?

धन्यवाद!

उत्तर

0

This Sun forum post में पाप टोन उत्पन्न करने के लिए कुछ दिलचस्प कोड है। साथ ही, यह देखते हुए कि डब्ल्यूएवी फ़ाइल प्रारूप अत्यधिक जटिल नहीं है, आप वांछित तरंग का प्रतिनिधित्व करने वाली तालिका बना सकते हैं और फिर उसे फ़ाइल में लिख सकते हैं। आसपास के कुछ उदाहरण हैं, उदा। a raw audio converter और how to write a wav file

+3

सूर्य मंच लिंक मर चुका है। – RealHowTo

+0

आईआईआरसी, चर्चा में [दृष्टिकोण] (http://stackoverflow.com/a/7782749/230513) [एंड्रयू थॉम्पसन] (http://stackoverflow.com/users/418556/andrew-thompson) के कारण शामिल है, उद्धृत [यहां] (http://stackoverflow.com/a/2065693/230513)। – trashgod

2

क्या आपने JSyn पर देखा है? मुझे नहीं लगता कि जावा कोर पुस्तकालय आप जो चाहते हैं वह कर सकते हैं।

1

Java Sound API देखें।

थोड़ा और देखकर, मुझे Jass भी मिला।

+0

जैस = मृत लिंक –

39

Andrew's approach का उपयोग करके, यहां एक उदाहरण है जो equal tempered scale चलाता है।

import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 

public class Tone { 

    public static void main(String[] args) throws LineUnavailableException { 
     final AudioFormat af = 
      new AudioFormat(Note.SAMPLE_RATE, 8, 1, true, true); 
     SourceDataLine line = AudioSystem.getSourceDataLine(af); 
     line.open(af, Note.SAMPLE_RATE); 
     line.start(); 
     for (Note n : Note.values()) { 
      play(line, n, 500); 
      play(line, Note.REST, 10); 
     } 
     line.drain(); 
     line.close(); 
    } 

    private static void play(SourceDataLine line, Note note, int ms) { 
     ms = Math.min(ms, Note.SECONDS * 1000); 
     int length = Note.SAMPLE_RATE * ms/1000; 
     int count = line.write(note.data(), 0, length); 
    } 
} 

enum Note { 

    REST, A4, A4$, B4, C4, C4$, D4, D4$, E4, F4, F4$, G4, G4$, A5; 
    public static final int SAMPLE_RATE = 16 * 1024; // ~16KHz 
    public static final int SECONDS = 2; 
    private byte[] sin = new byte[SECONDS * SAMPLE_RATE]; 

    Note() { 
     int n = this.ordinal(); 
     if (n > 0) { 
      double exp = ((double) n - 1)/12d; 
      double f = 440d * Math.pow(2d, exp); 
      for (int i = 0; i < sin.length; i++) { 
       double period = (double)SAMPLE_RATE/f; 
       double angle = 2.0 * Math.PI * i/period; 
       sin[i] = (byte)(Math.sin(angle) * 127f); 
      } 
     } 
    } 

    public byte[] data() { 
     return sin; 
    } 
} 

यह निम्न-स्तर दृष्टिकोण पुराने, कम सक्षम प्लेटफ़ॉर्म के लिए उपयुक्त हो सकता है। javax.sound.midi पर भी विचार करें; एक पूर्ण उदाहरण दिखाया गया है here और Synthesizing Sound ट्यूटोरियल here उद्धृत किया गया है।

+0

जावा पैकेज javax.sound.sampled एक संश्लेषण पुस्तकालय नहीं है। यह केवल डिजिटल प्रतिनिधित्वों के पारित होने की सुविधा प्रदान करता है जो पहले से ही ओएस के मूल ऑडियो सिस्टम में संश्लेषित किए गए थे। –

+0

@ डगलसडेसीको: इस भेद को आकर्षित करने के लिए धन्यवाद; जबकि प्रश्नकर्ता चाहता था कि "फ्लाई पर ऑडियो फाइलें प्रोग्रामेटिक रूप से उत्पन्न करें," मैंने विकल्पों पर विचार करने के लिए अपने तर्क को उद्धृत करने के लिए उत्तर अपडेट किया है। – trashgod

+0

भेद की सराहना करने के लिए धन्यवाद। पूछताछकर्ता इस बात के बारे में बहुत विशिष्ट नहीं था कि लाइब्रेरी की मांग एक तरंग पीढ़ी लाइब्रेरी या एक बताना-ओएस-टू-प्ले-वेवफॉर्म लाइब्रेरी थी। आप midi लाइब्रेरी का उपयोग कर एक छोटे से प्रोग्राम की कोशिश कर सकते हैं। यह नमूनाकरण synth के तरीके में नोट्स पैदा करता है। अंग या सिंथेटिक-ध्वनि नोट्स के लिए कम उपयोगी लेकिन पारंपरिक उपकरणों की आवाज़ें उत्पन्न करने के लिए बहुत बेहतर है। –

1

Jcollider सुपरकॉलिडर संश्लेषण सर्वर के लिए जावा इंटरफ़ेस है। यदि आप संगीत को संश्लेषित करना चाहते हैं, तो यह चीजों को अधिक आसान बना देगा (यह स्वर जनरेटर से सिंथेसाइज़र तक दूर हो जाता है, ग्राफ पीढ़ी जैसी चीजों का ख्याल रखता है, संश्लेषण ग्राफ से म्यूट synths को फिर से जरूरी होने तक, synths के बीच सिग्नल पैचिंग गतिशील रूप से, आदि)।

7

यह करने के लिए सबसे आसान तरीका बनाया मिडी पुस्तकालयों में जावा के साथ है:

int channel = 0; // 0 is a piano, 9 is percussion, other channels are for other instruments 

    int volume = 80; // between 0 et 127 
    int duration = 200; // in milliseconds 

    try { 
     Synthesizer synth = MidiSystem.getSynthesizer(); 
     synth.open(); 
     MidiChannel[] channels = synth.getChannels(); 

     // -------------------------------------- 
     // Play a few notes. 
     // The two arguments to the noteOn() method are: 
     // "MIDI note number" (pitch of the note), 
     // and "velocity" (i.e., volume, or intensity). 
     // Each of these arguments is between 0 and 127. 
     channels[channel].noteOn(60, volume); // C note 
     Thread.sleep(duration); 
     channels[channel].noteOff(60); 
     channels[channel].noteOn(62, volume); // D note 
     Thread.sleep(duration); 
     channels[channel].noteOff(62); 
     channels[channel].noteOn(64, volume); // E note 
     Thread.sleep(duration); 
     channels[channel].noteOff(64); 

     Thread.sleep(500); 

     // -------------------------------------- 
     // Play a C major chord. 
     channels[channel].noteOn(60, volume); // C 
     channels[channel].noteOn(64, volume); // E 
     channels[channel].noteOn(67, volume); // G 
     Thread.sleep(3000); 
     channels[channel].allNotesOff(); 
     Thread.sleep(500); 



     synth.close(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
+0

यह एक अच्छा समाधान है, मैं इसके साथ बहुत मज़ाक करूँगा! चियर्स – Stevo

4

जावा के अंतर्निहित मिडी क्षमताओं

ऑफ-द-शेल्फ जावा 8 JRE निश्चित रूप से आप क्या है विशेष रूप से अनुरोध किया गया: एक अंतर्निहित synth पुस्तकालय। यह Synthesizing Sound में कुछ विस्तार से वर्णित है।

quite refined example एक नमूना संगीत synth के लिए एक दृश्य कुंजीपटल पहुंच प्रदान करता है।

javax.sound.midi लाइब्रेरी में उपकरण और MIDI और नमूना उपकरण प्रौद्योगिकी के आधार पर उन पर नोट्स चलाने की क्षमता शामिल है। ध्वनियां क्लासिक कुर्ज़वेइल संगीत वाद्ययंत्र लाइन के रूप में प्रामाणिक नहीं हैं, लेकिन ढांचा उस परिष्कार के स्तर का समर्थन करता है यदि आप एक ही उपकरण के लिए एकाधिक पिच श्रेणियों में अपना नमूना करना चाहते हैं और काफी सहज संक्रमण के विवरण का काम करते हैं श्रेणियों के बीच।

तुच्छ प्रयोग

के त्वरित दृश्य के लिए उदाहरण यहाँ एक तुच्छ उदाहरण क्लास है।

import javax.sound.midi.MidiSystem; 
import javax.sound.midi.Synthesizer; 
import javax.sound.midi.MidiChannel; 

public class PlayMidiNote 
{ 
    private static void sleep(int iUSecs) 
    { 
     try 
     { 
      Thread.sleep(iUSecs); 
     } 
     catch (InterruptedException e) 
     { 
     } 
    } 

    public static void main(String[] args) throws Exception 
    { 
     if (args.length < 3 && args.length > 4) 
     { 
      System.out.println("usage: java PlayNote 
        <8.bit.midi.note.number> <8.bit.velocity> 
        <usec.duration> [<midi.channel>]"); 
      System.exit(1); 
     } 

     int iMidiKey = Math.min(127, Math.max(0, 
       Integer.parseInt(args[0]))); 
     int iVelocity = Math.min(127, Math.max(0, 
       Integer.parseInt(args[1]))); 
     int iUSecsDuration = Math.max(0, 
       Integer.parseInt(args[2])); 
     int iChannel = args.length > 3 
      ? Math.min(15, Math.max(0, 
        Integer.parseInt(args[3]))) 
      : 0; 

     Synthesizer synth = MidiSystem.getSynthesizer(); 
     synth.open(); 

     MidiChannel[] channels = synth.getChannels(); 
     MidiChannel channel = channels[iChannel]; 

     channel.noteOn(iMidiKey, iVelocity); 
     sleep(iUSecsDuration); 
     channel.noteOff(iMidiKey); 

     synth.close(); 
    } 
} 

बहु सूत्रण या GitHub.com पर उपलब्ध उन जैसे javax.sound.midi.Sequencer के कार्यान्वयन का उपयोग संरचना वास्तव में संगीत बनाने के लिए आवश्यक प्रदान करेगा।

तरंग पीढ़ी

आप नमूने का उपयोग करने के बजाय अपने खुद के waveforms उत्पन्न करने के लिए चाहते हैं, तो आपके सवाल का जवाब दिया, "नहीं," हालांकि आप इस स्वर सिंथेसाइज़र मैं इस सवाल के लिए लिखा था के साथ खेल सकते है । यह कई विशेषताएं है। पिच के

  • नियंत्रण
  • आयाम का नियंत्रण (डिजिटल चरणों में)
  • न्यूनतम और अधिकतम आंकड़े (प्रति सेकंड चक्र में) से संकेत मिलता है जब आयाम बहुत अधिक है (जिसमें से स्वर की विकृति का कारण बनता है ऑडियो क्लिपिंग)
  • स्वर अवधि का नियंत्रण (सेकंड में)
  • हार्मोनिक्स का एक मनमाना संख्या (जो सुर के गुण या तरंग को निर्धारित करता है, जो कई कारकों है कि एक संगीत नोट के लय बनाने में से एक है के रिश्तेदार आयाम नियंत्रण)

यह सिंथ उच्च अंत तरंग पैदा synths के कई सुविधाओं का अभाव है। एक नोट

  • नोटों के दृश्यों खेलने नहीं करता है की अवधि पर सिद्धांत हार्मोनिक और अन्य हार्मोनिक्स के आयाम की

    • वास्तविक समय संशोधन
    • नहीं है (लेकिन अपेक्षाकृत आसानी से ऐसा करने के लिए संशोधित किया जा सकता है) सुविधा समाप्त करना हार्मोनिक्स या तो शिफ्ट (लेकिन यह कुछ हद तक एक अप्रासंगिक कमी है, क्योंकि हार्मोनिक्स के चरण विशेषताओं कुछ मानव कान पता लगाने में सक्षम नहीं है)

    SimpleSynth

    01,235,164 का एक अच्छा प्रदर्शन है
    • ऑडियो संश्लेषण के सिद्धांतों
    • हार्मोनिक्स के timbral प्रभाव
    • जावा के उपयोग उत्पन्न करने के लिए ऑडियो नमूना सरणियों
    • एक बाइट सरणी
    • इस तरह के एक बाइट के submittal में नमूने रखने एक लाइन

    मानक डिजिटल ऑडियो शब्दावली का उपयोग निरंतर और परिवर्तनीय नामकरण दोनों के लिए किया गया था। गणित टिप्पणी में समझाया गया है।

    import javax.sound.sampled.AudioSystem; 
    import javax.sound.sampled.AudioFormat; 
    import javax.sound.sampled.SourceDataLine; 
    
    class SimpleSynth 
    { 
        private static int SAMPLE_BITS = 16; 
        private static int CHANNELS = 1; 
        private static boolean SIGNED_TRUE = true; 
        private static boolean BIG_ENDIAN_FALSE = false; 
        private static float CDROM_SAMPLE_FREQ = 44100; 
    
        private SourceDataLine line; 
    
        private double dDuration; 
        private double dCyclesPerSec; 
        private double dAmplitude; 
        private double[] adHarmonics; 
    
        private double dMin; 
        private double dMax; 
    
        public SimpleSynth(String[] asArguments) throws Exception 
        { 
         dDuration = Double.parseDouble(asArguments[0]); 
         dCyclesPerSec = Double.parseDouble(asArguments[1]); 
         dAmplitude = Double.parseDouble(asArguments[2]); 
         adHarmonics = new double[asArguments.length - 3]; 
         for (int i = 0; i < adHarmonics.length; ++ i) 
          adHarmonics[i] = Double.parseDouble(
            asArguments[i + 3]); 
    
         AudioFormat format = new AudioFormat(
           CDROM_SAMPLE_FREQ, SAMPLE_BITS, 
           CHANNELS, SIGNED_TRUE, BIG_ENDIAN_FALSE); 
         line = AudioSystem.getSourceDataLine(format); 
         line.open(); 
         line.start(); 
        } 
    
        public void closeLine() 
        { 
         line.drain(); 
         line.stop(); 
        } 
    
        public void playSound() 
        { 
         // allocate and prepare byte buffer and its index 
         int iBytes = (int) (2.0 * (0.5 + dDuration) 
           * CDROM_SAMPLE_FREQ); 
         byte[] ab = new byte[iBytes]; 
         int i = 0; 
    
         // iterate through sample radian values 
         // for the specified duration 
         short i16; 
         double dSample; 
         double dRadiansPerSample = 2.0 * Math.PI 
           * dCyclesPerSec/CDROM_SAMPLE_FREQ; 
         double dDurationInRadians = 2.0 * Math.PI 
           * dCyclesPerSec * dDuration; 
         dMin = 0.0; 
         dMax = 0.0; 
         for (double d = 0.0; 
           d < dDurationInRadians; 
           d += dRadiansPerSample) 
         { 
          // add principle and the dot product of harmonics 
          // and their amplitudes relative to the principle 
          dSample = Math.sin(d); 
          for (int h = 0; h < adHarmonics.length; ++ h) 
           dSample += adHarmonics[h] 
             * Math.sin((h + 2) * d); 
    
          // factor in amplitude 
          dSample *= dAmplitude; 
    
          // adjust statistics 
          if (dMin > dSample) 
           dMin = dSample; 
          if (dMax < dSample) 
           dMax = dSample; 
    
          // store in byte buffer 
          i16 = (short) (dSample); 
          ab[i ++] = (byte) (i16); 
          ab[i ++] = (byte) (i16 >> 8); 
         } 
    
         // send the byte array to the audio line 
         line.write(ab, 0, i); 
        } 
    
        public void printStats() 
        { 
         System.out.println("sample range was [" 
           + dMin + ", " + dMax + "]" 
           + " in range of [-32768, 32767]"); 
    
         if (dMin < -32768.0 || dMax > 32767.0) 
          System.out.println("sound is clipping" 
            + "(exceeding its range)," 
            + " so use a lower amplitude"); 
        } 
    
        public static void main(String[] asArguments) 
          throws Exception 
        { 
         if (asArguments.length < 3) 
         { 
          System.err.println("usage: java SimpleSynth" 
            + " <duration>" 
            + " <tone.cycles.per.sec>" 
            + " <amplitude>" 
            + " [<relative.amplitude.harmonic.2>" 
            + " [...]]"); 
          System.err.println("pure tone:" 
            + " java SimpleSynth 1 440 32767"); 
          System.err.println("oboe-like:" 
            + " java SimpleSynth 1 440 15000 0 1 0 .9"); 
          System.err.println("complex:" 
            + " java SimpleSynth 1 440 800 .3" 
            + " .5 .4 .2 .9 .7 5 .1 .9 12 0 3" 
            + " .1 5.2 2.5 .5 1 7 6"); 
    
          System.exit(0); 
         } 
    
         SimpleSynth synth = new SimpleSynth(asArguments); 
         synth.playSound(); 
         synth.closeLine(); 
         synth.printStats(); 
    
         System.exit(0); 
        } 
    } 
    

    विषय अध्ययन के बढ़ाने के लिए संगीत संश्लेषण विशेषज्ञता

    यदि आप एक डिजिटल सिंथ विशेषज्ञ बनने की इच्छा पर पढ़ने के लिए कुछ विषयों रहे हैं।

    • डिजिटल ऑडियो
    • सिग्नल
    • Nyquist मापदंड
    • (जैसे एक गिटार के रूप में) एक तारवाला साधन पर हार्मोनिक्स बांधना कैसे
    • बेसिक त्रिकोणमिति, विशेष रूप से ज्या समारोह नमूना
  • संबंधित मुद्दे