एक माइक्रोकंट्रोलर से पॉलीफोनिक लगता है?


14

मैं एक पीजो बजर से जुड़ा एक पिन ( एक अलग दर पर ) टॉगल करके मोनोफोनिक ध्वनियां बना सकता हूं ।

मैं पॉलीफोनी बनाने के लिए सॉफ्टवेयर में दो मिश्रित ऑडियो सिग्नल कैसे उत्पन्न कर सकता हूं?

यहाँ वह कोड है जिसका उपयोग मैं एक साधारण धुन बजाने के लिए कर रहा हूँ।

#define F_CPU 8000000UL // 8MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>

// number of timer0 overflows/sec
#define INT_PER_SEC 31250

// Frequencies (in Hz) of notes
#define F_FSH_4 370
#define F_A_4 440
#define F_B_4 494
#define F_E_4 330
#define F_CSH_5 554
#define F_D_5 587
#define F_FSH_5 740
#define F_CSH_4 277
#define F_GSH_4 415

// number of timer0 overflows for notes
#define REST -1 // special case
#define FSH_4 INT_PER_SEC/F_FSH_4
#define A_4 INT_PER_SEC/F_A_4
#define B_4 INT_PER_SEC/F_B_4
#define E_4 INT_PER_SEC/F_E_4
#define CSH_5 INT_PER_SEC/F_CSH_5
#define D_5 INT_PER_SEC/F_D_5
#define FSH_5 INT_PER_SEC/F_FSH_5
#define CSH_4 INT_PER_SEC/F_CSH_4
#define GSH_4 INT_PER_SEC/F_GSH_4

#define SEMIQUAVER_TIME 60  // ms
#define BREATH_TIME 20      // ms

volatile uint32_t intrs = 0;
volatile int32_t curNote = REST;

// TIMER0 overflow
ISR(TIMER0_OVF_vect)
{
    if (curNote == REST)
        intrs = 0;
    else
    {
        intrs++;
        if (intrs >= curNote)
        {
            PORTD ^= _BV(PD4);
            intrs = 0;
        }
    }
}


void play(int32_t note, uint32_t len)
{
    int i;
    curNote = note;
    for (i = 0; i< len; i++)
        _delay_ms(SEMIQUAVER_TIME);
    curNote = REST;
    _delay_ms(BREATH_TIME);
}

int main(void)
{
    /* setup clock divider. Timer0 overflows on counting to 256.
     * 8Mhz / 1 (CS0=1) = 8000000 increments/sec. Overflows every 256, so 31250
     * overflow interrupts/sec */
    TCCR0B |= _BV(CS00);

    // enable overflow interrupts
    TIMSK0 |= _BV(TOIE0);

    // PD4 as output
    DDRD = _BV(PD4);

    TCNT0 = 0;
    intrs = 0;

    curNote = REST;

    // enable interrupts
    sei();

    while (1)
    {
        // Axel F
        play(FSH_4, 2);
        play(REST, 2);
        play(A_4, 3);
        play(FSH_4, 2);
        play(FSH_4, 1);
        play(B_4, 2);
        play(FSH_4, 2);
        play(E_4, 2);
        play(FSH_4, 2);
        play(REST, 2);
        play(CSH_5, 3);
        play(FSH_4, 2);
        play(FSH_4, 1);
        play(D_5, 2);
        play(CSH_5, 2);
        play(A_4, 2);
        play(FSH_4, 2);
        play(CSH_5, 2);
        play(FSH_5, 2);
        play(FSH_4, 1);
        play(E_4, 2);
        play(E_4, 1);
        play(CSH_4, 2);
        play(GSH_4, 2);
        play(FSH_4, 6);
        play(REST, 12);
    }
}

अरे क्या यह चीज़ मानव भाषा का उत्सर्जन कर सकती है? मेरा मतलब है शब्दों की तरह?
रिक_2047 5:27

1
Cantarino पर एक नज़र डालें - code.google.com/p/tinkerit/wiki/Cantarino
Toby Jaffey

@ जॉबी आपके द्वारा दिया गया संसाधन बहुत अच्छा था, लेकिन मैंने डेमो देखा, यह वास्तव में कुछ भी श्रव्य नहीं कह रहा है। अन्य जो आप जानते हैं?
रिक_२०४

डीएसी के बिना नहीं, नहीं।
टॉबी जाफ़ेई

@ जॉबी आपके पास डीएसी के साथ क्या है?
रिक_2047

जवाबों:


8

