Как отправить звук на динамик

Если бы я запрограммировал микроконтроллер (ATMega128) для воспроизведения реалтона с динамиком, как бы я это сделал?

Нужно ли использовать цифровой / аналоговый преобразователь для отправки различных значений амплитуды, или этого достаточно при изменении частоты? В любом случае, как бы я кодировал значения частоты и амплитуды, которые должен получить динамик? Нужно ли какое-то частотное мультиплексирование? Я не говорю просто о том, чтобы из динамика издавать простые звуки, например одну ноту, а затем другую. Я хочу сыграть настоящую песню со всеми инструментами, вокалом и т. Д.

8 ответов

Предполагая, что у вас есть несжатый 8-битный моноволновой файл 22,1 кГц:

1) раздеть заголовок
2) Каждые 1/22 100-я секунда:
2.1) Читать 8 бит
2.2) Используйте ЦАП, чтобы преобразовать его в диапазон напряжения динамика
2.3) Отправить его спикеру

Это даст вам качество звука [22,1 кГц /8 бит / моно] и простой способ воспроизведения реалистичных сэмплов.

Все эти частотные составляющие необходимы для разных синтезаторов. Динамик ПК, например, фактически один бит. Чтобы иметь разные амплитуды (чем "нет" и "максимум"), могут потребоваться некоторые приемы, такие как широтно-импульсная модуляция (как вы сказали, смещение частот вокруг, чтобы диафрагма говорящего эффективно имела больше позиций, чем две).

Но вам не нужно беспокоиться об этом. Все, что вам нужно сделать, это выпустить около 22 100 или 44 200 звуковых сэмплов в секунду в динамик, скажем, 8 или 16 бит на сэмпл для обозначения амплитуды.

Я пробовал что-то подобное. Во-первых, у вас НЕ будет достаточно памяти на микроконтроллере для хранения настоящей песни. Вам понадобится внешняя память, чтобы справиться с этим. Это означает использование интерфейса SPI для внешней флэш-памяти, EEPROM или чего-то еще. SD также хорош - я считаю, что это интерфейс в стиле SPI. Существует код для ATMegas для взаимодействия с SD-картами.

Второе важное дело - получить данные в правильном формате. Я бы сделал это, используя широтно-импульсную модуляцию (ШИМ) для создания различных уровней напряжения. Я полагаю, что у вас есть 16-битный ШИМ на этом микроконтроллере, так что вы можете иметь 16-битную точность звука. Если у вас есть проблемы с пространством, вы можете вместо этого использовать 8-битный ШИМ. Таким образом, ваши звуковые данные должны быть в 8 или 16-битном PCM с 0x0000, являющимся самым низким значением, и 0xFFFF, являющимся самым высоким. Если вам нужна высококачественная музыка, вам потребуется частота дискретизации 44 кГц, чтобы получить все хорошие гармоники и тому подобное. Я считаю, что это PCM - так же, как он называется на ПК.

Итак, у вас будут все эти значения - для пяти минут музыки у вас будет 5 * 60 * 44000 = 13 200 000 16-битных значений, что составляет 211 200 000 бит (211 мегабит, 26,4 мегабайт). Это ваши требования к хранению необработанных данных. Возможен MP3 - для этого есть внешние чипы, но у вас все равно будут большие требования к пространству.

Таким образом, каждую 1/44000 секунды вы будете обновлять значение в ШИМ-регистре. Ваша частота ШИМ должна быть выше на 4 или 5 - то есть 5 циклов ШИМ на значение.

Это ваш общий алгоритм - обновите значения в ШИМ-регистре и оставьте его до конца. Вам понадобится как минимум фильтр на выходе - ограничьте частоты звуковым диапазоном до 20 кГц (больше, если вы аудиофил). RC-фильтр будет работать, но я бы выбрал активный фильтр, потому что, если вы используете ШИМ, ваш выходной диапазон будет от 0 до 5 В, обычно со средним напряжением около 2,5 В. Динамики не любят уровни DC - только сигналы. Красивые синусоидальные волны, которые имеют среднее напряжение 0. Таким образом, ваш активный фильтр должен будет регулировать уровни напряжения и использовать двойные источники для обеспечения отрицательного напряжения. Вы также можете усилить сигнал для большой басовой накачки. Только не взрывайте свои динамики.

