Страница 1 из 2

Суммирование прямоугольных сигналов

Добавлено: Вт июл 11, 2023 21:38:40
kas1830
И снова здравствуйте!

Ранее экспериментировал с синтезом звука на AVR. По итогу сделал музыкальную шкатулку на ATTiny2313, где задействовал два таймера Т0 и Т1 в режиме СТС для вывода основной мелодии и бас-партии. Динамик, соответственно, смешивал все это хозяйство. Получилось неплохо.
Продолжая эту историю, заинтересовался, как технически суммируются прямоугольные импульсы? И можно ли обойтись в принципе одной ногой таймера в коде для вывода двух (и более нот) одновременно? Примерно, как на картинке ниже:

Изображение

Наглядный пример:



Буду благодарен за разъяснения и направление, куда копать дальше!

Re: Суммирование прямоугольных сигналов

Добавлено: Вт июл 11, 2023 21:50:04
КРАМ
[uquote="kas1830",url="/forum/viewtopic.php?p=4444709#p4444709"]как технически суммируются прямоугольные импульсы?[/uquote]
Так же, как и непрямоугольные и не импульсы - аналоговым сумматором. Простейший - резистивный. Можно сделать сумматор на ОУ.

Re: Суммирование прямоугольных сигналов

Добавлено: Вт июл 11, 2023 22:06:27
veso74
Для тонов с частотами в сотые доли герца нужна другая вычислительная мощность и ресурс. С AVR и указанным способом будет всего каких-то два тона. Рассмотрите как идею напр. NCO генератор, или два внешних генератора DDS. Будет легче.

Re: Суммирование прямоугольных сигналов

Добавлено: Ср июл 12, 2023 09:36:34
Jack_A
[uquote="veso74",url="/forum/viewtopic.php?p=4444727#p4444727"]Для тонов с частотами в сотые доли герца[/uquote]
Сотые доли Герца можно сгенерировать на самом медленном оборудовании, даже на реле :)) Ну если период - десятки секунд - это даже арифмометр "Феликс" осилит :shock: Но музыку в диапазоне инфразвука оценит разве что осьминог.
СпойлерУ нас НИИ сдавало тему - простейшая цикловая схема управления роботом. Для демонстрации подобрали и подключили к выходам несколько пускателей разных габаритов. При срабатывнии они издавали щелчок разной тональности - зависит от массы якоря. Программа исполняла "Чижик-пыжик" :))
------------------------
Как-то в институте на скучной лекции я взялся посчитать - с какой частотой я получаю стипендию. Оказалоь 3,8 * 10^-7 Гц :)

Re: Суммирование прямоугольных сигналов

Добавлено: Ср июл 12, 2023 10:44:00
veso74
Видимо переводчик БГ-РУ неправильно перевел мысль, но вы поняли. Я писал для 261,63 и 277,18 Hz.

Re: Суммирование прямоугольных сигналов

Добавлено: Ср июл 12, 2023 14:16:19
kas1830
Товарищи, спасибо всем, кто уже откликнулся.

В крайности уходить не стоит. Перефразирую вопрос проще: как на МК сгенерить одновременное звучание двух и более нот разной частоты? Типа аккорда. Какие есть технические варианты?

Re: Суммирование прямоугольных сигналов

Добавлено: Ср июл 12, 2023 17:42:38
Starichok51
kas1830, тебе уже ответили - сложить сигналы обычным сумматором.

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 08:33:23
kas1830
Похожий пост по теме:
https://forum.cxem.net/index.php?/topic ... %B8%D1%8E/

Цитата:
...в памяти прописывается массив, отражающий форму элементарного сигнала, а затем делается выборка, сложение с выборкой другой(-ими) ноты, одновременно звучащей, и результирующий код (8 и более бит) подается на R2R, ЦАП, или ШИМ.
Как раз то, что я ищу. У меня записан массив нот в памяти.
Поделитесь пжл примером кода, если у кого есть, как производится сложение выборок, чтобы выводить полифонию

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 10:20:25
Starichok51
кроме массива нот нужен массив частот этих нот. и складываются частоты, а не ноты.

