Синтез в піддіапазонах

Хоча в форматах Layer 1 і Layer 2 дані зберігаються по-різному, принципи, які у основі, одні й ті ж Почнемо з розгляду, яким чином реконструюється ІКМ-звук після декодування бітів B наступних розділах ви побачите, як для цих рівнів біти записуються у файл

Після попереднього декодування ми отримуємо групи з 32 відліків піддіапазонів Кожен відлік це амплітуда піддіапазону конкретної частоти Щоб реконструювати вихідний сигнал, спочатку треба перетворити 32 відліку піддіапазонів в 64 відліку ІКМ, складаючи пакет косінусоід Після цього послідовні набори ІКМ-значний змішуються, в результаті чого виходять 32 вихідних відліку

Лістинг 1412 Змінні для декомпресії Layer 1/Layer2

private:

long * _V [2] [16] / / Синтезується інтервал для лівого /

/ / Правого каналів

void Layerl2Synthesis(long *V[16], long *in, int inSamples, AudioSample *out)

void LayerlDecode () / / Декомпресія даних формату Layer1

void Layer2Decode () / / Декомпресія даних формату Layer2

B масивах V зберігаються 16 груп з 64 відліків ІКМ Кожен набір з 32 відліків піддіапазонів (в частотній області) відновлюється з 64 відліків ІКМ B масиви V записуються 16 наборів значень, оброблених останніми

Лістинг 1413 Ініціалізація загальних змінних Layer 1/Layer 2

for (int ch = 0 ch <2; ch + +) {/ / V зберігається всередині об'єкта. for (int i = 0; i <16; i + +) {

_V[ch][i] = new long[64]

for(int j=0j&lt64j++)

_V[ch][i][j] = 0

}

}

Оскільки масив V зберігається в обєкті, його необхідно знищити при уда-

леніі обєкта

Лістинг 1414 Очищення ресурсів MPEG

for(int ch=0ch&lt2ch++)

for(int i=0i&lt16i++)

delete [] _V[ch][i]

Для прискорення обчислень при реалізації синтезу піддіапазонів я скористався 32-бітної арифметикою з фіксованою точкою B комментаріяхсодержатся допущення, зроблені мною щодо різних змінних Я вирішив, наприклад, що відліки піддіапазонів мають формат 216, тобто 2 розряду перед десяткового точкою і 16 після

Подібна форма запису зручна для збереження точності значень Напри-

заходів, при множенні чисел, записаних як 215 і 213, у творі буде

28 розрядів після десяткової точки (15 +13) і 3 перед (2 розряду кожного з множників відповідають 1-у розряду плюс знак, у результату буде 2 значущих розряду плюс знак), що можна записати у вигляді 328 Так як 3 +28 це всього

31 розряд, то переповнення 32-бітного значення не відбудеться Аналогічниесо-

казу широко використовувалися при написанні цієї програми

Лістинг 1415 Синтез піддіапазонів Layer 1 і Layer2

void DecompressMpeg::Layerl2Synthesis(

long *V[16],

long *subbandSamples, int numSubbandSamples, AudioSample *pcmSamples) {

long *t = V[15]

for (int i = 15 i> 0 i -) / / Зрушуємо буфери V

V[i] = V[i-1] V[0] = t

/ / Перетворимо відліки поддиапазонов

/ / В відліки ІКМ в V [0]

Matrix(V[0],subbandSamples,numSubbandSamples)

/ / Переставляємо коефіцієнти

/ / Синтезованого інтервалу

/ / В більш зручному порядку і масштабується

/ / Їх у формат 312

static long D[512]

static bool initializedD = false

if (initializedD) { long *nextD = D for(int j=0j&lt32j++)

for(int i=0i&lt16i+=2) {

*nextD++ = SynthesisWindowCoefficients[j+32*i]&gt&gt4

*nextD++ = SynthesisWindowCoefficients[j+32*i+32]&gt&gt4

}

initializedD = true

}

/ / D має формат 312, V має формат 69, на виході

/ / Потрібно 1б-бітове число

long *nextD = D

for(int j=0j&lt32j++) {

long sample = 0 // 816 for(int i=0i&lt16i+=2) {

sample += (*nextD++ * V[i][j]) &gt&gt 8

sample += (*nextD++ * V[i+l][j+32]) &gt&gt 8

}

* PcmSamples + + = sample >> 1 / / Вихідні відліки

/ / Є 16-розрядними

}

}

