2010-08-04 12 views
12

के लिए माइक्रोसॉन्ड रिज़ॉल्यूशन पर फायरिंग घटनाएं कुछ माइक्रोसॉंड के संकल्प पर सी # में घटनाओं को आग लगाने का कोई तरीका है?मिडी अनुक्रमक

मैं एक मिडी अनुक्रमक का निर्माण कर रहा हूं, और इसके लिए प्रत्येक मिडी टिक को निकालने की आवश्यकता होती है, जो उस समय पंजीकृत किसी भी नोट को चलाएगी।

120 बीट प्रति मिनट और 120 पीपीक्यूएन (दालों प्रति बीट/तिमाही नोट) के एक प्रस्ताव पर, उस घटना को हर 4.16666 मिलीसेकंड को आग लगनी चाहिए। आधुनिक अनुक्रमकों में 768ppqn जैसे उच्च संकल्प होते हैं जिन्हें उस घटना को हर 651 माइक्रोसेकंडों को निकालने की आवश्यकता होती है।

मुझे मिली छोटी-छोटी घटनाओं के लिए सबसे अच्छा संकल्प 1 मिलीसेकंड है। मैं उससे आगे कैसे जा सकता हूं?

यह समस्या किसी भी सी # MIDI अनुक्रमक या MIDI फ़ाइल प्लेयर द्वारा हल हो चुकी है। शायद मैं सही कोण के माध्यम से समस्या को नहीं देख रहा हूं।

आपकी मदद के लिए धन्यवाद।

+0

मैं आपके गणित का पालन नहीं करता हूं। यदि 120ppqn = 41.6666ms, निश्चित रूप से 768ppqn! = 651microsec, लेकिन 768ppqn = 1000 * 41.6666 * 120/768 = 6510 microsec? – spender

+0

120 बीपीएम = 1 प्रत्येक 500 एमएस बीट, 120 बीट प्रति बीट = 500 एमएमएस/120 = 4.166ms और 768 टिक प्रति बीट = 500ms/768 = 0.651ms वास्तव में मेरे पहले नंबर में एक टाइपो है, मैं इसे अभी ठीक कर दूंगा । धन्यवाद। – Brice

+0

मेरे अपडेट किए गए उत्तर को देखें – Fredou

उत्तर

6

अधिकांश मिडी अनुक्रमक/मिडी खिलाड़ी या तो समय के बड़े ब्लॉक को तरंगों (कंप्यूटर स्पीकर के माध्यम से खेलने के लिए) में परिवर्तित कर देंगे या MIDI निर्देशों का एक बड़ा ब्लॉक (मिडी पोर्ट से जुड़े बाहरी डिवाइस के लिए) ले लेंगे। किसी भी तरह से, ध्वनि कार्ड पर डेटा का एक ब्लॉक कॉपी किया गया है, और साउंड कार्ड सटीक समय का ख्याल रखता है।

आप मल्टीमीडिया कंट्रोल एपीआई देखना चाहते हैं।

देखें this post over at the Microsoft discussion forum

0
बजाय टाइमर

उपयोग stopwatch

उदाहरण का उपयोग करने का 10x 1 सेकंड के लिए

,

static void Main(string[] args) 
    { 
     Stopwatch masterSW; 
     Stopwatch sw=null; 
     int count; 

     sw = Stopwatch.StartNew(); 
     sw.Reset(); 

     for (int i = 0; i < 10; i++) 
     { 
      count = 0; 
      masterSW = Stopwatch.StartNew(); 
      while (count!=1536) //1537*651 microsecond is about a second (1.0005870 second) 
      { 
       if (!sw.IsRunning) 
        sw.Start(); 

       if (sw.Elapsed.Ticks >= 6510) 
       { 
        count++; 
        sw.Reset(); 
       } 
      } 

      Debug.WriteLine("Ticks: " + masterSW.Elapsed.Ticks.ToString()); 
     } 
    } 

इच्छा उत्पादन:

Ticks: 10,005,392 (१.००,०५,३९२ पीछे नहीं है जो)
Ticks: 10,004,792
Ticks: 10,004,376
Ticks: 10,005,408
Ticks: 10,004,398
Ticks: 10,004,426
Ticks: 10,004,268
Ticks: 10,004,427
Ticks: 10,005,161
Ticks: 10004306

जो ठीक लगता है

+0

