Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2014:pitch-shifter

Měnič základního kmitočtu audio signálu

Tomáš Smatana, ID: 136583, xsmata00@stud.feec.vutbr.cz

Zadání

Navrhněte zařízení, na jehož vstupu bude připojen zdroj audio signálu (PC, přenosný přehrávač, mikrofon, …) a na výstupu audio zesilovač (sluchátka, reproduktor). Zařízení bude v reálném čase měnit základní kmitočet signálu a tím jeho výšku (pitch shift), výstupní délka signálu zůstane stejná. Stupeň změny kmitočtu bude nastavitelný.


Úvod

Jedním z parametrů zvukového signálu je jeho výška, kterou určuje jeho základní kmitočet. Cílem tohoto projektu je vytvoření zařízení, které bude sloužit ke změně tohoto základního kmitočtu. Hlavním prvkem zařízení bude vývojový kit STM32F4-Discovery. Pomocí pomocných vstupních obvodů se ke kitu připojí libovolný zdroj zvukového signálu se standardním linkovým výstupem např. přenosný audio přehrávač a na výstup libovolný elektroakustický měnič jako třeba sluchátka. Po uvedení zařízení do provozu bude v jeho úvodní konfiguraci na jeho výstupu stejný signál jako na vstupu. Na procházející audio signál nebude mít zařízení žádný vliv. Po použití uživatelského tlačítka, kterým je vývojový kit vybaven, dojde ke změně výšky výstupního signálu. Každým stisknutím se zvýší nebo naopak sníží výška o výšku jednoho půltónu.

Princip změny základního kmitočtu

Jeden ze způsobů, jak dosáhnout změny základního kmitočtu, je rozdílná rychlost mezi nahráváním a přehráváním hudebního signálu. Např. pokud byl magnetofonový pásek nebo gramofonová deska nahrána určitou rychlostí, při jejich poslechu jinou rychlostí dojde ke změně základního kmitočtu. Pokud bude rychlost přehrávání větší, výška zvuku bude vyšší a naopak.

Obdobně to lze řešit v tomto projektu. Analogový vstupní signál se pomocí AD převodníku určitým vzorkovacím kmitočtem převede na digitální a následně se s jiným vzorkovacím kmitočtem převede pomocí DA převodníku opět na analogový. Pro řešení tohoto projektu bude vzorkovací kmitočet DA převodníku konstantní a bude se měnit pouze vzorkovací kmitočet AD převodníku.

Aby bylo možné měnit základní kmitočet oběma směry, použije se tzv. kruhový buffer. Kruhový buffer je pole buněk s jejich konstantním konečným počtem. Počet těchto buněk bude odpovídat počtu vzorků odpovídajících časové délce signálu 20ms při použitém vzorkovacím kmitočtu 44 kHz.

Kruhový buffer

Přicházející vzorky se ze vstupního signálu budou zapisovat do jednotlivých buněk. S určitým zpožděním se budou vzorky číst a následně posílat na výstup. Změnou rychlosti zapisování vzorků dojde ke změně základního kmitočtu.

Z uvedeného principu je jasné, že bude při rozdílné rychlosti čtení a zapisování docházet k vzájemnému předbíhání čtecího a zapisovacího ukazatele. Jak je ukázáno na obrázku, bude to mít vliv na průběh výstupního signálu, kde vznikne zřetelně slyšitelná nespojitost.

Výstupní signál s nespojitostí

Tento problém lze poměrně dobře zmírnit s využitím zachované části starých vzorků a jejich následném sečtení s novými vzorky. Jak by mohl vypadat výsledný průběh signálu v tomto případě lze vidět na obrázku.

Výstupní signál s řešením nespojitosti

Hardware

Pro řešení projektu je využit vývojový kit STM32F4-Discovery od firmy ST Microelectronics, který je osazen procesorem STM32F407VGT6 od stejného výrobce. Podobu vývojového kitu a jeho blokové schéma lze vidět na obrázku.

STM32F4-Discovery Blokové schéma STM32F4-Discovery

Výběr tohoto hardwaru byl tak učiněn, protože pro tento vývojový kit a procesor existuje volně šiřitelné vývojové prostředí a také, protože obsahuje pro daný účel vhodné a potřebné periferie, kterými jsou:

  • 12 bit AD převodník
  • integrovaný audio kodek CS43L22 s DA převodníkem

AD převodník

Pro převod analogového vstupního signálu na digitální je použit AD převodník integrovaný v procesoru STM32F407VGT6. Tento procesor obsahuje celkem tři dvanáctibitové převodníky, přičemž každý má 16 kanálů. Pro potřeby tohoto projektu zpracovávat dva vstupní signály (levý a pravý kanál) je použit převodník ADC1 s kanálem 1 (port PA1) a převodník ADC2 s kanálem 11 (port PC1).

Protože AD převodníky zpracovávají signály s hodnotou v rozmezí mezi 0 V až napájecí napětí procesoru Vdd = 3 V a použitý vstupní signál je symetrický kolem 0 V, je nutno zařadit před převodníky pomocný obvod, který posune stejnosměrnou složku signálu na polovinu napájecího napětí. Výsledné schéma pomocného vstupního obvodu je na obrázku. Skládá se z odporového děliče napětí, vstupním kondenzátorem pro oddělení stejnosměrné složky a ochranné zenerovy diody. Pomocný obvod je stejný pro oba zpracovávané kanály.

Výsledné schéma pomocného obvodu na vstupu AD převodníků

Audio kodek CS43L22