Матрицирования

32 відліку піддіапазонів відповідають амплітудам 32 різних частот Ha кроціматрицированиявиробляється перетворення їх значень в 64 відліку ІКМ Це є ядром усього процесу декодування

Назва «матрицирования» відбулося від способу відновлення, описаний-

ного в стандарті ISO Стандарт визначає особливу матрицю розміром 64×32

I являє реконструкцію як процес множення матриць вектор з 32 відліків піддіапазонів множиться на цю матрицю, і виходять 64 відліку ІКМ Ці значення піддаються подальшій обробці, в результаті якої реконструюються 32 відліку ІКМ

Суворе визначення процесу матрицирования полягає в тому, що в ре-

зультате його виконання з 32 відліків піддіапазонів S0, S1, .., S31 за формулою

31

Vn  = ∑ Sk  cos[(16 + n)(2k + 1)π / 64]

=0

виходить 64 вихідних значення V0, V1, .., V63

Зауважимо, що кожен ряд цієї матриці являє собою відмінну від дру-

гіхкосінусоіду B представленої формулою кожна з косінусоід просто масштабується з відповідним коефіцієнтом Sk, a потім підсумовується з іншими, в результаті чого і виходять 64 вихідних значення

Повільне матрицирования

Так як значення в матриці косинусів 64×32 фіксовані, їх можна вирахувати заздалегідь, записати в таблицю і безпосередньо реалізувати наведену вище формулу, як це зроблено в наступній програмі:

Лістинг 1416 Матрицирования відліків Layer 1/Layer2медленная версія

static void IntMatrix(long *V, long *subbandSamples) {

int numSubbandSamples = 32

/ / N константа, тому зберігається в статичної змінної

static long N[64][32]

static bool initializedN = false

if (initializedN) {

for(int n=0n&lt64n++) {

for(int k=0k&lt32k++)

N[n][k] = static_cast&ltlong&gt

(81920*cos((16+n)* (2*k+l)*(314159265358979/

640)))

}

initializedN = true

}

for (int n = 0 n <64; n + +) {/ / матрицирования. long t = 0; / / Суму 3 2-х чисел,

/ / Кожне у форматі 221

long *samples = subbandSamples  // 116 long *matrix = N[n]              // 213 for(int k=0k&ltnumSubbandSamplesk++)

t += (*samples++ **matrix++) &gt&gt 8 V[n] = t&gt&gt10 // V is 13

}

}

У наведеній програми є два серйозні недоліки По-перше, невисока точність Кожен раз, складаючи або перемножуємо два числа з фіксованою точкою, ми потенційно можемо втратити один розряд точності через помилки округлення Так як для отримання кожного вихідного значення потрібно провести 32 операції множення і 32 додавання, точність результату викликає серйозні побоювання

Найбільшим недоліком є ​​низька швидкість виконання обчис-

лений Для кожної операції перемноження матриць потрібно провести більш

2000 операцій множення Ha компютері з 486-м процесором і тактовою частотою 66 МГц виконання програми матрицирования потребують близько двухміллісекунд K жаль, навіть при найнижчій з використовуваних в MPEG-1 частоті дискретизації в 32 000 відліку в секунду на декомпресію кожної групи з 32 відліків можна витратити всього 1 мілісекунду (при цьому треба памятати про те, що матрицирования це лише один із кроків у процесі декомпресії)

При більш високих частотах дискретизації, або при роботі зі стереозвуком часу ще менше Хоча на досить швидкому процесорі за допомогою цього

методу можна було б декодувати MPEG файл зі стереозаписью якості CD,

виконувати ще що-небудь в процесі декодування було б важко

Швидке матрицирования

