реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Работа со звуком в программе с операционной системой
stepper88
сообщение Jan 29 2013, 17:38
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 20-02-09
Пользователь №: 45 138



Здравствуйте, господа!
Понадобилось в проекте с операционной системой RL-ARM RTX проигрывать wav-файл с карты памяти. Подскажите пожалуйста, как лучше это реализовать. Само устройство сделано на базе LPC2378 (есть подключенная внешняя ОЗУ), звук выводится через ЦАП микроконтроллера. Я посмотрел, для вывода требуется частота отсчетов минимум 8 кГц, но системный тик RTX сейчас 1 милисекунда. Как поступить? Или уменьшать время системного тика, или каким-то образом задействовать еще один таймер и отправлять данные очередного отсчета из обработчика его прерывания?
Заранее благодарен
Go to the top of the page
 
+Quote Post
toweroff
сообщение Jan 29 2013, 18:32
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Скорее всего, другой таймер и приоритет ему поднять выше таймера RTX
Только тут может быть камень - если используете задержки критичные в RTX со всякими os_dly_wait, os_time_get и т.д., то могут быть неточности
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Jan 30 2013, 01:37
Сообщение #3


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (stepper88 @ Jan 30 2013, 01:38) *
Здравствуйте, господа!
Заранее благодарен

Добрый день! На мой взгляд лучше бы внешний кодек на I2S, и DMA'ем гнать в него поток из внешней RAM)
Но поскольку Вы уже использовали АЦП этого МК (не лучший вариант, к сожалению, т.к. если мне память не изменяет, DMA не имеет доступа к ЦАПу), то, наверно, действительно только таймер. В высокоприоритетную задачу вряд ли звуковой поток поставить. Хотя попробовать можно.


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Jan 30 2013, 06:50
Сообщение #4


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



Нормальный звук врядли на нем удастся сделать.
Go to the top of the page
 
+Quote Post
Allregia
сообщение Jan 30 2013, 08:01
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Цитата(ar__systems @ Jan 30 2013, 08:50) *
Нормальный звук врядли на нем удастся сделать.


Так не музыку же собираются играть, раз там Fs=8kHz.

Цитата
DMA не имеет доступа к ЦАПу


При Fs=8kHz и не надо никакого DMA.
Можно завести таймер на 8кгц и сделать два буфера, в один считывать с карты памяти, со второго - по прерыванию таймра выводить в ЦАП. По концу буфера, буфера меняются местами.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Jan 30 2013, 08:23
Сообщение #6


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (Allregia @ Jan 30 2013, 17:01) *
Можно завести таймер на 8кгц

Так моя и не спорит, понимает, что можно rolleyes.gif Вот только дергать ARM каждые 125 мкс как-то не камильфо. Нет, можно, но я, как уникальная личность, не сторонник такого подхода rolleyes.gif Желание эмулировать интерфейсы программно (где времянка играет основнополагающую роль) у меня еще отпало лет 6 назад rolleyes.gif

Гм... как абсурдная идея гнать аудио в FIFO USART, а на выходе конвертировать его сдвиговым регистром в параллельный код rolleyes.gif Я понимаю, печатка уже сделана.

Автор, когда придете к окончательному решению, будьте добры, расскажите нам, как и что rolleyes.gif Аж интересно стало!


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
stepper88
сообщение Jan 30 2013, 14:06
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 20-02-09
Пользователь №: 45 138



Цитата(haker_fox @ Jan 30 2013, 14:23) *
Автор, когда придете к окончательному решению, будьте добры, расскажите нам, как и что rolleyes.gif Аж интересно стало!

Простите пожалуйста, что не ответил сразу. На работе интернет тормозит сегодня жутко. Пока что сделал сегодня только распаковку файла wav и вывод отсчетво на терминал.
У меня вопрос насчет таймера - если я сделаю прерывания с частотой 8 кГц это не порушит операционную систему? Просто устройство должно реализовывать госовое меню по телефону и охота отлавливать реакцию модема - повесил ли пользователь трубку, а может быть, нажал кнопку. С кодеком, к сожалению не получится - плата уже сделана и не хочется сильно вносить изменения в схемотехнику.
За идею с буферами спасибо отдельное - вполне возможно, что тоже пробовать буду.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Jan 30 2013, 14:20
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(stepper88 @ Jan 30 2013, 18:06) *
У меня вопрос насчет таймера - если я сделаю прерывания с частотой 8 кГц это не порушит операционную систему? Просто устройство должно реализовывать госовое меню по телефону и охота отлавливать реакцию модема - повесил ли пользователь трубку, а может быть, нажал кнопку.

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

я когда-то делал подобное, с использованием БПФ, но это было на PC
Мне от модема валился оцифрованный поток, я его просто БПФ скармливал и выделял КПВ оттуда
Go to the top of the page
 
+Quote Post
stepper88
сообщение Jan 30 2013, 16:13
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 20-02-09
Пользователь №: 45 138