Po procesu zpracovaní signálu slouží pro jeho následný převod na výstupní analogový signál audio kodek CS43L22, který je integrovaný na použitém vývojovém kitu. Jeho zapojení lze vidět na blokovém schématu vývojového kitu. Tento kodek obsahuje 24-bitový DA převodník a výstupní sluchátkový zesilovač.

Blokové schéma

Blokové schéma výsledného zařízení lze vidět na obrázku. Na vstup zařízení je připojen zdroj audio signálu. Audio analogový signál je analogově upraven v pomocném obvodu pro následné zpracování AD převodníky. Vstupní signál je dále přiveden do AD převodníků integrovaných v procesoru. Pro každý zpracovávaný kanál je použitý jeden převodník. Následuje zpracování signálu, při kterém dojde ke změně základního kmitočtu audio signálu. Po zpracování se signál pomocí DA převodníku obsažených v audio kodeku CS43L22 integrovaném na vývojovém kitu převede zpět na analogový signál, který lze napojit na elektroakustický měnič, například sluchátka. Ovládání je prováděno pomocí uživatelského tlačítka umístěného na desce vývojového kitu.

Blokové schéma výsledného zařízení

Software

Program pro mikrokontrolér byl napsán v prostředí programu Em::Blocks 2.30. Pro zjednodušení práce byla kostra programu vygenerována pomocí programu STM32CubeMX.

Softwarové řešení je tvořeno obsluhou AD převodníků ADC1 a ADC2. Tyto převodníky jsou nastaveny pro práci v kontinuálním módu, s maximální rychlostí 2,4 MS/s a DMA přenosem převedené hodnoty do paměti.

Časovač TIM3, je nastaven pro generování přerušení každou 1ns. V obsluze tohoto přerušení se inkrementuje počítadlo. Po dosažení určité hodnoty počítadla se použijí hodnoty získané posledním převodem AD převodníků a umístí se do jednoho prvku pole proměnné jako vzorek do kruhového bufferu. Až se postupně naplní celé pole, začne se pole plnit novými hodnotami od začátku. Tento cyklus probíhá neustále dokola.

Pro přehrání dat z pole hodnot je použit integrovaný kodek CS43L22 na vývojové desce, pomocí kterého se postupně vyčítají hodnoty a to konstantní rychlostí.

Pro změnu základního kmitočtu audio signálu se využívá rozdílný vzorkovací kmitočet mezi AD a DA převodem. V řešeném projektu je vzorkovací kmitočet DA převodníku konstantní a to 44 kHz. Vzorkovací kmitočet AD převodníků se volí vhodným nastavením hodnoty inkrementovaného počítadla v obsluze přerušení časovače, při které se sejme hodnota získaná AD převodem. Pro změnu této hodnoty se používá tlačítko.

Hlavní vytvořené části programu

main.c

int main(void)
{
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_ADC2_Init();
  MX_TIM3_Init();
 
  // Spusteni casovace
  HAL_TIM_Base_Start_IT(&htim3);
 
  // Spusteni AD prevodu a nasledneho DMA prenosu pro oba prevodniky
  if (HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADC1hodnota, 1) != HAL_OK)
  return 0;
 
  if (HAL_ADC_Start_DMA(&hadc2, (uint32_t*)&ADC2hodnota, 1) != HAL_OK)
  return 0;
 
  // Inicializace AUDIO periferie
  BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, 70, 44000);
 
  // Prehrani prvniho useku
  BSP_AUDIO_OUT_Play((uint16_t*)L_kanal, BUFFER_SIZE*2);
 
  while (1)
  {
    // obsluha tlačítka
    while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET)
    {
        HAL_Delay(50);
 
        if(posun < 10)
        {
            posun = posun + 1;
        }
        else
        {
            posun = 5;
        }
 
        HAL_Delay(250);
    }
  }
}

obsluha přerušení časovače

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    static int i = 0;
    static uint16_t j = 0;
 
    if(i < (17 + posun))
    {
        i = i + 1;
    }
    else
    {
        if(j < 880)
        {
            L_kanal[j] = (uint16_t)ADC1hodnota;
            P_kanal[j] = (uint16_t)ADC2hodnota;
 
            j = j + 1;
        }
        else
        {
            j = 0;
 
            L_kanal[j] = (uint16_t)ADC1hodnota;
            P_kanal[j] = (uint16_t)ADC2hodnota;
 
            j = 1;
        }
 
        i = 0;
    }
}

Výsledky

Bylo vyřešeno kompletní zapojení celého zařízení. Pro realizaci vstupního pomocného obvodu bylo použito nepájivé pole.

S funkčností softwaru to nedopadlo nejlépe. Podařilo se zrealizovat pouze první část, kterou je převod vstupního audio signálu do kruhového bufferu a obsluha tlačítka.

Zprovoznit výstupní audio kodek se nepodařilo.

Výsledný vzhled zařízení lze vidět na obrázku.

Výsledná podoba realizace

Závěr

Při realizaci zařízení bylo příliš mnoho času stráveného nad seznámením se a zprovozněním základních periferií mikrokontroléru jako je např. AD převodník a DMA přenos, v důsledku čehož nebyly zprovozněny další potřebné periferie, jako je audio kodek. Pokud by bylo snažší zprovoznění těchto periferií, byly by lépe promyšleny a odladěny záležitosti, jako je třeba velikost a přesnost jednoho kroku změny základního kmitočtu nastavovaného tlačítkem.

2014/pitch-shifter.txt · Poslední úprava: 2015/01/18 23:31 autor: Tomáš Smatana