अच्छी तरह से एक आसान चाल PWM के साथ दो पिनों का उपयोग करना है, और उन्हें स्पीकर के विपरीत पक्षों से बांधना है। फिर प्रत्येक पिन को एक अलग गति से संशोधित करें, और आप एक ही बार में दो नोट चला सकते हैं ... मूल रूप से स्पीकर उन्हें आपके लिए एक साथ मिला रहा है। दो से अधिक नोट और आपको सॉफ्टवेयर में बताए अनुसार करना होगा।


1
यदि आप पीडब्लूएम (वांछित सिग्नल की तुलना में बहुत अधिक आवृत्ति पर स्विच करना) का उपयोग कर रहे हैं, तो आप पहले से ही केवल एक आउटपुट पिन का उपयोग करके कई संकेतों को एक साथ मिला सकते हैं।
14

5

पॉलीफोनी प्राप्त करने का मानक तरीका कुछ निश्चित रुकावट दर (सबसे अधिक बार 8000 हर्ट्ज या 44100 हर्ट्ज) को बाधित करना है, प्रत्येक ध्वनि स्रोत से एक "उच्च" (+1) या "कम" (-1) (या कुछ मध्यवर्ती) प्राप्त करें। , कुल प्राप्त करने के लिए सभी संख्याओं को जोड़ें, फिर उस कुल संख्या को DAC से बाहर भेजें।

जैसा कि अन्य लोगों ने यहां कहा है, थोड़ी चतुराई के साथ पीडब्ल्यूएम एक डीएसी की जगह ले सकता है।

"माइक्रोकंट्रोलर polyphony" पेज कुछ और जानकारी और टिप्स देता है।


3

मुझे लगता है कि यह अच्छा पुराने छोटे पीसी डॉस गेम रत्न ने पीसी स्पीकर के माध्यम से वास्तविक पॉलीफोनिक ध्वनि का उपयोग किया: डिगर

मुझे नहीं पता कि उन्होंने इसे कैसे बनाया है, लेकिन आप साइट से सी स्रोत कोड डाउनलोड कर सकते हैं।


मैं अभी भी अपने सिर में धुन सुन सकता हूँ
टोबी जाफ़े

2

यह मदद कर सकता है -> सरल PWM DAC


Arduino को नोटों को खेलने के लिए अतुल्य रूप से प्राप्त करने के लिए आपको मिडी के समान एक प्रणाली का उपयोग करने की आवश्यकता होगी - नोट पर और नोट बंद करने के लिए अलग-अलग कमांड के साथ, टोन लाइब्रेरी में निर्मित यह करता है लेकिन पॉलीफोनी नहीं करता है - लेकिन नवीनतम संस्करण की तरह यह करता है - code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation
जिम

2

आप बस दो वर्ग तरंगों को जोड़ सकते हैं, और स्पीकर को "एनालॉग" सिग्नल को आउटपुट करने के लिए तेज pwm का उपयोग कर सकते हैं।

अगर आप गेम साउंड, क्विक और डर्टी पसंद करते हैं तो यहां एक और अलग तरीका है:

https://gitweb.bl0rg.net/cgi-bin/gitweb.cgi?p=arduinisten.git;a=blob;f=projekte/soundz/arpeggio/arpeggio.pde;h=6ceb64a57916c094e87e5983c07b5dd1b4623083;hb=HEAD


2

यदि आप अपने स्पीकर ईवेंट के लिए सॉफ़्टवेयर का उपयोग कर रहे हैं, तो सबसे आसान तरीका संभवतः दो स्वतंत्र डेटा स्ट्रीम उत्पन्न करना और उनके बीच वैकल्पिक करना है। यह दृष्टिकोण बहुत अच्छी तरह से काम कर सकता है कि स्पीकर आउटपुट I / O पिन या DAC द्वारा नियंत्रित किया जाता है या नहीं। उदाहरण के लिए:

int चयनकर्ता;
uint16_t चरण [8], freq [8];

शून्य व्यवधान (शून्य) { चयनकर्ता ++; चयनकर्ता और = 7; चरण [चयनकर्ता] + freq [चयनकर्ता]; DAC_OUT = sinewave [चरण [चयनकर्ता] >> 8]; }

उपरोक्त आवश्यक दृष्टिकोण है जिसका उपयोग मैंने 1996 में PIC-आधारित संगीत बॉक्स में किया था (C के बजाय असेंबली कोड का उपयोग करके)। ध्यान दें कि बाधित दर को प्रभावी नमूना दर का 8 गुना होना चाहिए, लेकिन प्रत्येक रुकावट को केवल एक आवाज के लिए प्रसंस्करण करना होगा। ध्यान दें कि यदि आउटपुट फ़िल्टरिंग अच्छा है, तो यह दृष्टिकोण प्रभावी डीएसी रिज़ॉल्यूशन के 3 बिट्स अधिक होगा, जो नमूनों को संख्यात्मक रूप से जोड़ देगा और फिर उन्हें आउटपुट करेगा, लेकिन यह नमूना दर पर बहुत अधिक शोर उत्पन्न करेगा और इसके गुणन में कई गुना अधिक होगा। फ़िल्टरिंग इस प्रकार से भी अधिक महत्वपूर्ण है क्योंकि यह अन्यथा होगा।


