@@ -19,6 +19,7 @@ static inline void delay_us(unsigned us) {
1919 }
2020}
2121
22+
2223static bool ac97_reset_and_unmute (void ) {
2324 /* Exit cold reset (run): set bit1 in GLOB_CNT. */
2425 outl (g .nabm + AC97_NABM_GLOB_CNT , 0x00000002 );
@@ -35,7 +36,8 @@ static bool ac97_reset_and_unmute(void) {
3536 if (caps & 0x0001 ) {
3637 uint16_t ec = inw (g .nam + AC97_NAM_EXT_CTRL );
3738 outw (g .nam + AC97_NAM_EXT_CTRL , ec | 0x0001 );
38- outw (g .nam + AC97_NAM_PCM_FRONT_RATE , 48000 );
39+ outw (g .nam + AC97_NAM_PCM_FRONT_RATE , 44100 );
40+ dprintf ("ac97: PCM front DAC rate now %u Hz\n" , inw (g .nam + AC97_NAM_PCM_FRONT_RATE ));
3941 }
4042 return true;
4143}
@@ -93,7 +95,7 @@ static bool init_ac97(void) {
9395 }
9496 if (ac97_start (dev )) {
9597 kprintf ("ac97: started\n" );
96- ac97_stream_prepare (4096 /*frag bytes*/ , 48000 /*Hz*/ );
98+ ac97_stream_prepare (4096 , 44100 ); // 44.1khz stereo LE 16 bit
9799 } else {
98100 dprintf ("ac97: start failed\n" );
99101 return false;
@@ -318,8 +320,6 @@ void ac97_idle(void) {
318320 if (s_q_head_fr == s_q_len_fr ) {
319321 s_q_head_fr = 0 ;
320322 s_q_len_fr = 0 ;
321- /* (buffer kept for reuse; free here if you want to release memory when idle) */
322- /* if (s_q_cap_fr > SOME_LIMIT) { kfree(s_q_pcm); s_q_pcm=NULL; s_q_cap_fr=0; } */
323323 }
324324
325325 /* recover from a halted engine if needed (cheap check) */
@@ -330,78 +330,31 @@ void ac97_idle(void) {
330330 }
331331}
332332
333-
334- void ac97_test_melody (void ) {
335- if (!g .bdl || !g .buf || g .bdl_n != 32 || g .frag_frames == 0 || g .frag_bytes == 0 ) {
336- dprintf ("ac97: test_melody: stream not prepared\n" );
337- return ;
338- }
339-
340- /* One ephemeral staging fragment (stereo S16LE). No special alignment needed. */
341- int16_t * frag = kmalloc (g .frag_bytes );
342- if (!frag ) {
343- dprintf ("ac97: test_melody: OOM\n" );
344- return ;
345- }
346-
347- /* Use actual programmed rate if var-rate is enabled; otherwise assume 48k. */
333+ uint32_t ac97_get_hz () {
348334 uint32_t rate = 48000 ;
349335 uint16_t caps = inw (g .nam + AC97_NAM_EXT_CAPS );
350336 if (caps & 0x0001 ) {
351337 if (inw (g .nam + AC97_NAM_EXT_CTRL ) & 0x0001 ) {
352338 rate = inw (g .nam + AC97_NAM_PCM_FRONT_RATE );
353- if (rate == 0 ) rate = 48000 ;
354- }
355- }
356-
357- /* Little square-wave line: A4 B4 C5 E5 D5 C5 B4 A4 A5 (each ~60 ms) */
358- static const uint16_t notes_hz [] = {440 , 494 , 523 , 659 , 587 , 523 , 494 , 440 , 880 };
359- static const uint16_t dur_ms [] = {600 , 600 , 600 , 600 , 600 , 600 , 600 , 600 , 600 };
360- const size_t nnotes = sizeof (notes_hz ) / sizeof (notes_hz [0 ]);
361-
362- const uint32_t F = g .frag_frames ; /* frames per fragment (stereo S16) */
363- size_t total_frames_enqueued = 0 ;
364-
365- for (size_t n = 0 ; n < nnotes ; n ++ ) {
366- const uint32_t freq = notes_hz [n ];
367- uint32_t frames_left = (rate / 1000u ) * dur_ms [n ];
368- if (freq == 0 ) continue ;
369-
370- /* Integer square-wave state */
371- uint32_t period = rate / freq ;
372- if (period == 0 ) period = 1 ;
373- uint32_t halfperiod = period >> 1 ;
374- uint32_t phase = 0 ;
375-
376- while (frames_left > 0 ) {
377- const uint32_t out_frames = (frames_left > F ) ? F : frames_left ;
378-
379- /* Generate exactly out_frames into the staging fragment */
380- for (uint32_t i = 0 ; i < out_frames ; i ++ ) {
381- const int16_t s = (phase < halfperiod ) ? 6000 : (int16_t ) -6000 ;
382- frag [(i << 1 )] = s ; /* L */
383- frag [(i << 1 ) + 1 ] = s ; /* R */
384- if (++ phase >= period ) phase = 0 ;
385- }
386-
387- /* Non-blocking enqueue (zero-pads the tail of the fragment inside ac97_play_s16le) */
388- const size_t pushed = push_all_s16le (frag , out_frames );
389- if (pushed == 0 || pushed < out_frames ) {
390- dprintf ("ac97: test_melody: ring full after %zu frames\n" , total_frames_enqueued );
391- kfree (frag );
392- return ;
339+ if (rate == 0 ) {
340+ rate = 48000 ;
393341 }
394-
395- total_frames_enqueued += pushed ;
396- frames_left -= out_frames ;
397342 }
398343 }
344+ return rate ;
345+ }
399346
400- dprintf ("ac97: test_melody: enqueued %zu frames (~%u ms)\n" ,
401- total_frames_enqueued ,
402- (unsigned ) ((total_frames_enqueued * 1000u ) / rate ));
347+ void ac97_test_melody (void ) {
348+ if (!g .bdl || !g .buf || g .bdl_n != 32 || g .frag_frames == 0 || g .frag_bytes == 0 ) {
349+ dprintf ("ac97: test_melody: stream not prepared\n" );
350+ return ;
351+ }
403352
404- kfree (frag ); /* safe: hardware reads from the DMA ring, not this staging buffer */
353+ fs_directory_entry_t * entry = fs_get_file_info ("/system/webserver/test.raw" );
354+ int16_t * data = kmalloc (entry -> size );
355+ fs_read_file (entry , 0 , entry -> size , (unsigned char * )data );
356+ push_all_s16le (data , entry -> size / sizeof (int16_t ) / 2 );
357+ kfree (data );
405358}
406359
407360/* ===================== Module entry points ===================== */
0 commit comments