धन्यवाद। मैंने स्टॉपवॉच का उपयोग करने की कोशिश की है, लेकिन मुझे पता है कि यह केवल स्टॉपवॉच.स्टार्ट और स्टॉपवॉच.स्टॉप के बीच विलुप्त समय की जांच करने की अनुमति देता है, यह नियमित अंतराल पर घटनाओं को आग नहीं देता है – Brice

+0

वह काफी नियमित अंतराल पर 'गिनती ++' निष्पादित कर रहा है।जब तक मशीन पर बिल्कुल कुछ भी नहीं चल रहा है, यह काम कर सकता है। –

3

मुझे लगता है कि आप जी की संभावना नहीं है और एक टाइमर से बिल्कुल सही संकल्प। एक बेहतर दृष्टिकोण 1 एमएमएस सटीक टाइमर का उपयोग करना होगा, और जब यह आग लगती है, यह जांचने के लिए कि कौन सी एमआईडीआई घटनाएं लंबित हैं और उन्हें आग लगाना है।

तो, मिडी घटनाओं जाना एक क्रमबद्ध कतार में, आपको पहले एक नज़र, और उस समय के लिए अधिक से अधिक निकट आग टाइमर सेट। जब टाइमर आग लगती है, तब तक कतार से सभी घटनाओं का उपभोग करें, जब तक कि आप भविष्य की घटना का सामना न करें। इस घटना के लिए समय की गणना करें। Reschedule टाइमर।

बेशक

, यदि आप अपने soundcard के लिए outputting रहे हैं, दृष्टिकोण मौलिक रूप से अलग है, और आप अपने सभी समय के लिए नमूनों की गिनती की जानी चाहिए।

1

यह घटनाओं सही ढंग से .NET में माइक्रोसेकंड अंतराल पर निकाल दिया है करने के लिए संभव नहीं है।

असल में क्योंकि विंडोज स्वयं वास्तविक समय ओएस नहीं है, कुछ मोडर सॉफ़्टवेयर में 100% सटीकता के साथ कुछ भी कर रहा है, उपयोगकर्ता मोड सॉफ़्टवेयर में, काफी असंभव है।

एमएसडीएन पत्रिका लेख: Implement a Continuously Updating, High-Resolution Time Provider for Windows को इतना मुश्किल क्यों है, इस बारे में अधिक जानकारी के लिए। हालांकि यह विंडोज एनटी के बारे में बात करता है, यह अभी भी विंडोज के बाद के संस्करणों पर लागू होता है।

इस लेख का निष्कर्ष यह सार अच्छी तरह से:

तुम अब लगता है कि आप प्राप्त कर सकते हैं एक लगभग मनमाना परिशुद्धता के साथ सिस्टम का समय यहाँ है, बस एक मामूली चेतावनी हैं: भूल नहीं है विंडोज एनटी जैसे मल्टीटास्किंग सिस्टम की प्रीपेबिलिटी। सर्वोत्तम मामले में, आपको प्राप्त होने वाला टाइम स्टैम्प से प्रदर्शन काउंटर पढ़ने के लिए केवल को पूर्ण समय में पढ़ने के लिए ले जाता है। सबसे खराब मामलों में, समय बीतने वाला समय आसानी से मिलीसेकंड के दसियों के क्रम में हो सकता है।

हालांकि यह हो सकता है दर्शाते हैं कि आप कुछ नहीं के लिए इस सभी के माध्यम से चला गया, तो निश्चिंत रहें कि आप नहीं किया। पर कॉल निष्पादित करने के लिए भी Win32 API GetSystemTimeAsFileTime (या यूनिक्स के तहत gettimeofday) समान स्थितियों के अधीन है, इसलिए आप वास्तव में उससे भी बदतर नहीं हैं। में अधिकांश मामलों में, आपके पास अच्छे परिणाम होंगे। बस को विंडोज एनटी में टिकटों के आधार पर रीयल-टाइम भविष्यवाणी की आवश्यकता नहीं है।

+0

यह "उपयोगकर्ता मोड में" नहीं होना चाहिए, न कि "सॉफ़्टवेयर में", क्योंकि कर्नेल ड्राइवर भी सॉफ़्टवेयर हैं और निश्चित रूप से उप-माइक्रोसॉन्ड समय/विलंबता में सक्षम हैं। –

संबंधित मुद्दे