Mit dieser Library kann der Audio-DAC (CS43L22) vom Discovery-Board benutzt werden um WAV-Files aus dem Flash abzuspielen.
(zum abspielen von MP3-Files gibt es eine extra LIB)
Die WAV-Files müssen im 16bit PCM-Format entweder Mono oder Stereo vorliegen. Und es funktionieren Abtastraten von 8kHz bis 48kHz.
Mit meinem PC-Programm “FileConverter” können beliebige WAV-Files in ein C-Format umgewandelt werden um dieses dann im Projekt hinzufügen zu können.
Der Header vom WAV-File wird vor dem abspielen geprüft und ausgewertet. Falls da was nicht stimmen sollte (z.B. nur 8bit Format) wird eine Fehlernummer zurückgeliefert.
Die WAV kann entweder nur einmal “single” oder endlos “loop” abgespielt werden. Es gibt noch Funktionen für Pause, Resume, Stop und Volume.
Hinweis : Der I2S-Clock und der notwendige PLL muss nicht im “system_stm32f4xx.c-File” eingestellt werden, das wird von der Library erledigt.
Benutzte Pins :
1 2 3 4 5 6 7 | PB9 = SDA PB6 = SCL PA4 = WS PC7 = MCLK PC10 = SCK PC12 = SD PD4 = Reset |
Voraussetzungen :
1 2 | Benutzte Module der CooCox-IDE : SPI, DMA, MISC Benutzte Librarys : STM32_UB_I2C1 |
Enumerationen :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | typedef enum { WAV_OK = 0, // WAVE-Header ist ok WAV_INIT_ERR, // Fehler beim init WAV_SIZE_ERR, // File zu klein WAV_ID_ERR, // RIFF-ID fehlt WAV_ID2_ERR, // WAVE-ID fehlt WAV_ID3_ERR, // fmt-ID fehlt WAV_FMT_LEN_ERR, // falsche Länge von ftm WAV_TYP_ERR, // Typ ist nicht PCM WAV_CH_ERR, // kein Mono oder Stereo WAV_FRQ_ERR, // Fehler bei Samplefrq WAVE_FRAME_ERR, // Fehler im Frame WAVE_BPS_ERR, // Fehler bei Bit per Sample WAVE_ID4_ERR // DATA-ID fehlt }WAV_ERR_t; |
Funktionen :
1 2 3 4 5 6 7 | ErrorStatus UB_CS43L22_Init(void); // init vom CS43L22 WAV_ERR_t UB_CS43L22_PlayWAVSingle(UB_WAV *wav, uint8_t Volume); // PLAY (einmal) WAV_ERR_t UB_CS43L22_PlayWAVLoop(UB_WAV *wav, uint8_t Volume); // PLAY (Endlos) void UB_CS43L22_PauseWAV(void); // PAUSE void UB_CS43L22_ResumeWAV(void); // WEITER (nach Pause) void UB_CS43L22_StopWAV(void); // STOP void UB_CS43L22_SetVolume(uint8_t Volume); // zum einstellen der Lautstärke |
Beispiel :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | //-------------------------------------------------------------- // File : main.c // Datum : 09.06.2013 // Version : 1.0 // Autor : UB // EMail : mc-4u(@)t-online.de // Web : www.mikrocontroller-4u.de // CPU : STM32F4 // IDE : CooCox CoIDE 1.7.0 // Module : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der CS43L22 Library // Hinweis : Diese zwei Files muessen auf 8MHz stehen // "cmsis_boot/stm32f4xx.h" // "cmsis_boot/system_stm32f4xx.c" //-------------------------------------------------------------- #include "main.h" #include "stm32_ub_led.h" #include "stm32_ub_cs43l22.h" int main(void) { ErrorStatus check; SystemInit(); // Quarz Einstellungen aktivieren // init der LEDs UB_Led_Init(); // init vom CS43L22 check=UB_CS43L22_Init(); if(check==SUCCESS) { UB_Led_On(LED_GREEN); // abspielen der WAV in einer Endlosloop UB_CS43L22_PlayWAVLoop(&m32k16b_wav, 70); } else { UB_Led_On(LED_RED); } while(1) { } } |
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download :
Hier das PC-Programm zum umwandeln von WAV-Files in C-Files zum Download :
Hey,
danke für das tolle Projekt. Deine Demo funktioniert wunderbar.
Wenn ich aber selbst ein File einbinde, bleiben die Kopfhörer still. Ich habe eine MP3 mit Audacity eingelesen, gekürzt und dann als Wave 16-Bit PCM exportiert(44,1kHz Samplerate). Mit deinem Programm problemlos in *.c gewandelt, im Projekt eingebunden und programmiert. Die hex-Daten sehen gut aus, zumindest immer veränderliche Werte und im Betrieb geht auch die grüne Led an.
Hast du eine Idee, wo ich den fehler mache?
schwer zu sagen, sende mir einfach mal das original WAV-File zu, vlt finde ich den Fehler.
du hast das Problem ja mittlerweile gelöst aber hier zur Info. Der WAV-Header von deinem File entspricht nicht dem standard und die Funktion “UB_CS43L22_PlayWAVLoop” wirft eine Fehlermeldung….die aber blöderweise in meinem Beispiel-Programm nicht angezeigt wird da sollte man vlt. noch den Rückgabewert auswerten !
Achso, das hatte ich dann auch vermutet. Da ist wohl etwas bei der Umwandlung mp3->wav schief gelaufen. Danke fürs schauen. Die leuchtende grüne Led hat mich verwirrt, da sie zu unrecht geleuchtet hat, auch wenn die mit meinem Fehler gar nix zu tun hatte.
Thank you very much for this (sorry I only know English).
What is the “required format” for the wave files. I have the same issue as Tobias.
This library is just what I have been looking for
The Sound-File-Format must be “PCM” with no compression, and 16bit per Sample
Channels : mono or stereo, SamplFrq : 8kHz to 48kHz
Please check the return value of the function “UB_CS43L22_PlayWAVLoop”
to locate an error in the WAV-Header
Hey,
First of all thank you for this website, it has greatly improved my understanding of the STM32F4 discovery board.
I’m working on a project where i want to record audio (using the MP45DT02 mic) and save it as a WAV file on a USB stick. After this i want to use the Audio-DAC (CS43L22) to play the recorded file. I have used a combination of Demo_32_USB_MSC_HOST, Demo_47_MP45DT02, Demo_54_USB_MP3 and this one to achieve this. I’m having some trouble with the last step, i don’t know how i can acces the recorded file. Maybe you can help me?
Again, thanks for everything.
Greetings, Sidney
Hi, the MP45DT02-Lib saves the audio as WAV-File (not MP3) please test on a first step that this file is ok. You can play it on a pc to verify that. In a second step you have to change the CS43L22-Lib to play the WAV from USB instead of FLash.
Hey, thanks for the response. Sorry i didn’t reply sooner, but my computer crashed. Right now i have recorded a WAV file on the USB using the UB_MP45DT02_RecordLoop function from the Demo_47_MP45DT02 library. Now i want to use the UB_CS43L22_PlayWAVLoop function to play the recording. The PlayWAVLoop function requires a “UB_WAV” input. I don’t know how i can acces the recording and change it to meet this requirement. Hopefully you can help me with this problem.
Hi, please ignore my previous question. Where do i have to change the CS43L22-Lib to play the WAV from USB instead of FLash? Thank you.
please have a look at the function “UB_CS43L22_PlayWAVSingle”
you need to call two functions :
1. UB_AUDIO_InitNew()
2. EVAL_AUDIO_Play()
The “init” defines the output, volume and samplerate.
The “play” plays the wav-file.
But you have to call the play function in a loop
becouse you must load the wav-file from usb
in little packets so you need a buffer
like this
Hi, thank you for your answer. I have changed the “UB_CS43L22_PlayWAVSingle” function like you told me, but there is still no sound from the device.
My code:
WAV_ERR_t UB_CS43L22_PlayWAVSingle(uint8_t Volume)
{
WAV_ERR_t ret_wert=WAV_INIT_ERR;
UB_WAV wav_file;
UB_WAV * wav_file_pt;
FATFS_t controle;
FATFS_t buffer_check;
FIL recording;
uint8_t wav_buff[256]="0";
if((cs43l22_status==CS43L22_INIT_OK) || (cs43l22_status==CS43L22_STOP)) {
// check vom WAV-Header
wav_start = wav_buff;
wav_file_pt = &wav_file;
controle=UB_Fatfs_OpenFile(&recording,“test16k.wav“,F_RD);
buffer_check=UB_Fatfs_ReadBlock(&recording,wav_start,256,wav_file.size);
wav_file.size = UB_Fatfs_FileSize(&recording);
wav_file.table = wav_start;
ret_wert=P_CS43L22_CheckWAV(wav_file_pt);
if(ret_wert==WAV_OK) {
cs43l22_status=CS43L22_PLAY;
wav_loop=0; // single play
wav_start=wav_file.table[my_wav.data_start];
if(my_wav.channels==2) {
// stereo
UB_AUDIO_InitNew(OUTPUT_DEVICE_HEADPHONE, Volume, my_wav.samplerate);
}
else {
// mono
UB_AUDIO_InitNew(OUTPUT_DEVICE_HEADPHONE, Volume, my_wav.samplerate/2);
}
UB_Led_On(LED_BLUE);
EVAL_AUDIO_Play((uint16_t*)wav_start, 256);
wav_start = wav_buff;
while(buffer_check!=FATFS_EOF)
{
buffer_check=UB_Fatfs_ReadBlock(&recording,wav_start,256,wav_file.size);
EVAL_AUDIO_Play((uint16_t*)wav_start, 256);
wav_start = wav_buff;
}
}
}
return(ret_wert);
}
Sorry, more readable:
http://pastebin.com/ZrRA2wHz
Hallo,
ich gebe ein sehr kurzes File wieder: 16 Bit mono 44,1kHz ca. 4000 Werte.
Habe dein Projekt direkt in CoIDE genommen und dann den Inhalt
deines Audio-Files gegen mein kurzes getauscht.
Nun spielt er erst mein kurzes, dann aber das lange von dir (ist wohl noch im Flash!).
Hab dann trotzdem es in mein Projekt kopiert. Nun stürzt nach Aufruf
UB_CS43L22_PlayWAVSingle(&File1, 255);
irgend es ab (es werden Variablen und Ports überschrieben…).
Das Audio-File wird fehlerlos erkannt.
Woran könnte das liegen?
hast du nur die Daten mit einem Editor ersetzt ?
Du musst dein WAV-File mit meinem FileConverter in ein C-File
wandeln, damit wird auch die Längenangabe mit gespeichert.
in deinem Fall die 4000 Bytes.
ah, – noch ne Frage
wie kommt die Audio-Datei ins Flash?
Wie geht es, dass direkt aus dem Flash wiedergegeben wird?
Gibt es eine Einstellung in CoIDE?
Habe “const” benutzt, aber dann wird nach Reset nur die const Daten ins RAM
kopiert und dann von dort wiedergegeben.
mit der Angabe “const” landen die Daten im Flash. 880 kByte würden auch schlecht ins RAM vom F4 passen