При розробці програми, що виконує швидке матрицирования, ми скористаємося декількома оригінальними рішеннями, про які розповідається в главі 24 Якщо ви, хоча б поверхово, незнайомі з перетвореннями Фурє в цілому і з алгоритмом швидкого перетворення Фурє (ШПФ) зокрема, вам, ймовірно, буде потрібно прочитати главу 24, перш ніж продовжити розпочатий тут розмова (Якщо ви погано розбираєтеся в комплексних числах, то вам краще взагалі пропустити цю главу цілком)

Переписавши формулу матрицирования, варто привести її до виду, почасти подібному з формулою дискретного перетворення Фурє (ДПФ) Після цього можна використовувати описані в 24-й главі методи, що дозволить нам розробити алгоритм, схожий з ШПФ

Щоб переконатися, що формула матрицирования за формою подібна з ДПФ, згадаємо, що cos (x) це дійсна частина показовою функції комплексного числа eix (i квадратний корінь з -1) Тоді я можу переписати формулу для обчислень при матрицирования наступним чином:

31

Vn   = Re al ⎜ ∑

k = 0

S k e

(16 + n )( 2 k +1) π  / 64  ⎞

Ha перший погляд може здатися, що приведення нашої формули до виду, який вимагає використання повільних складних обчислень, тільки ускладнило ситуацію Проте в цілому з показовими функціями працювати набагато простіше, ніж з тригонометричними

Це дозволить нам значно спростити формулу B Зокрема, я можу легко винести за суму частину, яка не залежить від k:

V   = Re al ⎛

31

e i (16 + n ) π  / 64 ∑

k = 0

S k e

(16 + ) 2 kπ / 64  ⎞

Тепер застосуємо одну хитрість пронумеруємо Vn як V16, V17, .., V79 B резуль-

таті ми можемо відкинути член «16 +»:

V   = Re al ⎛

31

e in π  / 64 ∑

k = 0

S k e

iπnk / 32  ⎞

Якщо нам вдасться придумати, як швидко обчислити внутрішню суму, то ми зможемо просто домножити її на константу е “р/64, взяти від результату дійсну частину і назад перенумерувати всі належним чином, отримавши тим самим шуканий результат Отже, потрібен швидкий спосіб обчислення суми

Наша сума дуже схожа на формулу ДПФ, описаного в 24 главі Ми име-

ем справу з одним з окремих випадків перетворення більш загального вигляду:

−1

= 0

S k e

iπnk / N

Це перетворення не є перетворенням Фурє Однак воно досить на нього схоже, тому ми спробуємо використовувати ті ж самі хитрощі B Зокрема, суму можна розкласти на непарну і парну складові:

⎛ ( / 2 ) −1

iπ( 2 ) / N  

⎛ ( / 2 ) −1

iπ( 2 +1) / N  

⎜        S k e

⎟ + ⎜

2 k +1e                

⎝   = 0

⎠    ⎝   = 0                                             ⎠

Слідуючи висновку алгоритму БПФ, запишемо формулу у вигляді двох перетворень-

ний з числом точок N / 2:

( N / 2 )−1

⎜  ∑ k e

⎝   =0

iπnk /( N / 2 ) ⎞

⎟ + e

iπn / N

( N / 2 )−1

+1e

=0

iπnk / N  

Якщо уважно подивитися на цю формулу, стає ясно: визначити перетворення для 32 точок (що нам потрібно) можна шляхом обчислення двох перетворень для 16 точок A то ж саме для 16 точок отримаємо через перетворення для 8 точок і тд B кінці кінців ця формула покаже вам, як з 16 двоточкових перетворень отримати те ж саме для 32 точок

Тепер згадаємо, що перетворення 32 точок дає 64 значення Аналогічним чином перетворення двох точок дає 4 значення Якщо вихідними значеннями є а і b, то двухточечное перетворення дасть нам a + b, a +ib, a-b і a-ib

Грунтуючись на виконану роботу і використовуючи прийоми, описані в 24-й главі, ми можемо побудувати пропонований нижче алгоритм B цієї функції використовуються кілька способів оптимізації роботи, які так ж можуть бути застосовані до реалізації ШПФ, про що йде мова в 24 главі

Лістинг 1417 Матрицирования відліків Layer 1 і Layer 2 швидка версія

