restore old ac97wav.c

git-svn-id: svn://kolibrios.org@577 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2007-07-10 23:05:34 +00:00
parent 268f6d98b7
commit 94ec5d65c8
2 changed files with 273 additions and 543 deletions

View File

@ -19,24 +19,13 @@
#include "../mpg/mpg123.h"
#include "../sound.h"
typedef struct
{
int sender;
int size;
int code;
char data[1];
} IPC;
int ipc_client = 0;
#define MP3_ERROR_OUT_OF_BUFFER 5
int m_last_error;
void _stdcall thread_proc(void *param);
void _stdcall create_thread(void *proc, void *param, int stack_size);
void _stdcall init_ipc(void);
void _stdcall send_ipc(int dst, DWORD code);
IPC * _stdcall recieve_ipc(void);
void touch(char *buf, int size);
int mp3FindSync(byte* buf, int size, int* sync);
@ -47,16 +36,9 @@ char *fname;
struct reader rd;
struct frame fr;
void draw_window();
void draw_progress_bar();
void do_ipc();
void exit();
DWORD hDrv;
DWORD hSound;
SNDBUF hBuff;
volatile int snd_init=0;
CTRL_INFO info;
@ -68,7 +50,6 @@ int r_vol=-700;
int pan =0;
DWORD status;
DWORD offset;
DWORD first_sync;
unsigned char *testbuff;
@ -81,108 +62,310 @@ int outsize;
int outremain;
int totalout;
int done;
char path[1024];
char header[] = "AC97 MP3 player";
char buttons_text[]=" Play Stop << >> Vol- Vol+";
void (*snd_play)();
void draw_window()
{
BeginDraw();
DrawWindow(100,100,299,72,0x404040,3,0,0,0);
make_button(7,24,45,13, 0x10|BT_NORMAL,0x808080);
make_button(56,24,45,13, 0x11|BT_NORMAL,0x808080);
make_button(104,24,45,13, 0x12|BT_NORMAL,0x808080);
make_button(152,24,45,13, 0x13|BT_NORMAL,0x808080);
make_button(200,24,45,13, 0x14|BT_NORMAL,0x808080);
make_button(248,24,45,13, 0x15|BT_NORMAL,0x808080);
make_button(7,41,286,11, 0x30|BT_HIDE|BT_NOFRAME,0x404040);
draw_bar(7,41,286,11,0x404040);
draw_bar(7,55,286,11,0x404040);
write_text(12,58,0x004000|FONT0, fname, strlen(fname));
write_text(11,57,0x00FF20|FONT0, fname, strlen(fname));
write_text(8,8,0xFFFFFF|FONT0, header, strlen(header));
write_text(12,28,0x404040|FONT0,buttons_text,strlen(buttons_text));
write_text(11,27,0xA0FFA0|FONT0,buttons_text,strlen(buttons_text));
EndDraw();
};
void draw_progress_bar()
{ DWORD x;
x = 287.0f * (float)(rd.filepos-rd.strremain)/(float)fileinfo.size;
if(x==0) return;
draw_bar(7,41,x,11,0xA0A0A0);
draw_bar(x+7,41,287-x,11,0x404040);
};
void debug_out_str(char* str)
{
while (*str != 0)
{
debug_out(*str);
str++;
}
}
int main(int argc, char *argv[]) //int argc, char *argv[])
{
DWORD fmt;
DWORD r_bytes;
int retval;
int err;
int ver;
int evnt;
int key;
int pos;
int msg;
int cnt;
IPC *incom;
_asm
{
mov eax, 40
mov ebx, 0x47 ;recieve ipc
int 0x40
mov eax, 66
mov ebx, 1
mov ecx, 1
int 0x40
fname = argv[1];
debug_out_str("\n\rPlay file ");
debug_out_str(fname);
debug_out_str("\n\r");
InitHeap(1024*1024);
if(get_fileinfo(fname, &fileinfo)==FILE_NOT_FOUND)
{ debug_out_str("\n\rfile not found\n\r");
return 0;
};
init_ipc();
InitHeap(0);
if(err = InitSound(&ver))
{ debug_out_str("Sound service not installed\n\r");
{
debug_out_str("Sound service not installed\n\r");
return 0;
}
if( (SOUND_VERSION>(ver&0xFFFF)) ||
(SOUND_VERSION<(ver >> 16)))
{ debug_out_str("Sound service version mismatch\n\r");
{
debug_out_str("Sound service version mismatch\n\r");
return 0;
}
make_decode_tables(32767);
init_layer2();
init_layer3(32);
fr.single = -1;
outremain = 0x40000 ;
if( !(outbuf=UserAlloc(outremain)))
return 0;
touch(outbuf, outremain);
if ( !(testbuff=UserAlloc(4096)))
return 0;
if (! (inpbuf=UserAlloc(0x10000)))
return 0;
testbuff = UserAlloc(4096);
get_fileinfo(fname, &fileinfo);
r_bytes=0;
retval=read_file (fname,testbuff,0,2048,&r_bytes);
if ( retval && (r_bytes==0))
return 0;
inpbuf = UserAlloc(0x10000);
touch(inpbuf, 0x10000);
create_reader(&rd, inpbuf, 0x10000);
init_reader(&rd,fname);
fname = argv[1];
if(get_fileinfo(fname, &fileinfo)==FILE_NOT_FOUND)
fmt = test_wav((WAVEHEADER*)testbuff);
if (fmt != 0)
{
_asm
{
mov eax, 23
mov ebx, 100
int 0x40
mov [msg], eax
}
if (msg != 7)
{
debug_out_str("\n\rfile not found\n\r");
return 0;
};
incom = recieve_ipc();
if(incom->code != 'CNCT')
{
debug_out_str("\n\rinvalid ipc code\n\r");
status = ST_EXIT;
return 0;
};
ipc_client = incom->sender;
send_ipc(ipc_client,'CNCT');
snd_play = &play_wave;
set_reader(&rd, 44);
outbuf = UserAlloc(32*1024);
touch(outbuf, 32768);
}
else
{ fmt = test_mp3(testbuff);
if(fmt ==0) return 0;
snd_play = &play_mp3;
outremain = 0x40000 ;
outbuf = UserAlloc(outremain);
touch(outbuf, outremain);
make_decode_tables(32767);
init_layer2();
init_layer3(32);
fr.single = -1;
};
status = ST_PLAY;
snd_init=0;
if (err = CreateBuffer(fmt,0, &hBuff))
{
debug_out_str("create buffer return error\n\r");
; return 0;
}
SetVolume(hBuff,l_vol,r_vol);
GetVolume(hBuff,&l_vol,&r_vol);
create_thread(thread_proc, 0, 4096);
for(snd_init=0,cnt=100; (snd_init==0)&&(cnt!=0); cnt--)
delay(10);
if (!snd_init)
return 0;
draw_window();
while(1)
{ delay(10);
switch(status)
{ case ST_PLAY:
snd_play();
continue;
case ST_STOP:
StopBuffer(hBuff);
status = ST_DONE;
continue;
case ST_EXIT:
StopBuffer(hBuff);
DestroyBuffer(hBuff);
return 0;
};
};
return 0;
};
void touch(char *buf, int size)
{ int i;
char a;
for ( i = 0;i < size; i+=4096)
a = buf[i];
};
DWORD test_mp3(char *buf)
{ unsigned long hdr;
WAVEHEADER whdr;
while (1)
{ if(rd.filepos > 102400)
return 0;
if(!rd.head_read(&rd,&hdr))
return 0;
if(!decode_header(&fr,hdr))
{ rd.strpos-=3;
rd.stream-=3;
rd.strremain+=3;
continue;
};
break;
};
first_sync = rd.filepos-rd.strremain-4;
whdr.riff_id = 0x46464952;
whdr.riff_format = 0x45564157;
whdr.wFormatTag = 0x01;
whdr.nSamplesPerSec = freqs[fr.sampling_frequency];
whdr.nChannels = 2; //mpginfo.channels;
whdr.wBitsPerSample = 16;
return test_wav(&whdr);
};
void play_mp3()
{ char *outPtr;
int totalout;
int outcount;
// memset(&fr,0,sizeof(fr));
fr.down_sample_sblimit = 32;
fr.single = -1;
reset_mpg();
outPtr = outbuf;
totalout=0;
done = 0;
outremain=0x40000;
memset(outbuf,0,0x40000);
set_reader(&rd, 0); //;first_sync);
while(1)
{ if(status!=ST_PLAY)
break;
for(;;)
{ outcount = 0;
if( !read_frame(&rd, &fr))
{ done = 1;
break;
};
fr.do_layer(&fr, outPtr,&outcount);
outPtr+= outcount;
totalout+=outcount;
outremain-=outcount;
if(outremain < outcount*2)
break;
};
if(done)
{ if(totalout < 4096)
{ memset(outPtr,0,4096-totalout);
totalout = 4096;
};
}
else
if(totalout < 8192)
continue;
outPtr = outbuf;
while (totalout >= 4096)
{
WaveOut(hBuff,outPtr,4096);
if(status!=ST_PLAY)
{ if(status != ST_EXIT)
status = ST_STOP;
return;
};
totalout-=4096;
outPtr+=4096;
outremain+=4096;
};
if(done)
break;
memmove(outbuf,outPtr, totalout);
outPtr = outbuf+totalout;
}
if(status != ST_EXIT)
status = ST_STOP;
};
void play_wave()
{ int retval;
set_reader(&rd,44);
retval = 0;
while(1)
{
if(status!=ST_PLAY)
break;
if( !stream_read_raw(&rd,outbuf,32768))
{ done = 1;
break;
};
WaveOut(hBuff,outbuf,32768);
};
if(status != ST_EXIT)
status = ST_STOP;
};
void snd_stop()
{
StopBuffer(hBuff);
};
void _stdcall thread_proc(void *param)
{ int evnt;
int pos;
int key;
DWORD offset;
_asm
{
mov eax, 66
mov ebx, 1
mov ecx, 1
int 0x40
};
draw_window();
while(1)
{ if(status==ST_PLAY)
{ draw_progress_bar();
evnt = wait_for_event(80);
@ -285,330 +468,14 @@ int main(int argc, char *argv[]) //int argc, char *argv[])
draw_progress_bar();
break;
};
break;
case EV_IPC:
do_ipc();
break;
};
};
return 0;
};
void draw_window()
{
BeginDraw();
DrawWindow(100,100,299,72,0x404040,3,0,0,0);
make_button(7,24,45,13, 0x10|BT_NORMAL,0x808080);
make_button(56,24,45,13, 0x11|BT_NORMAL,0x808080);
make_button(104,24,45,13, 0x12|BT_NORMAL,0x808080);
make_button(152,24,45,13, 0x13|BT_NORMAL,0x808080);
make_button(200,24,45,13, 0x14|BT_NORMAL,0x808080);
make_button(248,24,45,13, 0x15|BT_NORMAL,0x808080);
make_button(7,41,286,11, 0x30|BT_HIDE|BT_NOFRAME,0x404040);
draw_bar(7,41,286,11,0x404040);
draw_bar(7,55,286,11,0x404040);
write_text(12,58,0x004000|FONT0, fname, strlen(fname));
write_text(11,57,0x00FF20|FONT0, fname, strlen(fname));
write_text(8,8,0xFFFFFF|FONT0, header, strlen(header));
write_text(12,28,0x404040|FONT0,buttons_text,strlen(buttons_text));
write_text(11,27,0xA0FFA0|FONT0,buttons_text,strlen(buttons_text));
EndDraw();
};
void draw_progress_bar()
{ DWORD x;
x = 287.0f * (float)(rd.filepos-rd.strremain)/(float)fileinfo.size;
if(x==0) return;
draw_bar(7,41,x,11,0xA0A0A0);
draw_bar(x+7,41,287-x,11,0x404040);
};
void debug_out_str(char* str)
{
while (*str != 0)
{
debug_out(*str);
str++;
}
}
void touch(char *buf, int size)
{ int i;
char a;
for ( i = 0;i < size; i+=4096)
a = buf[i];
};
DWORD test_mp3(char *buf)
{ unsigned long hdr;
WAVEHEADER whdr;
while (1)
{ if(rd.filepos > 102400)
return 0;
if(!rd.head_read(&rd,&hdr))
return 0;
if(!decode_header(&fr,hdr))
{
if((hdr & 0xffffff00) == 0x49443300)
{
int id3length = 0;
id3length = parse_new_id3(&rd, hdr);
continue;
};
rd.strpos-=3;
rd.stream-=3;
rd.strremain+=3;
continue;
};
break;
};
first_sync = rd.filepos-rd.strremain-4;
whdr.riff_id = 0x46464952;
whdr.riff_format = 0x45564157;
whdr.wFormatTag = 0x01;
whdr.nSamplesPerSec = freqs[fr.sampling_frequency];
whdr.nChannels = 2; //mpginfo.channels;
whdr.wBitsPerSample = 16;
return test_wav(&whdr);
};
void play_mp3()
{ char *outPtr;
int totalout;
int outcount;
fr.down_sample_sblimit = 32;
fr.single = -1;
reset_mpg();
outPtr = outbuf;
totalout=0;
done = 0;
outremain=0x40000;
memset(outbuf,0,0x40000);
set_reader(&rd, 0); //;first_sync);
while(1)
{ if(status!=ST_PLAY)
break;
for(;;)
{ outcount = 0;
if( !read_frame(&rd, &fr))
{ done = 1;
break;
};
fr.do_layer(&fr, outPtr,&outcount);
outPtr+= outcount;
totalout+=outcount;
outremain-=outcount;
if(outremain < outcount*2)
break;
};
if(done)
{ if(totalout < 4096)
{ memset(outPtr,0,4096-totalout);
totalout = 4096;
};
}
else if(totalout < 8192) continue;
outPtr = outbuf;
while (totalout >= 4096)
{
WaveOut(hBuff,outPtr,4096);
if(status!=ST_PLAY)
{ StopBuffer(hBuff);
return;
};
totalout-=4096;
outPtr+=4096;
outremain+=4096;
};
if(done)
{ status = ST_STOP;
if( ipc_client)
send_ipc(ipc_client,'DONE');
return;
}
memmove(outbuf,outPtr, totalout);
outPtr = outbuf+totalout;
};
};
int play_track(char *path)
{
DWORD fmt;
DWORD r_bytes;
int retval;
int err;
// int err;
retval = ST_DONE;
get_fileinfo(path, &fileinfo);
offset = 0;
err=read_file (path,testbuff,0,2048,&r_bytes);
if (err)
return ST_DONE;
init_reader(&rd,path);
fmt = test_wav((WAVEHEADER*)testbuff);
if (fmt != 0)
{
snd_play = &play_wave;
set_reader(&rd, 44);
retval = ST_PLAY;
}
else
{ fmt = test_mp3(testbuff);
if(fmt ==0)
return ST_DONE;
snd_play = &play_mp3;
outremain = 0x40000;
retval = ST_PLAY;
};
SetFormat(hBuff, fmt);
return retval;
};
void play_wave()
{ int retval;
set_reader(&rd,44);
retval = 0;
while(1)
{
if(status!=ST_PLAY)
break;
if( !stream_read_raw(&rd,outbuf,32768))
{ done = 1;
break;
};
WaveOut(hBuff,outbuf,32768);
};
if(status != ST_EXIT)
status = ST_STOP;
};
void snd_stop()
{
StopBuffer(hBuff);
};
void do_ipc()
{
IPC *incom;
incom = recieve_ipc();
switch(incom->code)
{
case 'PLAY':
fname = incom->data;
status = ST_TRACK;
return;
case 'STOP':
status = ST_STOP;
return;
case 'EXIT':
status = ST_EXIT;
exit();
};
};
void _stdcall thread_proc(void *param)
{
int err;
if (err = CreateBuffer(PCM_ALL|PCM_OUT,0, &hBuff))
{
debug_out_str("create buffer return error\n\r");
exit();
};
SetVolume(hBuff,l_vol,r_vol);
GetVolume(hBuff,&l_vol,&r_vol);
// debug_out_hex(l_vol);
// debug_out_str("\n\r");
// debug_out_hex(r_vol);
// debug_out_str("\n\r");
if(fname[0] !='/0')
status = play_track(fname);
debug_out_str("\n\rPlay file ");
debug_out_str(fname);
debug_out_str("\n\r");
snd_init = 1;
while(1)
{ delay(10);
switch(status)
{
case ST_TRACK:
strcpy(path, fname);
status = play_track(fname);
if( ipc_client & (status == ST_DONE))
{ send_ipc(ipc_client,'DONE');
continue;
};
case ST_PLAY:
snd_play();
continue;
case ST_STOP:
StopBuffer(hBuff);
status = ST_DONE;
continue;
case ST_EXIT:
StopBuffer(hBuff);
DestroyBuffer(hBuff);
if (ipc_client)
send_ipc(ipc_client,'EXIT');
return;
};
};
};
void delay (int val)
{
_asm
{ mov eax,5
{ mov eax,5
mov ebx, [val]
int 0x40
};

View File

@ -19,10 +19,6 @@ public _write_text@20
public _debug_out@4
public _debug_out_hex@4
public _create_thread@12
public _init_ipc@0
public _recieve_ipc@0
public _send_ipc@8
public _memset
@ -397,95 +393,6 @@ toend:
ret
public _allmul
_allmul:
mov eax, [esp+8]
mov ecx, [esp+16]
or ecx,eax
mov ecx, [esp+12]
jnz .hard
mov eax, [esp+4]
mul ecx
ret 16
.hard:
push ebx
mul ecx
mov ebx,eax
mov eax, [esp+8]
mul dword [esp+20]
add ebx,eax
mov eax,[esp+8]
mul ecx
add edx,ebx
pop ebx
ret 16
align 4
_allshr:
cmp cl,64
jae .sign
cmp cl, 32
jae .MORE32
shrd eax,edx,cl
sar edx,cl
ret
.MORE32:
mov eax,edx
sar edx,31
and cl,31
sar eax,cl
ret
.sign:
sar edx,31
mov eax,edx
ret
public __ftol2_sse
align 4
__ftol2_sse:
push ebp
mov ebp, esp
sub esp, 20
and esp, 0xFFFFFFF0
fld st0
fst dword [esp+18]
fistp qword [esp+10]
fild qword [esp+10]
mov edx, [esp+18]
mov eax, [esp+10]
test eax, eax
jz .QnaNZ
.not_QnaNZ:
fsubp st1, st0
test edx, edx
jns .pos
fstp dword [esp]
mov ecx, [esp]
xor ecx, 0x80000000
add ecx, 0x7FFFFFFF
adc eax, 0
mov edx, [esp+14]
adc edx, 0
jmp .exit
.pos:
fstp dword [esp]
mov ecx, [esp]
add ecx, 0x7FFFFFFF
sbb eax, 0
jmp .exit
.QnaNZ:
mov edx, [esp+14]
test edx, 0x7FFFFFFF
jne .not_QnaNZ
fstp dword [esp+18]
fstp dword [esp+18]
.exit:
leave
ret
public __fltused
__fltused dd 0
@ -497,49 +404,5 @@ align 4
fileio FILEIO
align 4
_init_ipc@0:
push ebx
mov eax, 60
mov ebx, 1
mov ecx, ipc_buff
mov edx, (5*4+1024)
int 0x40
pop ebx
ret
align 4
_recieve_ipc@0:
mov [ipc_buff.size], 8
mov eax, ipc_buff.sender
ret
align 4
proc _send_ipc@8 stdcall, dst:dword, code:dword
push ebx
push esi
mov eax, 60
mov ebx, 2
mov ecx, [dst]
lea edx, [code]
mov esi, 4
int 0x40
pop esi
pop ebx
ret
endp
;align 4
;ipc_ctrl:
; .pid dd ?
; .size dd 4
; .msg dd ?
align 4
ipc_buff:
.lock dd 0
.size dd 8
.sender dd ?
.msg_size dd ?
.msg dd ?
.data rb 1024