1

वे पुराने गेम सिस्टम और " पीसी स्पीकर " के दिनों में ऐसा करते थे, लेकिन मुझे नहीं पता कि कैसे।

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

दूसरा विचार: क्या आप पीडब्लूएम-शैली के दोलन और आउटपुट एनालॉग सिग्नल की आवृत्ति बढ़ा सकते हैं ?


2
मुझे याद है कि एक एनईएस एमुलेटर पर एक लंबे समय से पहले देख रहा था और मेरा मानना ​​है कि वे प्रोग्रामेबल फ्रीक्वेंसी के साथ तीन तरंगों का उपयोग करते थे। दो वर्ग तरंगें और एक त्रिकोण तरंग।
mjh2007

... और एक शोर स्रोत, जाहिरा तौर पर। en.wikipedia.org/wiki/NES_Sound_Format
एंडोलिथ

1

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

एकमात्र गोचर्स यह है कि आपको एक वास्तविक स्पीकर की आवश्यकता है (मुझे लगता है कि एक पीजो इतनी तेजी से चलती है कि यह पूरी तरह से पूर्ण और बहुत तेज़ी से पूर्ण तक पहुंचती है) और आपको थोड़ा तेज़ी से टॉगल करने में सक्षम होने की आवश्यकता है। मैंने कुछ प्रयोग किए और लगभग 5MHz की अधिकतम गति के साथ आया , जो 11,025 हर्ट्ज ऑडियो सिग्नल के लिए पर्याप्त होना चाहिए (शायद सबसे अच्छी गुणवत्ता जिसे आप प्राप्त कर सकते हैं।)

बेशक 11025 हर्ट्ज @ 8-बिट 11 किलोबाइट / सेकंड है, जो एक सीरियल पोर्ट की गति से बहुत तेज है। यह केवल फ्लैश में संग्रहीत किए जाने वाले दूसरे या दो मूल्य के ऑडियो की अनुमति देता है, इसलिए आप मक्खी पर उत्पन्न ऑडियो खेलने के लिए बहुत सीमित होते हैं, बशर्ते कि स्पीकर को मोड़ने के लिए पर्याप्त खाली सीपीयू समय निकल जाए!

इसे प्राप्त करने के लिए कुछ अन्य तरीके भी हैं, और ऐसा लगता है कि ऊपर वर्णित विधि के Arduino के लिए पहले से ही एक कार्यान्वयन है।


2
पीडब्लूएम को सुचारू करने के लिए आप स्पीकर से पहले एक फिल्टर का उपयोग कर सकते हैं, भले ही स्पीकर खुद कितना तेज चलता हो।
एंडोलिथ


1

एक पल के लिए ध्वनि ए चलायें, जैसे कि शायद 50 एमएस फिर ध्वनि बी और पीछे और पीछे स्विच करें। विचार यह है कि कान बताए जाने की तुलना में तेजी से स्विच करें और यह एक ही समय में बजने जैसा लगेगा।


1

मेरा मानना ​​है कि Arduino के लिए एक टोन लाइब्रेरी है जो दो टोन करती है। आपको उस AVR चिप को कोड को अनुकूलित करने में सक्षम होना चाहिए जिसका आप उपयोग कर रहे हैं। वहाँ भी arduino.cc पर उत्कृष्ट तरंग उत्पादन धागे के एक जोड़े हैं

यदि आप एक DAC जोड़ने का निर्णय लेते हैं तो मेरे पास http://wiblocks.luciani.org/docs/app-notes/nb1a-nco.html चार स्वतंत्र आउटपुट चैनलों पर एक संख्यात्मक नियंत्रित थरथरानवाला उदाहरण है। क्वाड DAC और संदर्भ केवल $ 2 या तो के बारे में है।


0

यहाँ एक ही समय पर 2 धुन बजाने के लिए मेरा कोड है। क्षमा करें, आपको एक्सेस पाने के लिए AVR फ्रीक में पंजीकरण करना होगा।


4
अगर आप यहाँ कोड पोस्ट करते हैं, तो मैं आपको एक
उत्थान दूंगा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.