// Ha вхід подаються відліки піддіапазонів у форматі 216 static void Matrix (long * V, long * subbandSamples, int numSamples) {

for(int i=numSamplesi&lt32i++)

subbandSamples[i]=0

static const double PI=314159265358979323846

long * workR = V / / Повторне використання V в якості

/ / Робочого сховища

long workI [64] / / Уявна частина

static const, char order[] =

{0,16,8,2 4,4,20,12,28,2,18,10,26,6,22,14,30,

1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31}

/ / B цій частині кроку ініціалізації

/ / Проводиться попереднє обчислення

/ / 2-точкових перетворень (з двох вхідних чотири вихідних)

/ / Користуємося тим, що у вхідних значень є тільки

/ / Дійсна частина

long * pWorkR = workR / / Формат 216

long * pWorkI = workI / / Формат 216

const char *next = order

for(int n=0n&lt16n++) {

long a = subbandSamples[*next++]

long b = subbandSamples[*next++]

*pWorkR++ = a+b *pWorkI++ = 0

*pWorkR++ = a  *pWorkI++ = b

*pWorkR++ = a-b *pWorkI++ = 0

*pWorkR++ = a   *pWorkI++ = b

}

//

Це швидка версія перетворення,

//

описаного в стандарті ISO

//

Використовуються ті ж принципи, що і для БПФ, але наше

//

перетворення перетворенням Фурє HE є

//

Для економії часу заздалегідь обчислюємо

//

всі значення фазових зрушень

static long phaseShiftsR[32], phaseShiftsI[32]    // 114

static bool initializedPhaseShifts = false

if ( initializedPhaseShifts) {/ / Одноразова ініціалізація

for(int i=0i&lt32i++) {       // 114

phaseShiftsR[i] = static_cast&ltlong&gt(163840*cos(i*(PI/

320)))

phaseShiftsI[i] = static_cast&ltlong&gt(163840*sin(i*(PI/

320)))

}

initializedPhaseShifts = true

}

/ / При кожній ітерації відкидається один значущий біт

/ / B результаті отримуємо один зайвий біт,

/ / Захищає від переповнення

int phaseShiftIndex, phaseShiftStep = 8

for(int size=4 size&lt64 size &lt&lt= 1) {

/ / Так як величина першого фазового зсуву завжди дорівнює 1,

/ / Можна скоротити кількість операцій, продублировав цикл,

for(int n=0 n &lt 64 n += 2*size) { long tR = workR[n+size] workR[n+size] = (workR[n] tR)&gt&gt1 workR[n] = (workR[n] + tR)&gt&gt1

long tI = workI[n+size] workI[n+size] = (workI[n] tI)&gt&gt1 workI[n] = (workI[n] + tI)&gt&gt1

}

phaseShiftIndex = phaseShiftStep

for(int fftStep = 1 fftStep &lt size fftStep++) { long phaseShiftR = phaseShiftsR[phaseShiftIndex] long phaseShiftI = phaseShiftsI[phaseShiftIndex] phaseShiftIndex += phaseShiftStep

for(int n=fftStep n &lt 64 n += 2*size) {

long tR = (phaseShiftR*workR[n+size]

phaseShiftI*workI[n+size])&gt&gt14

long tI = (phaseShiftR*workI[n+size]

+ phaseShiftI*workR[n+size])&gt&gt14 workR[n+size] = (workR[n] tR)&gt&gt1 workI[n+size] = (workI[n] tI)&gt&gt1 workR[n] = (workR[n] + tR)&gt&gt1

workI[n] = (workI[n] + tI)&gt&gt1

}

}

phaseShiftStep /= 2

}

/ / Отримуємо остаточні значення V, обробляючи

/ / Отримані в результаті перетворення вихідні значення