Добавлено after 10 minutes 30 seconds:
для лучшего понимания прочитай эту статью https://www.radiokot.ru/circuit/digital/game/51/
а также запусти поиск по фразе "синтез мелодий на AVR", и найдешь уйму информации по синтезу мелодий.

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 10:55:39
Engineer_Keen
Для складывания двух и более звуков, если используется AVR и ШИМ 8-10 бит, достаточно их все тупо сложить (с учетом знака) и при выходе за пределы разрядности тупо ограничить, т.е. если сумма для 8 бит>255, то результат будет 255, если меньше 0, то 0.
Да, при сложении может произойти искажение (перегрузка), ее можно обойти, заранее поделив громкость на количество одновременно складываемых звуков, но в этом скорее всего не будет необходимости, учитывая условия.

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 11:13:55
kas1830
Спасибо за ответ.
[uquote="Engineer_Keen",url="/forum/viewtopic.php?p=4445419#p4445419"]...если используется AVR и ШИМ 8-10 бит[/uquote]
Тут у меня как раз не ШИМ, а СТС режим. Будет аналогично или есть особенности?

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 11:22:17
BOB51
ГЫММ...
В данном случае похоже не сумматор, а смеситель нужен...
https://ru.wikipedia.org/wiki/Смеситель_(электроника)
:roll:

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 12:02:12
Engineer_Keen
[uquote="kas1830",url="/forum/viewtopic.php?p=4445437#p4445437"]Тут у меня как раз не ШИМ, а СТС режим. Будет аналогично или
есть особенности?[/uquote]

Э погодите-ка, тут есть варианты...
Если вы генирируете звук при помощи сложения разных меандров, т.е. используете режим CTC для задания частот именно самих звуковых волн и ЭТИ волны надо микшировать, то действительно, это проще сделать внешним смесителем. Кстати, можно использовать один железный таймер, а частоты меандров синтезировать программно, используя вариант ниже.

А вот если режим CTC нужен для задания частоты квантования и по этой частоте вы бы через ШИМ выводили семплы, то суммировать их можно методом, который я описал выше.

Кстати, и для задачи частоты квантования и для ШИМ (даже стерео) можно использовать всего ОДИН таймер, причем частоту квантования можно задавать в широких пределах, в том числе близкую к стандартным 11-22-44кГц. Для этого таймер настраивается в режим CTС со сравнением с ICR, в ICR заносится нужное для заданной частоты квантования значение. А семплы нормируются с учетом этого значения и выводятся в OCRA и OCRB в прерывании по переполнению.

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 12:10:22
Asmodey
В некоторых моделях PIC микроконтроллеров присутствует периферийный модуль DATA SIGNAL MODULATOR. Возможно подойдет для поставленных топикстартером целей.

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 12:48:11
veso74
Или с тремя NCO генераторами (напр. PIC18F25Q43), но отклоняемся от темы.

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 15:14:45
BOB51
Модулятор и в старших АВРках есть...
:roll:

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 22:27:40
Asmodey
Ну так то в старших, а у PIC в копеечных младших имеются.

Re: Суммирование прямоугольных сигналов

Добавлено: Чт июл 13, 2023 22:50:32
kas1830
Э погодите-ка, тут есть варианты...
Если вы генерируете звук при помощи сложения разных меандров, т.е. используете режим CTC для задания частот именно самих звуковых волн и ЭТИ волны надо микшировать, то действительно, это проще сделать внешним смесителем. Кстати, можно использовать один железный таймер, а частоты меандров синтезировать программно, используя вариант ниже.

А вот если режим CTC нужен для задания частоты квантования и по этой частоте вы бы через ШИМ выводили семплы, то суммировать их можно методом, который я описал выше.
Спасибо, а можно поподробнее (или пример)? Пока непонятно. что с чем складывать.
У меня два таймера Т0 и Т1 тикают независимо в режиме СТС, далее в прерывании каждый дергает свою ногу, с частотой, заданной регистром сравнения.
Динамик соединен с двумя выводами МК и делает всю работу по смешению за меня.

Re: Суммирование прямоугольных сигналов

