DEMO.DESIGN
Frequently Asked Questions
 
оглавление | demo party в ex-СССР | infused bytes e-mag | новости от ib/news | другие проекты | письмо | win koi lat

следующий фpагмент (2)
- [104] Pascal talks (2:5030/84) ------------------------ SU.PASCAL.MODULA.ADA - Msg : 4 of 25 From : Teplitsky Dmitry 2:5020/323 26 Jan 95 10:24:00 To : Konstantin Nazarenko Subj : Управление спикером на САМОМ низком уровне. -------------------------------------------------------------------------------- Hello Konstantin! 25 Jan 95 14:19, Konstantin Nazarenko wrote to All: KN> Хочу сделать subj. Собственно говоря, как происходит сотворение KN> звука? Единичка - на катушку динамика подается напруга, 0 - выкл. KN> Вот так 1-0-1-0... много-много раз. В доках, которыми я обладаю, KN> описано, как управлять схемой 8253, но там нужно сразу задавать KN> желаемую частоту и длительность. А я хочу сам пихать - 1-0-1-0.. KN> , чтоб побитово ;) KN> Возможно ли это? И если да - то как? В общем играет 8и бытные VOC,RAW файлы :) Я вообще-то это дело писал эдак в 92 ... так что стиль :) procedure Speaker(Speed,HowMany:word;Buffer:pointer);assembler; asm push es mov al,0FEh out 21h,al mov al,3 out 61H,al mov al,90h out 43H,al mov dx,1 les si,Buffer cli @1: mov cx,Speed @loopl: loop @LoopL mov al,es:[si] shr al,1 <- это можно заменить на XLAT на табличку от ScreamTracker'а out 42H,al inc DX inc si cmp dx,HowMany jne @1 xor al,al out 21h,al sti pop es end; procedure StopPlay;assembler; asm xor al,al out 61h,al end; Regardz, Teplitsky
следующий фpагмент (3)|пpедыдущий фpагмент (1)
- [53] Available echoes... (2:5030/84) ------------------ REC.GAMES.PROGRAMMER - Msg : 4 of 11 From : slama@slama.pub.hr 2:5030/315 19 Oct 95 07:17:00 To : All Subj : Re: How to play digitial audio through PC speaker -------------------------------------------------------------------------------- X-RealName: Davor Slamnig chenilim@imap1.asu.edu writes: > David Mandala (davidm@them.com) wrote: > : Does anyone have any sample code on playing raw or wav files through the PC > : speaker. We need to play a file but can't figure out how? > > You basically need to: > > 1) Set timer interrupt to a higher rate and "one-shot" mode > 2) Hook the timer interrupt > 3) Play a sequence of bits through the speaker based on > the actual sound level. Do this by varying the next timer > tick duration. > > Eg. > 0 = 0000000 > 64 = 1001001 > 128 = 1010101 > > (or something like that - I'm not too sure) > > Another good method I like is to stretch the range of the data > sound-stream to their extremes and play a 1-bit for values >128 and a 0 > for values <128 (1 byte samples of course). This produces louder samples > at the expense of sound quality. > > - Chen-I Lim > cilim@asu.edu I found a piece of code I that demonstrates both methods that Chen describes. This thread has been going on for quite a while, so I'm posting it. The first method is called pulse position modulation (PPM), and I call the second method "maximum clipping modulation" (MCM). I guess the code could be tweaked to produce better results. PPM is "Hi-fi" (if such a term can be used for this kind of noise) with very low volume. MCM is louder, but really distorted (like the Gremlins sound). Note: The oldest and cheapest sound card will outperform the speaker output immesurably. If you are really low on budget, build an D/A converter and hook it to the paralell port. Have fun Slama /* bzonk.c Davor Slamnig, 10/93 Interrupt driven PC speaker sample player Pulse position & Maximum clipping modulation Plays raw unsigned 8-bit samples BC 3.1 - large model */ #include <dos.h> #include <alloc.h> #include <stdio.h> #include <conio.h> #include <ctype.h> #define TIMER_VEC 0x08 struct s_sample{ unsigned char *buf; long size; }Sample; int Freq[10] = { 27, /* 45 kHz */ 149, /* 8 kHz */ 119, /* 10 kHz */ 99, /* 12 kHz */ 80, /* 15 kHz */ 60, /* 20 kHz */ 48, /* 25 kHz */ 40, /* 30 kHz */ 34, /* 35 kHz */ 30 /* 40 kHz */ }; unsigned char *Intptr, *Intend; int Rate, Intprev = 0, Scut, Scnt; unsigned char Hibits; void interrupt (*oldtimer)(), interrupt (*newtimer)(); void end_play(void) { outportb(0x61, Hibits); /* speaker off */ outportb(0x40, 0xff); /* slow down clock timer to 18.2 Hz */ outportb(0x40, 0xff); setvect(TIMER_VEC, oldtimer); /* restore old clock vector */ } void advance(void) { ++Intptr; if(++Scnt > Scut){ ++Intptr; Scnt = 0; } } void interrupt PPM() { long calc; asm{ cli } if(Intptr < Intend){ calc = (*Intptr * Rate) >> 8; /* adjust pulse range */ outportb(0x42, calc); /* hi byte */ outportb(0x42, 0); /* lo byte */ advance(); } else end_play(); asm { sti } outportb(0x20, 0x20); /* EOI - End Of Interrupt */ } void interrupt MCM() { asm{ cli } if(Intptr < Intend){ /* play */ if(*Intptr > 126){ if(Intprev != 1){ outportb(0x61, Hibits | 2); Intprev = 1; } } else{ if(Intprev != 0){ outportb(0x61, Hibits); Intprev = 0; } } advance(); } else end_play(); asm { sti } outportb(0x20, 0x20); /* EOI - End Of Interrupt */ } void start_play(void) { asm{ cli }; Intptr = Sample.buf; Intend = Intptr + Sample.size; if(newtimer == PPM){ outportb(0x43, 0xb0); /* 8253 timer 2, mode 0 */ outportb(0x61, Hibits | 3); /* couple speaker to timer 2 */ } else{ outportb(0x43, 0xb8); /* 8253 timer 3, mode 4 */ outportb(0x61, Hibits); /* speaker off */ } outportb(0x40, Rate); /* set timer 0 speed */ outportb(0x40, 0); /* high byte */ setvect(8, newtimer); asm{ sti }; } void play_loop(void) { int c; oldtimer = getvect(TIMER_VEC); newtimer = MCM; Hibits = inportb(0x61) & 0xfc; Scnt = 0; Rate = 60; printf("\n Press 0 - 9 to play +|- Change mode\n"); while((c = getch()) != 0x1b){ switch(c){ case '+': newtimer = MCM; break; case '-': newtimer = PPM; break; default: if(isdigit(c)){ Scut = c - '0'; start_play(); } break; } } end_play(); } int load_sample(char *filename) { FILE *fp; if((fp = fopen(filename, "rb")) == NULL){ perror(filename); return 0; } fseek(fp, 0, SEEK_END); Sample.size = ftell(fp); rewind(fp); if((Sample.buf = (unsigned char*)farmalloc(Sample.size)) == NULL){ perror("Can't allocate buffer"); fclose(fp); return 0; } printf("Loading %s\n", filename); fread(Sample.buf, 1, Sample.size, fp); fclose(fp); return 1; } int main(int argc, char *argv[]) { if(argc != 2){ printf("\nUsage: bzonk sample\n"); return 1; } if(!load_sample(argv[1])) return 1; play_loop(); return 0; }

Всего 2 фpагмент(а/ов) |пpедыдущий фpагмент (2)

Если вы хотите дополнить FAQ - пожалуйста пишите.

design/collection/some content by Frog,
DEMO DESIGN FAQ (C) Realm Of Illusion 1994-2000,
При перепечатке материалов этой страницы пожалуйста ссылайтесь на источник: "DEMO.DESIGN FAQ, http://www.enlight.ru/demo/faq".