2013-06-23 2 views
0

У меня есть плата MP3, прикрепленная к микроконтроллеру ATmega, который дополнительно подключен к потенциометру. Плата MP3 воспроизводит данные MP3 непосредственно через встроенный динамик, поэтому я также могу установить громкость вывода.математическая функция как двоичные операции

Итак, как вы могли догадаться, я прочитал значение из poti и направил его на микроконтроллер. К сожалению, микроконтроллер не увеличивает объем линейным способом. Таким образом, из значений от 0 до 128 вы почти ничего не слышите, а от 128 до 255 (макс.) Громкость быстро увеличивается.

Я узнал, что следующая функция может решить эту проблему:

vol = 1 - (1 - x)^4 

но х должно быть между 0 и 1, и результат также между 0 и 1.

Поскольку я на микроконтроллер, я хотел бы

  1. преобразовать эту формулу, так что я могу использовать его с беззнаковыми целыми
  2. оптимизировать (возможно, использовать несколько дешевых двоичных функций), потому что я читаю значение poti несколько раз в секунду. Поэтому эту функцию нужно рассчитывать несколько раз в секунду, и я тоже хочу использовать микроконтроллер для других вещей ;-)

Возможно, у некоторых из вас есть идея? Было бы замечательно!

uint8_t linearize_volume(uint8_t value) { 
    // ideas? 
    // please don't use bigger data types than uint16_t 
} 
+0

Подняв что-то к четвертой власти, просто возводите в квадрат его дважды. Это слишком дорого? Кроме того, сколько памяти у вас есть, чтобы предварительно скопировать таблицы для ускорений? –

+0

Моя проблема в том, что 255^4 больше 2^16, поэтому я не могу сохранить его в 'uint16_t'. –

ответ

1

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

uint8_t linearize_volume(uint8_t value) { 
    // Approximate 255 * (1 - (1 - x/255)^4) 
    uint16_t x = 0xff - value; 
    x = (x * x) >> 8; 
    x = (x * x) >> 8; 
    return 0xff - x; 
} 
3

Вы можете «заплатить» за память для циклов процессора. Если у вас имеется 256 байт ROM, самым дешевым способом вычисления такой функции будет построение таблицы поиска.

Сделайте программу, которая печатает список из 256 8-битных чисел со значениями вашей нелинейной функции. Неважно, насколько быстро программа, потому что вы собираетесь запускать ее только один раз. Скопируйте номера, которые программа печатает в вашу программу на C как инициализатор массива, и выполняйте поиск вместо вычисления функции.

+0

+1: 256-байтная таблица поиска в ПЗУ не очень подходит для серии ATmega. Вы можете сгенерировать LUT с более реалистичными (сложными?) Функциями рампы. –

0

Во-первых, убедитесь, что вы используете линейный горшок, а не звуковой конус.

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

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

«MP3-доска» должна включать в себя возможность управления томом без необходимости изменять образцы.

Вы заявляете, что читаете банк и отправляете его на микро. Разве вы не читаете банк с микро-АЦП?

+0

Когда я говорю «Я читаю значение из поти», я имею в виду, что я использую АЦП для получения значения от 0 до 255. –

+0

То, что я не могу различить, - это то, как вы получаете MP3-образцы в микро. Неужели я глуп? Вы спрашиваете о получении образцов АЦП из банка или из данных MP3? –

+0

У вас есть «звуковой горшок» или «линейный горшок»? Есть большая разница с тем, что АЦП будет читать из них. Я думаю, вы хотите линейный горшок. –