Добавлено: Пт июл 14, 2023 11:24:33
Engineer_Keen
Ну вот так, например...
Код для суммирования 4х меандров (2 отключил чтобы понятнее сумма выглядела). Тактовая для Mega88 - 8МГц, частота семплов 22кГц, использован один 16 разрядный таймер, и одно его прерывание, 20 байт ОЗУ, и 270 флеша, загрузка контроллера ~45%.
Спойлер

Код: Выделить всё

;программа сложения 4х прямоугольных сигналов с произвольными частотами

	.include	"m88def.inc"				;определения для Mega88
	.include	"MacroAVR.asm"				;макросы для упрощения кода

	.equ	F_CPU=8000000					;частота контроллера

	.equ	SND_SAMPLE_FREQ		=22050			;частота выборок
	.equ	SND_OCR_VALUE		=F_CPU/SND_SAMPLE_FREQ	;расчет значения для режима CTC
	.equ	SND_MID_VALUE		=SND_OCR_VALUE/2	;половина выходного сигнала
	.equ	NUMBER_OF_SIGNALS	=4			;количество смешиваемых сигналов

	.equ	FREQ0	=261		;C4			;частоты сигналов
	.equ	FREQ1	=311		;D#4
	.equ	FREQ2	=110		;A2
	.equ	FREQ3	=61		;B1

	.equ	DIV0	=SND_SAMPLE_FREQ/FREQ0/2		;расчет делителей
	.equ	DIV1	=SND_SAMPLE_FREQ/FREQ1/2		;для частоты каждого сигнала
	.equ	DIV2	=SND_SAMPLE_FREQ/FREQ2/2
	.equ	DIV3	=SND_SAMPLE_FREQ/FREQ3/2

	.def	ZERO	=R2					;для ускорения арифметики
	.def	STR	=R3					;для ускорения вх/вых в прерывание

			;структура данных для одного сигнала
	.equ	PH_OFFSET	=0				;фаза
	.equ	DIV_OFFSET	=2				;делитель
	.equ	OUT_OFFSET	=4				;значение на выходе
	.equ	SIGNAL_SIZE	=2+2+1				;ее размер

	.dseg		;сегмент данных
SIG:		.byte	SIGNAL_SIZE*NUMBER_OF_SIGNALS		;данных сигналов

	.cseg		;сегмент кода
	.org	0
	RJMP	RESET

	.org	OVF1addr
	RJMP	SAMPLE_OUT	;прерывание для расчета и вывода семпла

DIVS:
	.dw	DIV0,DIV3,0,0	;рассчитанная таблица частот сигналов (0-отключено для наглядности)
;	.dw	DIV0,DIV1,DIV2,DIV3

RESET:	SETSTACK			;установка стека
	OUTI	CLKPR,(1<<CLKPCE)	;сброс делителя тактовой
	STS	CLKPR,ZERO
	OUTI	DDRC,(1<<PC4)|(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0);тестовые выходы 
	OUTI	TCCR1A,(1<<COM1A1)|(1<<WGM11)|(0<<WGM10)	;настройка таймера CTC, TOP=ICR
	OUTI	TCCR1B,(1<<WGM12)|(1<<WGM13)|(1<<CS10)
	OUTI	ICR1H,High(SND_OCR_VALUE)		;период квантования
	OUTI	ICR1L,Low(SND_OCR_VALUE)
	OUTI	OCR1AH,High(SND_MID_VALUE)		;в ШИМ - половина уровня
	OUTI	OCR1AL,Low(SND_MID_VALUE)
	LDS	R16,TIMSK1				;вкл. прерывания OVF1
	ORI	R16,(1<<TOIE1)
	STS	TIMSK1,R16
	SBI	DDRB,PB1				;включить вывод ШИМ
	SETZ	DIVS*2					;копирование таблицы из флеша
	SETY	SIG					;в структуру сигнала
	LDI	R17,NUMBER_OF_SIGNALS
DLOOP:	LPM	XL,Z+					;чтение делителя
	LPM	XH,Z+
	STD	Y+PH_OFFSET+0,XH			;запись начального значения фазы
	STD	Y+PH_OFFSET+1,XL
	STD	Y+DIV_OFFSET+0,XH			;и это же значение в делитель
	STD	Y+DIV_OFFSET+1,XL
	STD	Y+OUT_OFFSET,ZERO			;значение функции изначально=0
	ADIW	YL,SIGNAL_SIZE			;переход к следюущему 
	DJNZ	R17,DLOOP				
	SEI						;вкл. глобальных прерываний