MP3, вероятно, лучшая альтернатива PCM. Есть чипы: http://www.sparkfun.com/commerce/product_info.php?products_id=8892

Это, однако, целый микроконтроллер. И у вас уже есть один. Но давайте посмотрим правде в глаза - ATMega не собирается делать MP3 самостоятельно, независимо от того, как вы это делаете.

Похоже, что волновой щит, упомянутый выше, в основном делает это - использует SD-карту для хранения PCM и внешний усилитель для звука. Удачи!

Одним из методов генерации устойчивого тона является прямой цифровой синтез. Вам понадобится ЦАП, либо выделенный чип, либо резисторная лестница.

Вы устанавливаете счетчик для переполнения на частоте, которую вы хотите сгенерировать, и на каждом тике счетчика вы используете его для индексации волновой таблицы и получения выходного значения для вашего ЦАП.

Я написал несколько разных техник генерации тона для Arduino здесь, в New Noises From MidiVox. Код обновления ЦАП специфичен для MidiVox (и Adafruit WaveShield's) MCP4921, но генерация синусоидальной волны должна быть в целом применима. Я пытался сохранить код, в основном, общий для ATmegas, но в него попала пара Arduino-измов.

Вставленный из этого поста, вот некоторый код для воспроизведения тона 440 Гц на Arduino с MCP4921 на шине SPI:

uint16_t sample = 0;

/* incr = freq * (2^16 / 15625) 
 * So for 440Hz, incr = 1845 */
uint16_t incr = 1845;

/* oscillator position */
uint16_t pos = 0;

const uint8_t sine[] = {
    0x80, 0x83, 0x86, 0x89, 0x8C, 0x8F, 0x92, 0x95, 0x98, 0x9B, 0x9E, 0xA2,
    0xA5, 0xA7, 0xAA, 0xAD, 0xB0, 0xB3, 0xB6, 0xB9, 0xBC, 0xBE, 0xC1, 0xC4,
    0xC6, 0xC9, 0xCB, 0xCE, 0xD0, 0xD3, 0xD5, 0xD7, 0xDA, 0xDC, 0xDE, 0xE0,
    0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEE, 0xF0, 0xF1, 0xF3, 0xF4,
    0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE,
    0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
    0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 0xF3, 0xF1,
    0xF0, 0xEE, 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
    0xDA, 0xD7, 0xD5, 0xD3, 0xD0, 0xCE, 0xCB, 0xC9, 0xC6, 0xC4, 0xC1, 0xBE,
    0xBC, 0xB9, 0xB6, 0xB3, 0xB0, 0xAD, 0xAA, 0xA7, 0xA5, 0xA2, 0x9E, 0x9B,
    0x98, 0x95, 0x92, 0x8F, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77,
    0x74, 0x71, 0x6E, 0x6B, 0x68, 0x65, 0x62, 0x5E, 0x5B, 0x59, 0x56, 0x53,
    0x50, 0x4D, 0x4A, 0x47, 0x44, 0x42, 0x3F, 0x3C, 0x3A, 0x37, 0x35, 0x32,
    0x30, 0x2D, 0x2B, 0x29, 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
    0x16, 0x15, 0x13, 0x12, 0x10, 0x0F, 0x0D, 0x0C, 0x0B, 0x0A, 0x08, 0x07,
    0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06,
    0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x12, 0x13, 0x15,
    0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x29, 0x2B, 0x2D,
    0x30, 0x32, 0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x42, 0x44, 0x47, 0x4A, 0x4D,
    0x50, 0x53, 0x56, 0x59, 0x5B, 0x5E, 0x62, 0x65, 0x68, 0x6B, 0x6E, 0x71,
    0x74, 0x77, 0x7A, 0x7D
};

void setup() {
    cli();

    /* Enable interrupt on timer2 == 127, with clk/8 prescaler. At 16MHz,
       this gives a timer interrupt at 15625Hz. */
    TIMSK2 = (1 << OCIE2A);
    OCR2A = 127;

    /* clear/reset timer on match */
    TCCR2A = 1<<WGM21 | 0<<WGM20; /* CTC mode, reset on match */
    TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20; /* clk, /8 prescaler */

    SPCR = 0x50;
    SPSR = 0x01;
    DDRB |= 0x2E;
    PORTB |= (1<<1);

    sei();
}

ISR(TIMER2_COMPA_vect) {
    /* OCR2A has been cleared, per TCCR2A above */
    OCR2A = 127;

    pos += incr;

    /* shift left a couple of bits for more volume */
    sample = sine[highByte(pos)] << 2;

    PORTB &= ~(1<<1);

    /* buffered, 1x gain, active mode */
    SPDR = highByte(sample) | 0x70;
    while (!(SPSR & (1<<SPIF)));

    SPDR = lowByte(sample);
    while (!(SPSR & (1<<SPIF)));

    PORTB |= (1<<1);
}

void loop() {
}

Отличная особенность Direct Digital Synthesis в том, что чрезвычайно легко воспроизводить несколько тонов вместе (путем добавления) или микшировать их на желаемых уровнях громкости (путем умножения на уровень громкости перед добавлением).

Я обнаружил, что Arduino может играть около 30 тонов одновременно, используя этот метод. Мое конкретное приложение для моделирования органов Хаммонда, и это может оказаться полезным для чтения.

Сегодня воспроизводить файлы MP3 с 8-битного микроконтроллера легко и дешево. Вам нужно устройство памяти (например, SD-карта) и набор микросхем MP3. Смотрите эту статью для примера. Вы можете найти много других на avrfreaks. Там вы также можете найти статьи для воспроизведения звуков без внешнего чипа.

Вы можете воспроизводить базовые звуки с широтно-импульсной модуляцией (ШИМ), но для настоящей песни вам понадобится ЦАП. Я видел проекты, которые воспроизводили файлы MP3 с использованием только ЦАП и программного обеспечения, но в них использовались более мощные микроконтроллеры ARM.

Если вы чувствуете себя особенно творчески, вы можете создать свой собственный цифро-аналоговый преобразователь, используя резисторную лестницу.

У вас недостаточно места на ATMega128, чтобы сделать что-то слишком модное. Самый простой способ подключить динамик (маленький 2"или меньше) - через резистор. Проверьте текущую пропускную способность выхода и рассчитайте R соответственно.

---------------------- +V
    |
    \
    / R
    \
    /              ----------
    |              |
    |   ------     |
    ----|    |-----| Microcontroller
        /    \     |
       --------    |
        Speaker    ---------

Что касается создания тональных сигналов, то при базовом переключении выходного сигнала будет звучать обычная стилафонная звучащая дерьмо. Вы можете использовать широтно-импульсную модуляцию для получения аппроксимаций любого аналогового звука (слишком сложный, чтобы в него вдаваться, и AtMega, вероятно, не будет иметь достаточно затяжки или памяти). Этот метод использовался для создания звуковых драйверов для ПК без звуковой карты (только со встроенным динамиком) в старые добрые времена...

Если вы используете Arduino, вы можете купить WaveShield Леди Ады за 22 доллара США. Леди Ада предлагает много вкусностей Arduino, которые стоит купить. Некоторыми примерами являются GPS, Ethernet и шаговые / сервоэкраны.

Вы можете взглянуть на MP3-плеер с открытым исходным кодом и посмотреть, как они это делают. Я предполагаю, что вам понадобится цифроаналоговый преобразователь для получения звука достойного качества.

Другие вопросы по тегам