Цитата(toweroff @ Jan 30 2013, 20:20) *
вы же используете голосовые функции модема? что там к вам от него валится?
Если поток валится, как анализируете?

На схеме распаяли апаратный декодер DTMF - думаю или с него брать данные, или же встроенный DTMF-декодер модема (модем Quectel M10) попробую запрячь
Go to the top of the page
 
+Quote Post
toweroff
сообщение Jan 30 2013, 18:25
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



А как собираетесь отслеживать то, что пользователь повесил трубку? Насколько я помню, никакими техническими средствами не определить этого. Только через анализ КПВ на предмет кородких гудков
Go to the top of the page
 
+Quote Post
stepper88
сообщение Feb 1 2013, 06:49
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 20-02-09
Пользователь №: 45 138



Цитата(toweroff @ Jan 31 2013, 00:25) *
А как собираетесь отслеживать то, что пользователь повесил трубку?

Когда пользователь кладет трубку, модем выдает NO CARIER и как раз это хочу отлавливать в другой задаче.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Feb 1 2013, 06:56
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(stepper88 @ Feb 1 2013, 10:49) *
Когда пользователь кладет трубку, модем выдает NO CARIER и как раз это хочу отлавливать в другой задаче.

это если был ОБМЕН данными с другим модемом на той стороне. У вас только голосовые функции, не забывайте
Насколько я помню, переведя модем в голосовой режим, можно было только его оттуда вывести. Сам он просто гнал потоком те звуки, которые были в линии. Соответственно, т.к. никакого обмена не было, то и терять связь не с кем. Откуда NO_CARIER возьмется?
хотя может модемы и поумнели sm.gif
Go to the top of the page
 
+Quote Post
stepper88
сообщение Feb 9 2013, 07:40
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 20-02-09
Пользователь №: 45 138



Прошу прощения, что долго не заходил в тему.
На данный момент изобразил две функции воспроизведения wav-файла. Первая была более простой - там просто между отправками отсчетов на цап запускается таймер и отмеряет задержку - прерывание там не используется.
Код
memcpy(&size, &buffer[4],4);
while (size>128)
{
    fread(buffer, sizeof(char), 128, f);
    size=size-128;
    for (t=0;t<128;t++)
    {
        DACR=buffer[t]<<8;
        T1_delay(86);
    }
    result=os_evt_wait_or(0x003E, 0);
    if (result==OS_R_EVT)
    {
        fclose(f);
        return;
    }
}
fread(buffer, sizeof(char), size, f);
for (t=0;t<size;t++)
{
    DACR=buffer[t]<<8;
    T1_delay(86);
}
result=os_evt_wait_or(0x003E, 0);
if (result==OS_R_EVT)
{
    fclose(f);
    return;
}
fclose(f);
result=os_evt_wait_or(0x003E, timeout);
}

Второй вариант использует прерывания от таймера и два буфера
Код
memcpy(&size, &buffer[4],4);
fread(buffer, sizeof(char), 256, f);
size=size-256;
T1TCR=0x01;
while (size>128)
{
    switch (empty)
    {
        case 0: break;
        case 1: fread(buffer, sizeof(char), 128, f); empty=0; size=size-128; break;
        case 2: fread(&buffer[128], sizeof(char), 128, f); empty=0; size=size-128; break;
    }
    result=os_evt_wait_or(0x003E, 5);
    if (result==OS_R_EVT)
    {
        T1TCR=0;
        fclose(f);
        return;
    }
}
switch (empty)
{
    case 0: break;
    case 1: fread(buffer, sizeof(char), 128, f); empty=0; size=size-128; break;
    case 2: fread(&buffer[128], sizeof(char), 128, f); empty=0; size=size-128; break;
}
result=os_evt_wait_or(0x003E, 5);
if (result==OS_R_EVT)
{
    T1TCR=0;
    fclose(f);
    return;
}

Обработчик прерывания
Код
void T1_Handler (void) __irq
{
    T1IR=0x01;
    switch (t)
    {
        case 128: empty=1; break;
        case 0: empty=2; break;
    }
    DACR=buffer[t++]<<8;
    VICVectAddr = 0;  // Acknowledge Interrupt
}

Решил вместо двух массивов использовать один, но поочередно записывать в первую и вторую половины массива.
Насчет "поумневших" модемов в моем случае оказалось достаточным включить встроенный декодер DTMF модема и он по нажатию каждой кнопки выплевывал сообщение.
P.S. прилагаю файл wav.c - в нем функция play_wav() реализует проигрывание файла без использования прерывания от таймера, функция play_wav_int() соответственно с использованием
Прикрепленные файлы
Прикрепленный файл  wav.rar ( 1.65 килобайт ) Кол-во скачиваний: 10
 
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 09:48
Рейтинг@Mail.ru


Страница сгенерированна за 0.01487 секунд с 7
ELECTRONIX ©2004-2016