LOOP:	SETX	SIG+OUT_OFFSET				;основной цикл
	LDI	R17,NUMBER_OF_SIGNALS			;просто вывод
	CLR	R18					;значения функций на выходы
OLOOP:	LD	R16,X					;для наглядности
	BST	R16,7
	BLD	R18,4
	LSR	R18
	ADIW	XL,SIGNAL_SIZE
	DJNZ	R17,OLOOP
	IN	R16,PORTC
	ANDI	R16,0xF0
	OR	R16,R18
	OUT	PORTC,R16
	RJMP	LOOP

			;процедура вывода семпла
SAMPLE_OUT:
	SBI	PORTC,PC4	;вывод загрузки контроллера процедурой
	IN	STR,SREG	;сохранение SREG и регистров
	PUSH	R17
	PUSH	R16
	PUSHX
	PUSHY
	PUSHZ
	LDI	ZL,0x08		;начальное значение суммы сигналов
	LDI	R17,NUMBER_OF_SIGNALS
	SETY	SIG		;установка на структуру первого сигнала
SLOOP:	LDD	XH,Y+PH_OFFSET+0	;чтение фазы
	LDD	XL,Y+PH_OFFSET+1
	CP	XL,ZERO
	CPC	XH,ZERO
	BREQ	SKIP			;если 0, про сигнал не обрабатывать
	LDD	R16,Y+OUT_OFFSET	;чтение значения на выходе
	SBIW	XL,1			;уменьшаем фазу
	BRNE	NO_INVERT		;если не 0, переход к сохранению
	COM	R16			;если 0, инвертируем выход
	STD	Y+OUT_OFFSET,R16	;сохраняем значение на выходе
	LDD	XH,Y+DIV_OFFSET+0	;перезагружаем значение фазы
	LDD	XL,Y+DIV_OFFSET+1
NO_INVERT:
	STD	Y+PH_OFFSET+0,XH	;сохраняем фазу
	STD	Y+PH_OFFSET+1,XL
	SBRC	R16,7			;суммируем значения на выходах
	INC	ZL			
	SBRS	R16,7
	DEC	ZL
SKIP:	ADIW	YL,SIGNAL_SIZE		;переход к следующему
	DJNZ	R17,SLOOP

	CJNE	ZL,0x08,NO_HALF		;проверка суммы значений и преобразование в ШИМ
	SETZ	SND_MID_VALUE		;если сумма=0, выводим половину в ШИМ
	RJMP	OCR_SET
NO_HALF:CJLO	ZL,0x08,OUT_MIN		;если сумма<0, выводим в ШИМ 0
	SETZ	SND_OCR_VALUE-1		;если сумма>0, выводим в ШИМ максимальное значение
	RJMP	OCR_SET
OUT_MIN:SETZ	0
OCR_SET:
	STS	OCR1AH,ZH		;вывод в регистры ШИМ
	STS	OCR1AL,ZL
	POPZ				;восстановление регистров
	POPY
	POPX
	POP	R16
	POP	R17
	OUT	SREG,STR
	CBI	PORTC,PC4
	RETI
Результат. Зеленый (после RC-цепочки) = желтый+синий. Нижний осциллограф - ШИМ, и загрузка контроллера.
СпойлерИзображение

PS: О, зацените игрушку :idea:
всего 146 байт флеша и 14 ОЗУ, работает от встроенного RC на 8МГц, 7 кнопок, можно все сразу нажать, будет 7 меандров на выходе и еще 66% процессорного времени свободно. Можно прикрутить читалку нот по таймеру и готова музыкальная шкатулка :))) :facepalm:
SYNTH_TEST.rar
(47.78 КБ) 67 скачиваний

Re: Суммирование прямоугольных сигналов

Добавлено: Сб июл 15, 2023 04:21:42
Аlex
http://www.pic24.ru/doku.php/osa/articles/pk2_osa_piano
Сделано на каком-то дубовом камне.