{

static long vShiftR[64], vShiftI[64]      // 113 static bool initializedVshift = false

int n

if ( initializedVshift) {/ / Ініціалізіруем тільки

/ / Один раз

for(n=0n&lt32n++) {      // 114 vShiftR[n] =

static_cast&ltlong&gt(163 840*cos((32+n)*(PI/640)))

vShiftI[n] =

static_cast&ltlong&gt(163 840*sin((32+n)*(PI/640)))

}

initializedVshift = true

}

/ / Тепер отримуємо значення V з комплексних чисел,

/ / Отриманих в результаті перетворень

long *pcmR = workR+33       // 612 long *pcmI = workI+33       // 612

V [16] = 0 / / V [16] завжди дорівнює 0

for (n = l n <32; n + +) {/ / V дійсна

/ / Частина, V має формат 69

V[n+16] = (vShiftR[n] * *pcmR++ vShiftI[n] *

*pcmI++)&gt&gt15

}

V [48] = (-workR [0]) >> 1 / / VShift [32] завжди дорівнює -1

/ / Користуємося симетрією

/ / Результату

for(n=0n&lt16n++) V[n] = V[32-n]

for(n=ln&lt16n++) V[48+n] =V[48-n]

}

}

Розглянутий підхід також може використовуватися для розробки альтернативного здійснення операції матрицирования з плаваючою крапкою Перевага застосування чисел з плаваючою точкою полягає в точності Написана

нами програма дозволяє отримати точність тільки до 13-го розряду (з точності в 16 розрядах, якій я хочу добитися для кінцевих результатів) Хоча нові процесори працюють досить швидко для того, щоб розробка MPEG-декодера з плаваючою точкою стала реальністю, розглянута нами целочисленная версія все-таки працює швидше B випадку якщо нам необхідно виробляти додаткову обробку даних у ході декомпресії звуку, це може виявитися корисним

Для конкретики в табл 145 зазначено, скільки потрібно часу для проведення матрицирования 32 значень в декількох різних реалізаціях алгоритму B попередньому розділі я привів безхитрісно програму «повільної» версії в «швидкої» версії використовується алгоритм, розробкою якого ми тільки що займалися Нагадаю, що в таблиці вказано час виконання лише операції матрицирования Зазначу, що для відтворення стереосигнала CD-якості необхідно проводити обробку кожної групи з 32 відліків за 360 мкс

Таблиця 145 Тимчасові характеристики для різних реалізацій операції матрицирования

Процесор Компілятор ОС Цілочисельний З плаваючою точкою

Швидкий Повільний-

Швидкий Повільний-

 ний ний

Intel

486DX2/66

Intel

GCC 272

VC++ 50

FreeBSD21

Windows 95

400

450

1200

1120

720

1390

1100

960

486DX2/66

CW11

Mac OS 76

55

90

103

113

PowerPC

603e/2OO

Intel

VC++50

Windows 95

100

340

230

210

Pentium/90

Час всюди зазначено в мікросекундах

Як ви можете переконатися, оптимізація такого роду в кращому випадку є «чорною магією» Цілочисельна версія, що застосовує алгоритм, описаний в цьому розділі, працює в 2-3 рази швидше (забезпечуючи до 30% збільшення швидкості роботи декодера в цілому) Версії, що використовують арифметику з плаваючою крапкою, поводяться абсолютно по-різному: на другій системі «швидка» реалізація з плаваючою точкою працює на 50% повільніше, ніж «повільна»

Коефіцієнти зважування

B стандарт ISO включена таблиця з 512 девятизначних чисел з плаваючою точкою таблиця коефіцієнтів зважування Показати, що кожне з цих чисел в точності відповідає ступеня числа 1/65536 не вдається Так само не можна сказати, що ця таблиця симетрична, оскільки елементи з 257 по 511 це числа, протилежні числах з 1 по 255, узятим в зворотному порядку Якщо поділити кожне з чисел, представлених в наступній таблиці, на 65 536, то в результаті вийдуть числа з плаваючою точкою, що збігаються із зазначеними в стандарті

Лістинг 1418 Коефіцієнти синтезованого інтервалу для Layer 1 і Layer 2

static long SynthesisWindowCoefficients [] = / / Числа

/ / З фіксованою

/ / Точкою

/ / Формату 216

