
जैसा कि आप जानते हैं, टेलीफोनी में वॉइस ट्रांसमिशन शामिल है। वॉयस ट्रांसमिशन के लिए किसी को 20Hz-20kHz की पूर्ण बैंडविड्थ की आवश्यकता नहीं है, 3.5kHz तक एक स्पष्ट अंतर और पहचानने योग्य आवाज के लिए पर्याप्त है। अधिक सटीक होने के लिए, टेलीफोनी में प्रयुक्त
भाषण आवृत्ति बैंड 300 से 3400 हर्ट्ज तक है। एक आम चैनल में संपीड़ित करते समय, सटीक आवंटन के लिए, किनारों के साथ सुरक्षात्मक आवृत्ति अंतराल की आवश्यकता होती है, क्योंकि बैंडविड्थ 4 kHz है। डिजिटाइज़ करने पर यह 8kHz हो जाता है। अब, संचार चैनलों की मोटाई के विकास के कारण, समान स्काइप और अन्य, "बढ़ी हुई" गुणवत्ता का घमंड करते हुए, 16kHz, या 32kHz का उपयोग करते हैं, जो कि, हालांकि, सामान्य बातचीत में वास्तव में श्रव्य नहीं है (लेकिन यह गिरावट के मामले में बहुत स्पष्ट रूप से दिखाई देता है। संचार चैनल की गुणवत्ता, लेकिन जब इसने मार्केटर्स को चिंतित किया)।
इसलिए, लगभग सभी ध्वनि फाइलें जो टेलीफोनी में उपयोग की जाती हैं, उन्हें 8kHz डिजिटलीकरण के साथ दर्ज किया जाता है। बड़े प्रवाह के प्रसंस्करण को गति देने के लिए, उपयोग की जाने वाली संपीड़न विधियाँ सरल और वांछित परिणाम पर लागू होती हैं, जब वांछित भाषण संपीड़न पर लागू होती हैं। यह एक साधारण डिजिटलीकरण (
पीसीएम ), सरल डेल्टा कोडेक्स (एडीपीसीएम, जी
711 ), या मुश्किल कोडेक्स (
जीएसएम 06.10 ) है। टेलीफोनी सिस्टम के लिए ये प्रारूप "मूल" हैं - तारांकन चिह्न, फ़्रेस्विच (और शायद अन्य भी)। इन प्रारूपों में, सिस्टम द्वारा लोगों के लिए खेलने के लिए डेटा तैयार किया जाता है, और सिस्टम के समान प्रारूपों में रिकॉर्ड किए जा सकते हैं।
हालाँकि, अब वेब ग्रह के चारों ओर तेजी से विस्तार कर रहा है, और लोग वेब पर वार्तालाप, अभिवादन आदि की रिकॉर्डिंग सुनने में सक्षम होना चाहते हैं, जहां एमपी 3 "मूल" प्रारूप बन गया है ...
नतीजतन, दुर्लभ "संग्रह को सुनें" फ़ंक्शन के लिए, भोले समाधान को टेलीफोन प्रारूप से रिकॉर्डिंग को एमपी 3 में ट्रांसकोड करने के लिए सर्वर को कॉन्फ़िगर करना है।
सब कुछ ठीक हो जाएगा, लेकिन:
- एमपी में रिकॉर्डिंग या तो बड़े या बदतर हैं;
- एमपी में ट्रांसकोडिंग के लिए सर्वर सीपीयू पर लोड की आवश्यकता होती है;
- ट्रांसकोडिंग तथ्य के बाद होता है, और मक्खी पर नहीं (हालांकि इसके लिए भी एक इलाज है);
- ट्रांसकोड की गई फ़ाइलें अनिवार्य रूप से केवल क्लाइंट के लिए आवश्यक होती हैं।
इस अपमान को देखकर, एक इंजीनियर की आत्मा बीमार हो गई और अच्छा प्रदर्शन करने की मांग करने लगी। और यह "इसे बुरी तरह से करने के लिए नहीं है, लेकिन तब यह कैसे था", अर्थात्, यह अच्छा और सीधा है: वास्तव में, टेलीफोनी में उपयोग किए जाने वाले कोडक अच्छे परिणामों के लिए डिज़ाइन किए गए हैं, और यह बहुत सस्ता है। तो एक महंगा एमपी 3 एन्कोडिंग ऑपरेशन क्यों करें, फिर क्लाइंट पर एक महंगा एमपी 3 डिकोडिंग ऑपरेशन करना है क्योंकि यह डिकोडर पहले से ही है? चलो ग्राहक पर यह सबसे सरल डिकोडर बनाते हैं, और यह बात है!
मैं इन तैयार डिकोडरों की कमी से विशेष रूप से आश्चर्यचकित था। यह है कि
WavPlayer का जन्म कैसे हुआ: टेलीफोनी फ़ाइलों के लिए एक फ्लैश प्लेयर।
वह क्या कर सकता है:
- एक रिकॉर्ड पर कूदने के लिए एक पट्टी के साथ जीयूआई, इसके बिना जीयूआई, आमतौर पर कोई यूआई नहीं
- JS इंटरफ़ेस पर संपूर्ण इंटरफ़ेस को प्रबंधित और रेंडर करने के लिए API
- कोडेक समर्थन: PCM, G.711u / a, GSM 06.10, IMA ADPCM
- प्रारूपों के लिए समर्थन: एयू, डब्ल्यूएवी, कई मानक रॉ
और हाल ही में, उपयोगकर्ताओं ने मानक एमपी 3 प्लेयर के लिए परदे के पीछे जोड़ दिए हैं ताकि केवल WavPlayer का उपयोग देशी और ट्रांसकोड किए गए अभिलेखागार दोनों को खेलने के लिए किया जा सके। (शुरू में, मैंने ऐसा नहीं किया था, यह मानते हुए कि किसी भी फ्लैश-एमपी 3 प्लेयर, एचटीएमएल 5 का उपयोग करने के लिए जेएस की चिंता थी, या वेवपलेयर का उपयोग करना था)।
जो कोई भी प्रत्येक कोडेक्स और प्रारूप के विवरण को पढ़ता है, वह समझ जाएगा कि खिलाड़ी ट्रैफ़िक जाम जितना सरल है। लेकिन अगर ऐसा होता, तो यह लंबे समय तक अस्तित्व में होता ... इसलिए, मैं संक्षेप में इसके निर्माण की कहानी बताऊंगा।
प्रारंभ में, केवल एक फ्लैश में ध्वनियों को बजाना चाहिए था: एमपी 3 आवेषण को बजाना। वह सब है। और कुछ नहीं। 10 वें संस्करण से शुरू होकर, नमूनाडैटा इवेंट फ्लैश.मीडिया.ाउंड के इंटरफेस में दिखाई दिया है, जो उत्पन्न ध्वनि को उत्पन्न करने और खेलने की अनुमति देता है। लेकिन एक फ्लैश के रूप में, वह इसे केवल अपने तरीके से करता है: केवल 44kHz, केवल स्टीरियो, केवल 32 बिट फ़्लोटिंग पॉइंट नंबर।
और हमारे पास 8kHz / 16kHz पूर्णांक है। अगर हम सिर्फ सोर्स डेटा लेते हैं और जैसा है वैसा ही देते हैं, तो हमें खराब पढ़ने लायक और बहुत ज्यादा फ्रीक्वेंसी मिलती है। निष्कर्ष? यह आवश्यक है कि हमारे पास जो नमूने हैं - उन्हें दूसरे शब्दों में करें।
जब पुन: नमूनाकरण किया जाता है, तो यह समझना महत्वपूर्ण है कि आवृत्ति के एक सरल दोहरीकरण के साथ भी, आप केवल दो नमूनों के बीच "औसत" संख्या नहीं ले सकते हैं - परिणामस्वरूप ध्वनि उच्च आवृत्तियों पर बहुत सीटी बजाएगी, क्योंकि एक चिकनी साइनसॉइड के बजाय हमें एक आरा मिलता है। मूल चिकनी ध्वनि (दूसरी व्युत्पन्न को कम करने के साथ) को पुनर्स्थापित करके, और वांछित आवृत्ति पर इसे फिर से डिजिटाइज़ करके सही पुनरुत्पादन प्राप्त किया जाता है। इस तरह हम सही नमूना दर के साथ सही चिकनी ध्वनि प्राप्त करते हैं।
चूंकि, मैं निश्चित रूप से, सिद्धांत को जानता हूं, लेकिन व्यवहार में मैं बहुत आलसी हूं, और कार्य "बहुत आसानी से रिकॉर्ड" खेलना था, जल्दी से हल करना आवश्यक था। फ्लैश मैं नहीं जानता, और लिनक्स के तहत एक काम करने वाली मशीन। मैंने फ्लैश संकलक के आकार को देखा - सौ मीटर के लिए, यह इतना टूट गया कि मैंने एक फ्लैश पर जल्दी और आसानी से एक विकल्प खोजने का फैसला किया। क्विक
गूग्लिंग ने एक बढ़िया विकल्प दिया -
हैएक्स । एक सरल सी / जावा-जैसी भाषा जिसे कई लक्ष्य प्लेटफार्मों में अनुवादित किया जा सकता है, जिसमें मुझे एक की आवश्यकता है - फ्लैश। उसे ले जाया गया।
सामान्य तौर पर,
पहले काम करने वाले लेआउट को जल्दबाजी में तूल दिया गया था:
एक फॉग प्रोजेक्ट था जिसमें ओग फाइलों को मैन्युअल रूप से डिकोड किया गया था। वहां से, ऑडियोसिंक लिया गया, जो पुल के बजाय पुश इंटरफ़ेस को लागू करता है: जिस बफर को हम लिखते हैं, और जब फ्लैश डेटा का अगला टुकड़ा चाहता है, तो ऑडियोसिंक बफर से इसे भेजता है। सबसे इष्टतम और सुंदर कार्यान्वयन नहीं, लेकिन तैयार-निर्मित। एक Resampler के रूप में, Lanczos resampler कार्यान्वयन (उच्चतम गुणवत्ता, Sinc कार्यों के आधार पर) OpenJDK से माथे लिया गया था। कोड सबसे इष्टतम नहीं है (बाद में इसे एक शुद्ध एक्शन स्क्रिप्ट पर लागू किया गया था - यह लगभग 4 गुना तेजी लाने में सक्षम था), लेकिन यह काम करता है (और मुझे कुछ और नहीं चाहिए)।
इंटरफ़ेस सरल है: जब यह होता है तो एक त्रिकोण बनाएं। क्लिक करने पर, प्ले () लॉन्च होता है और एक वर्ग तैयार होता है। क्लिक करके, दो ऊर्ध्वाधर स्टिक खींची जाती हैं।
G711 को डिकोड करने के लिए, कोड को Sox से लिया गया था, PCM के लिए कोड ने अपने आप ही जन्म दिया।
और, ज़ाहिर है, टायर के इस बैरल में ओओपी चम्मच: फ़ाइल और डिकोडर इंटरफेस, जो मुख्य खिलाड़ी को एक विशिष्ट भिन्नता से अमूर्त करने की अनुमति देता है। सच है, इंटरफेस आवश्यकता से बाहर पैदा हुए थे, और व्यवस्थित रूप से नहीं, लेकिन यह कब अलग था? फ़ाइल इस तरह से काम करती है - फ़ाइल का इनपुट डेटा पढ़ा जाता है, और डिकोडर को पुश () विधि के माध्यम से भेज दिया जाता है। जैसे ही सभी हेडर पढ़े जाते हैं, फ़ाइल उपयुक्त प्रारूप के एक डिकोडर के अंदर खुद को बनाता है, और इसमें ऑडियो डेटा को रटना शुरू कर देगा। तैयार () पद्धति सही होने लगती है, और उसी क्षण से, अन्य सभी स्ट्रीम मेटाडेटा विधियां भी मान्य हो जाती हैं, और आप getSamples () अनुरोध का उपयोग करके ऑडियो स्ट्रीम डेटा पढ़ सकते हैं, जो नमूने वापस कर देगा। उपलब्ध () नमूने।
डिकोडर का संचालन भी सरल है - यह बाइट्स में नमूना के आकार को संचारित करता है ताकि डिकोडर को खिलाने के लिए फ़ाइल को आवश्यक पैकेट में काटा जा सके। डिकोडर क्रमिक रूप से बफर डेटा को एक नमूने (एक हस्ताक्षरित फ्लोट में) में परिवर्तित करने के लिए है।
मुख्य समस्या जो उत्पन्न होती है वह है नमूना का उचित खिलाना। आपको याद दिला दूं कि रेज़मप्लेर वर्चुअल डबल कन्वर्सेशन के सिद्धांत पर काम करता है - इनपुट सैंपल फ्रीक्वेंसी फ्रीक्वेंसी के साथ इनपुट डेटा के आधार पर, एक स्मूथ सिग्नल रिस्टोर होता है, जो आउटपुट फ्रिक्वेंसी पर री-डिजिटाइज़ होता है। सिग्नल को पुनर्स्थापित करने के लिए सिग्नल की हमेशा आवश्यकता होती है; इसलिए, पहले आपको डिकोडर को वांछित लंबाई की चुप्पी के साथ खिलाने की आवश्यकता है, आरंभीकरण के लिए। और इस चुप्पी को पहले जवाब से बाहर फेंक दें - फिर हम शुरुआत से ही सही रेज़म्पलिंग प्राप्त करेंगे। उसी तरह, हमारे डेटा के समाप्त होने के बाद, सभी बहाल जानकारी प्राप्त करने के लिए - फिर से शुरू करने वाले को चुप्पी के बाद खिलाया जाना चाहिए।
और इस तरह के एक मैकर के साथ सैनिकों की हमारी कंपनी वास्तव में सही रूप में 44 kHz पर कितना डेटा की आवश्यकता है उत्पन्न करती है।
बेस प्लेयर ने काम करना शुरू करने के बाद, इसे थोड़ा कंघी करना शुरू किया: सबसे पहले, अधिक जटिल कोडेक्स, विशेष रूप से जीएसएम के लिए समर्थन। यह तुरंत स्पष्ट हो गया कि सभी को नमूना-दर-बिट डिकोड नहीं किया गया था, यहां बैच प्रोसेसिंग की आवश्यकता थी - इसलिए डिकोडर इंटरफ़ेस को इनपुट सरणी + ऑफसेट, आउटपुट सरणी + ऑफसेट के लिए फिर से तैयार किया गया था, जो आउटपुट के लिए कितने नमूने डाले गए थे। रॉ फ़ाइलों का समर्थन करने के लिए, अधिकांश कोड सार्वभौमिक है, इसे एक अलग सामान्य वर्ग में स्थानांतरित कर दिया गया, ताकि प्रारंभिक में न्यूनतम - केवल आवश्यक पैरामीटर ओवरराइड कर सकें। जीएसएम डिकोडर को हमेशा की तरह लिया गया था जहां यह पाया गया था, बस वांछित सिंटैक्स में जल्दी से बदल दिया गया था। अजीब तरह से पर्याप्त - यह सब एक धमाके के साथ काम किया।
उसी समय, खिलाड़ी नियंत्रण इंटरफ़ेस को जेएस कोड + लोड, प्ले, पॉज़ इवेंट से जारी किया गया था, जिससे आप ब्राउज़र में खिलाड़ी की स्थिति को आकर्षित कर सकते हैं। परिणामी उत्पाद को उत्पादन में सावन कहा जाने लगा। जब उन्होंने परीक्षण करना शुरू किया, तो कुछ समस्याएं सामने आईं, विशेष रूप से गहराई से आईई में, जिसे टुकड़ों में भरी हुई फ़ाइल 8k या 4k लगती है ... सामान्य तौर पर, एक टन की घटना उत्पन्न हुई थी, मुझे उनकी पीढ़ी की आवृत्ति में कटौती करनी पड़ी।
दुर्भाग्य से, यह जल्दी से स्पष्ट हो गया कि किसी को भी जेएस पर एक इंटरफ़ेस बनाने की इच्छा नहीं थी। फिर निर्णय जल्दी और गुआ द्वारा अंदर फेंक दिया गया था। खिलाड़ी ने आंतरिक ईवेंट बनाना शुरू कर दिया, और WavPlayerGui बनाया गया। उनका मिनी वारिस पहले की तरह बना हुआ है - सभी बटन; प्लस, पूर्ण बनाया गया था, जिसमें बाईं ओर एक ही बटन है, और दाईं ओर एक प्रगति पट्टी है जिसमें लंबाई, भरी हुई मात्रा और वर्तमान स्थिति दिखाई दे रही है। खैर, यह है कि टुकड़ों के थोड़ा अधिक वर्ग, जिनमें से आकार घटनाओं के जवाब में बदल गए।
जैसे ही यह दिखाई दिया, यह स्पष्ट हो गया कि सामान्य तौर पर इसे भी टिक करना चाहिए। वैसे भी, रिकॉर्डिंग सुनना केवल पूरी तरह से बेवकूफ़ है जब आपको 15 मिनट से 3 मिनट सुनने की आवश्यकता होती है ... आपको तलाश करना होगा ()। इस मामले में तलाश () लागू करना सबसे मुश्किल काम था: चूंकि हम स्रोत फ़ाइल को एक मनमाने स्थिति से डाउनलोड नहीं कर सकते (हम सर्वर से रेंज समर्थन की गारंटी नहीं दे सकते हैं, और यह एक फ्लैश में ऐसा करना इतना आसान नहीं है), मुझे तलाश की संभावनाएं सीमित करनी थीं ( ) 'लेकिन केवल लोड किए गए हिस्से के भीतर। लेकिन इस मामले में भी, हम 44 kHz (मेमोरी, व्हाइन, सॉरी) के लिए ट्रांसकोड किए गए डेटा की पूरी मात्रा को स्टोर नहीं करते हैं, इसलिए यदि पुनरावृत्ति के लिए आवश्यक है, तो निम्न होता है:
- अगर हम (44) तैयार 44kHz डेटा की सीमा के भीतर जाते हैं, तो हम जाँच करते हैं - यदि हां, तो हम केवल तैयार डेटा का उपयोग करके एक सिक बनाते हैं।
- यदि बाहर है, तो उस नमूने की तलाश करें जिससे मूल धारा के संदर्भ में प्लेबैक शुरू होना चाहिए
- पुनः आरंभिक मौन अनुनादक,
- इनपुट स्ट्रीम वांछित स्थिति में बदल जाती है,
- प्लेबैक शुरू करें।
फिर उन लोगों में से कुछ कॉस्मेटिक संशोधन थे जिन्होंने इसे जनता में उपयोग करना शुरू कर दिया, और फिर से एक चुनौती थी - क्या आईएमए एडीपीसीएम समर्थन करना संभव है। प्रारूप बल्कि घृणित है, सार्वभौमिक होने के दृष्टिकोण से, यह निकला: डेटा चैनल द्वारा चैनल नहीं है, लेकिन एक ही स्थान पर मिलाया जाता है, इसलिए मुझे डिकोड किए गए चैनल को डिकोडर में भी संचारित करना पड़ा; उसी समय, मुझे अन्य सभी कोडेक्स के लिए थोड़ी सार्वभौमिकता बनानी पड़ी, क्योंकि आउटपुट डेटा की मात्रा, अन्य सभी के लिए इनपुट के आधार पर, निश्चित और सरल है; और यहाँ ... सामान्य तौर पर, यह निर्भर करता है - एक स्पष्ट कहानी की आवश्यकता होती है, और डिकोडिंग को किसी भी तरह से एक मनमाने स्थान से शुरू नहीं किया जा सकता है। तदनुसार, तलाश () के लिए, फ़ंक्शन इस तरह काम करता है:
- हम जांचते हैं कि क्या तैयार (44) तैयार 44kHz डेटा की सीमा के भीतर है - यदि हां, तो हम सिर्फ तैयार डेटा का उपयोग करके एक सिक बनाते हैं
- यदि बाहर है, तो उस नमूने की तलाश करें जिससे मूल धारा के संदर्भ में प्लेबैक शुरू होना चाहिए
- एक नमूने की तलाश में जहां आप डिकोडिंग शुरू कर सकते हैं
- पुनः आरंभिक मौन अनुनादक,
- इनपुट स्ट्रीम को डिकोडिंग की स्थिति में बदल दिया जाता है
- डिकोडिंग करना और उस स्थिति में फेंकना जिसके साथ खेलना शुरू करना है
- प्लेबैक शुरू करें।
सामान्य तौर पर, अजीब तरह से, यह भी काम करता है। और फिलहाल, यह सभी के लिए उपयोग के लिए उपलब्ध है: यह ठीक उसी तरह से काम करता है, जिस तरह से इसकी आवश्यकता है।
एक पूर्ण रोमांच के लिए, यह केवल किसी भी तरह जेएस पर अंतिम इंटरफ़ेस बनाने के लिए बना हुआ है जिसे मैंने माना कि हमारे वेब डेवलपर्स करेंगे; एकीकरण का एक सरल और समझने योग्य उदाहरण बनाने के लिए, जिसे आप अपनी साइट में कॉपी-पेस्ट डाल सकते हैं, क्योंकि अक्सर यह एकीकरण समस्या सिस्टम प्रशासक के कंधों पर पड़ती है, न कि प्रोग्रामर ... इसलिए, जारी रखने के लिए।
गिथब पर परियोजना |
ऑनलाइन डेमो।