मैं आईफोन पर एक साधारण ऑडियो अनुक्रमक प्रोग्राम करना चाहता हूं लेकिन मुझे सटीक समय नहीं मिल रहा है। आखिरी दिनों में मैंने ऑडियो पर सभी संभावित ऑडियो तकनीकों का प्रयास किया, ऑडियो सर्विसेजप्लेसिस्टम साउंड और AVAudioPlayer और OpenQ से ऑडियोक्यूज़ से शुरू किया।आईफोन पर रीयल-टाइम सटीक ऑडियो अनुक्रमक प्रोग्राम कैसे करें?
मेरे आखिरी प्रयास में मैंने कोकोसडेन्सियन ध्वनि इंजन की कोशिश की जो ओपनएएल का उपयोग करता है और कई बफर में ध्वनि लोड करने की अनुमति देता है और फिर जब चाहें उन्हें चलाता है। यहाँ बुनियादी कोड है:
init:
int channelGroups[1];
channelGroups[0] = 8;
soundEngine = [[CDSoundEngine alloc] init:channelGroups channelGroupTotal:1];
int i=0;
for(NSString *soundName in [NSArray arrayWithObjects:@"base1", @"snare1", @"hihat1", @"dit", @"snare", nil])
{
[soundEngine loadBuffer:i fileName:soundName fileType:@"wav"];
i++;
}
[NSTimer scheduledTimerWithTimeInterval:0.14 target:self selector:@selector(drumLoop:) userInfo:nil repeats:YES];
initialisation मैं ध्वनि इंजन बनाने में, विभिन्न बफ़र्स के लिए कुछ ध्वनियों लोड और फिर NSTimer साथ अनुक्रमक पाश की स्थापना।
ऑडियो पाश:
- (void)drumLoop:(NSTimer *)timer
{
for(int track=0; track<4; track++)
{
unsigned char note=pattern[track][step];
if(note)
[soundEngine playSound:note-1 channelGroupId:0 pitch:1.0f pan:.5 gain:1.0 loop:NO];
}
if(++step>=16)
step=0;
}
यह Thats और यह एकदम सही ढंग से काम करता है, लेकिन समय अस्थिर और अस्थिर है। जैसे ही कुछ और होता है (i.g. एक दृश्य में ड्राइंग) यह सिंक से बाहर चला जाता है।
जैसा कि मैं ध्वनि इंजन और ओपनएएल को समझता हूं, बफर लोड होते हैं (इनिट कोड में) और फिर alSourcePlay(source);
के साथ तुरंत शुरू करने के लिए तैयार हैं - तो समस्या एनएसटीमर के साथ हो सकती है?
अब ऐपस्टोर में दर्जनों ध्वनि अनुक्रमक ऐप्स हैं और उनके पास सटीक समय है। आई जी ज़ूमिंग और ड्राइंग होने पर "इड्रम" में 180 बीपीएम में भी एकदम सही स्थिर धड़कन है। तो एक समाधान होना चाहिए।
क्या किसी के पास कोई विचार है?
अग्रिम में किसी भी मदद के लिए धन्यवाद!
सादर,
Walchy
अपने जवाब के लिए धन्यवाद। यह मुझे एक कदम आगे लाया लेकिन दुर्भाग्य से उद्देश्य के लिए नहीं। यहां मैंने किया है:
nextBeat=[[NSDate alloc] initWithTimeIntervalSinceNow:0.1];
[NSThread detachNewThreadSelector:@selector(drumLoop:) toTarget:self withObject:nil];
प्रारंभ में मैं अगली बीट के लिए समय स्टोर करता हूं और एक नया धागा बना देता हूं।
- (void)drumLoop:(id)info
{
[NSThread setThreadPriority:1.0];
while(1)
{
for(int track=0; track<4; track++)
{
unsigned char note=pattern[track][step];
if(note)
[soundEngine playSound:note-1 channelGroupId:0 pitch:1.0f pan:.5 gain:1.0 loop:NO];
}
if(++step>=16)
step=0;
NSDate *newNextBeat=[[NSDate alloc] initWithTimeInterval:0.1 sinceDate:nextBeat];
[nextBeat release];
nextBeat=newNextBeat;
[NSThread sleepUntilDate:nextBeat];
}
}
अनुक्रम लूप में मैंने थ्रेड प्राथमिकता को जितना संभव हो उतना उच्च सेट किया है और अनंत लूप में जाना है। ध्वनियों को चलाने के बाद मैं अगली बीट के लिए अगले पूर्ण समय की गणना करता हूं और थ्रेड को इस समय तक सोने के लिए भेजता हूं।
फिर से यह काम करता है और यह एनएसटीएचड के बिना मेरी कोशिशों की तुलना में अधिक स्थिर काम करता है लेकिन अगर कुछ और होता है, खासकर जीयूआई सामान यह अभी भी कमजोर है।
क्या आईफोन पर एनएसटीएचएड के साथ वास्तविक समय प्रतिक्रिया प्राप्त करने का कोई तरीका है?
सादर,
Walchy
मुझे लगता है कि @Walchy दोपहर के भोजन के लिए बाहर है ... आश्चर्य जो जिस तरह से उसने अंततः इसे करने का फैसला किया? –
दुर्भाग्य से मैं नमूना कोड पोस्ट नहीं कर सकता, लेकिन ऐप स्टोर में प्लेबैक ऐप के लिए, हम फ़ाइलों से पढ़े गए ऑडियो डेटा प्रदान करने के लिए कॉलबैक का उपयोग करते हैं। प्रत्येक फ़ाइल में एक ही ऑडियो विशेषताएं होती हैं, इसलिए सटीक समय प्रदान करने के लिए, हम ऑडियो फ़ाइल डेटा में उस नमूना बिंदु पर कूदते हैं।यह बहुत सटीक है (ऐप डाउनलोड करें और दिन का मुफ्त खेल प्राप्त करें)। हम लूप सेक्शन कर सकते हैं और फ़ाइल में सेक्शन पर जा सकते हैं, सभी एक बार में 20+ ट्रैक खेलते समय (अभी तक ट्रैक सीमा नहीं मारा है)। –