{0, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -3, -3, -4, -4, -5,

-5, -6, -7, -7, -8, -9, -10, -11, -13, -14, -16, -17, -19, -21,

-24, -26,

-29, -31, -35, -38, -41, -45, -49, -53, -58, -63, -68, -73, -79,

-85, -91, -97, -104, -111, -117, -125, -132, -139, -147, -154,

-161,-169, -176, -183, -190, -196, -202, -208,

213, 218, 222, 225, 227, 228, 228, 227, 224, 221, 215, 208, 200,

189, 177, 163, 146, 127, 106, 83, 57, 29, -2, -36, -72, -111,

-153, -197,-244, -294, -347, -401,

-459, -519, -581, -645, -711, -779, -848, -919, -991, -1064,

-1137, -1210, -1283, -1356, -1428, -1498, -1567, -1634, -1698,

-1759, -1817, -1870, -1919, -1962, -2001, -2032, -2057, -2075,

-2085, -2087, -2080, -2063,

2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131,

970, 794, 605, 402, 185, -45, -288, -545, -814, -1095, -1388,

-1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425,

-4788,

-5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, -7910,

-8209, -8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838,

-9916, -9959, -9966, -9935, -9863, -9750, -9592, -9389, -9139,

-8840, -8492, -8092, -7640, -7134,

6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082, 70, -998, -2122,

-3300, -4533, -5818, -7154, -8540, -9975, -11455, -12980, -14548,

-16155, -17799, -19478, -21189, -22929, -24694, -26482, -28289,

-30112, -31947, -33791, -35640,-37489, -39336, -41176, -43006,

-44821, -46617, -48390, -50137, -51853, -53534, -55178, -56778,

-58333, -59838, -61289, -62684, -64019, -65290, -66494, -67629,

-68692, -69679, -70590, -71420, -72169, -72835, -73415, -73908,

-74313, -74630, -74856, -74992, 75038, 74992, 74856, 74630,

74313,

73908,

73415,

72835,

72169,

71420,

70590,

69679,

68692,

67629,

66494,

65290,

64019,

62684,

61289,

59838,

58333,

56778,

55178,

53534,

51853,

50137,

48390,

46617,

44821,

43006,

41176,

39336,

37489,

35640,

33791,

31947,

30112,

28289,

26482,

24694,

22929,

21189,

19478,

17799,

16155,

14548,

12980,

11455,

9975,

8540, 7154, 5818, 4533, 3300, 2122, 998, -70, -1082, -2037,

-2935, -3776, -4561, -5288, -5959, 6574, 7134, 7640, 8092, 8492,

8840, 9139, 9389, 9592, 9750, 9863, 9935, 9966, 9959, 9916, 9838,

9727, 9585, 9416, 9219, 8998, 8755, 8491, 8209, 7910, 7597, 7271,

6935, 6589, 6237, 5879, 5517, 5153, 4788, 4425, 4063, 3705, 3351,

3004, 2663, 2330, 2006, 1692, 1388, 1095, 814, 545, 288, 45,

-185, -402, -605, -794, -970, -1131, -1280, -1414, -1535, -1644,

-1739, -1822, -1893, -1952, -2000, 2037, 2063, 2080, 2087, 2085,

2075, 2057, 2032, 2001, 1962, 1919, 1870, 1817, 1759, 1698, 1634,

1567, 1498, 1428, 1356, 1283, 1210, 1137, 1064, 991, 919, 848,

779, 711, 645, 581, 519,

459, 401, 347, 294, 244, 197, 153, 111, 72, 36, 2, -29, -57, -83,

-106, -127, -146, -163, -177, -189, -200, -208, -215, -221, -224,

-227, -228, -228, -227, -225, -222, -218,

213, 208, 202, 196, 190, 183, 176, 169, 161, 154, 147, 139, 132,

125, 117, 111, 104, 97, 91, 85, 79, 73, 68, 63, 58, 53, 49, 45,

41, 38, 35, 31,

29, 26, 24,

21, 19, 17,

16, 14, 13,

11, 10, 9, 8, 7, 7, 6, 5, 5,

4, 4, 3, 3,

2, 2, 2, 2,

1, 1, 1, 1,

1, 1}

Джерело: Кінтцель Т Керівництво програміста по роботі зі звуком = A Programmers Guide to Sound: Пер з англ М: ДМК Пресс, 2000 432 с, іл (Серія «Для програмістів»)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*