مشاهده دست آورد نظرسنجی: مباحث این تاپیک ادامه داشته باشد و در صورت ادامه کدام ی

رای دهنده
3. شما نمی توانید در این رای گیری رای بدهید
  • پایان فعالیت تاپیک

    0 0%
  • ادامه بحث با پورت موازی

    1 33.33%
  • ادامه بحث با پورت سریال

    2 66.67%
نمایش نتایج 1 تا 40 از 85

نام تاپیک: آموزش ارتباط با سخت افزار

Threaded View

پست قبلی پست قبلی   پست بعدی پست بعدی
  1. #11
    کاربر دائمی آواتار amin1softco
    تاریخ عضویت
    شهریور 1386
    محل زندگی
    پای آن سرو بلند
    پست
    1,832

    نقل قول: آموزش ارتباط با سخت افزار

    نقل قول نوشته شده توسط bidemajnoon مشاهده تاپیک
    سوال:
    چه جوری می شه به میکروفن وصل شد و ازش اطلاعات صوتی گرفت؟
    گرچه یکمی دیره اما این سورس رو ببین :

    /************************************************** **************************
    ** WARNING: You need at least a COMPACT memory model to run this. **
    ************************************************** ***************************
    ** Demonstration of recording a WAV file through the Sound Blaster **
    ** by Steven H Don **
    ** **
    ** For questions, feel free to e-mail me. **
    ** **
    ** shd@earthling.net **
    ** http://shd.cjb.net **
    ** **
    ************************************************** **************************/
    //Include files
    #include "ALLOC.H"
    #include "DOS.H"
    #include "MEM.H"
    #include "CONIO.H"
    #include "STDIO.H"

    #define CD 2
    #define Microphone 4
    #define LineIn 5

    //The simplest header a WAV file can have is this:
    struct SimpleHeader {
    long RIFF;
    long NextChunkSize;
    long WAVE;
    long fmt;
    long fmtDataLength;
    short WaveType;
    short Channels;
    long SampleRate;
    long BytesPerSecond;
    short BlockAlignment;
    short BitResolution;
    long data;
    long SoundLength;
    } Header;

    char Key;
    unsigned int WBuffer; //Write Buffer indicator
    unsigned char *DMABuffer; //Pointer to DMA Buffer

    unsigned int DMA; //The DMA channel
    unsigned int IRQ; //The IRQ level
    unsigned int Base; //Sound Blaster base address, Word

    //Pointers to old interrupt routines
    #ifdef __cplusplus
    void interrupt (*OldIRQ)(...);
    #else
    void interrupt (*OldIRQ)();
    #endif

    FILE *WAVFile; //Handle of the WAV file}
    long Recorded; //Amount of samples recorded}

    /************************************************** **************************
    ** Checks to see if a Sound Blaster exists at a given address, returns **
    ** true if Sound Blaster found, false if not. **
    ************************************************** **************************/
    int ResetDSP(unsigned int Test)
    {
    //Reset the DSP
    outportb (Test + 0x6, 1);
    delay(10);
    outportb (Test + 0x6, 0);
    delay(10);
    //Check if (reset was succesfull
    if (((inportb(Test + 0xE) & 0x80) == 0x80) && (inportb(Test + 0xA) == 0xAA))
    {
    //DSP was found
    Base = Test;
    return (1);
    }
    else
    //No DSP was found
    return (0);
    }

    /************************************************** **************************
    ** Send a byte to the DSP (Digital Signal Processor) on the Sound Blaster **
    ************************************************** **************************/
    void WriteDSP(unsigned char Value)
    {
    //Wait for the DSP to be ready to accept data
    while ((inportb(Base + 0xC) & 0x80) == 0x80);
    //Send byte
    outportb (Base + 0xC, Value);
    }

    /************************************************** **************************
    ** Writes a value to the SB's mixer chip **
    ************************************************** **************************/
    void WriteMixer (unsigned char R, unsigned char V)
    {
    outportb (Base + 4, R);
    outportb (Base + 5, V);
    }

    /************************************************** **************************
    ** Selects the source device for recording. **
    ** Valid values are: Microphone, CD and LineIn **
    ************************************************** **************************/
    void SelectSource (char Source)
    {
    //For older SB's
    WriteMixer (0xC, Source);
    //For newer SB's
    {
    //Disable right channel
    WriteMixer (0x3E, 0);
    //Record all sound through left channel
    switch (Source) {
    case Microphone : WriteMixer (0x3D, 1); break;
    case CD : WriteMixer (0x3D, 6); break;
    case LineIn : WriteMixer (0x3D, 24); break;
    }
    //Set volume of whatever is recording to full
    switch (Source) {
    case Microphone : WriteMixer (0x0A, 7); break;
    case CD : WriteMixer (0x28, 255); break;
    case LineIn : WriteMixer (0x2E, 255); break;
    }
    //Allow line and CD to be heard through speakers, but not microphone}
    switch (Source) {
    case Microphone : WriteMixer (0x3C, 0); break;
    case CD : WriteMixer (0x3C, 6); break;
    case LineIn : WriteMixer (0x3C, 24); break;
    }
    }
    }

    /************************************************** **************************
    ** Asks the user for a filename and prepares that file for recording. **
    ************************************************** **************************/
    void PrepareFile ()
    {
    char FileName [255];

    //Ask the user for a file name
    printf ("Please give filename : ");
    scanf ("%s", FileName);
    //Open the file for output
    WAVFile = fopen (FileName, "wb");
    //Save a dummy header
    fwrite (&Header, sizeof(Header), 1, WAVFile);
    }

    /************************************************** **************************
    ** Starts recording. The DMA controller is programmed with a block length **
    ** of 32K - the entire buffer. The DSP is instructed to play blocks of 16K **
    ** and then generate an interrupt (which allows the program to save the **
    ** parts that have already been recorded) **
    ************************************************** **************************/
    void StartRecording ()
    {
    long LinearAddress;
    unsigned int Page, OffSet;

    //Nothing recorded yet
    Recorded = 0;

    WriteDSP (0xD3); //DSP-command D1h - Disable speaker, required
    //on older SB's
    WriteDSP (0x40); //DSP-command 40h - Set sample frequency
    WriteDSP (165); //Write time constant
    /*
    The time constant is calculated as follows:
    (65536 - (256000000 / frequency)) >> 8
    */

    //Convert pointer to linear address
    LinearAddress = FP_SEG (DMABuffer);
    LinearAddress = (LinearAddress << 4) + FP_OFF (DMABuffer);
    Page = LinearAddress >> 16; //Calculate page
    OffSet = LinearAddress & 0xFFFF; //Calculate offset in the page
    outportb (0x0A, 4 | DMA); //Mask DMA channel
    outportb (0x0C, 0); //Clear byte pointer
    outportb (0x0B, 0x54 | DMA); //Set mode
    /*
    The mode consists of the following:
    0x54 + x = binary 01 01 01 xx
    | | | |
    | | | +- DMA channel
    | | +---- Write operation (the DSP writes to memory)
    | +------- Auto init mode
    +---------- Block mode
    */

    outportb (DMA << 1, OffSet & 0xFF); //Write the offset to the DMA controller
    outportb (DMA << 1, OffSet >> 8);

    if (DMA == 0) outportb (0x87, Page);
    if (DMA == 1) outportb (0x83, Page);
    if (DMA == 3) outportb (0x82, Page);

    outportb ((DMA << 1) + 1, 0xFF); //Set the block length to 0x7FFF = 32 Kbyte
    outportb ((DMA << 1) + 1, 0x7F);

    outportb (0x0A, DMA); //Unmask DMA channel

    WriteDSP (0x48); //DSP-command 48h - Set block length
    WriteDSP (0xFF); //Set the block length to 0x3FFF = 16 Kbyte
    WriteDSP (0x3F);
    WriteDSP (0x2C); //DSP-command 2Ch - Start auto-init playback
    }

    /************************************************** **************************
    ** Saves one half of the DMA buffer to the file **
    ************************************************** **************************/
    void SaveBuffer (unsigned int Buffer)
    {
    fwrite (DMABuffer + (Buffer << 14), 16384, 1, WAVFile);
    Recorded += 16384;
    }

    /************************************************** **************************
    ** Saves the final part of the buffer and finalizes the WAV file **
    ************************************************** **************************/
    void EndRecording ()
    {
    unsigned int Counter, OffSet, DMAPointer;

    //Stops DMA-transfer
    WriteDSP (0xD0);
    WriteDSP (0xDA);

    //Read DMA pointer from DMA controller
    DMAPointer = inportb (1 + (DMA >> 1));
    DMAPointer += (inportb (1 + (DMA >> 1)) << 8);

    /*
    DMAPointer contains amount that remains to be played.
    This is converted to the offset of the current sample
    */
    OffSet = 0x7FFF - DMAPointer;

    //Save the last bit
    fwrite (DMABuffer + (OffSet & 16384),
    OffSet & 16383,
    1, WAVFile);

    //The total amount recorded is now available
    Recorded += OffSet & 16383;

    //Save the actual header
    Header.RIFF = 0x46464952; //"RIFF"
    Header.NextChunkSize = Recorded + 36; //Size of the WAVE chunk
    Header.WAVE = 0x45564157; //"WAVE"
    Header.fmt = 0x20746D66; //"fmt "
    Header.fmtDataLength = 16; //length of fmt chunk
    Header.WaveType = 1; //Standard uncompressed WAV file
    Header.Channels = 1; //Mono
    Header.SampleRate = 11025; //11KHz
    Header.BytesPerSecond = Header.Channels * Header.SampleRate;
    Header.BlockAlignment = 1; //1 for 8bit, 2 for 16bit
    Header.BitResolution = 8; //8bit WAV file
    Header.data = 0x61746164; //"data"
    Header.SoundLength = Recorded;
    //Save the actual header
    fseek (WAVFile, 0, SEEK_SET);
    fwrite (&Header, sizeof(Header), 1, WAVFile);
    fclose (WAVFile);
    }

    /************************************************** **************************
    ** IRQ service routine - this is called when the DSP has finished playing **
    ** a block **
    ************************************************** **************************/
    #ifdef __cplusplus
    void interrupt ServiceIRQ (...)
    #else
    void interrupt ServiceIRQ ()
    #endif
    {
    //Relieve DSP
    inportb (0x22E);
    //Acknowledge hardware interrupt
    outportb (0x20, 0x20);
    //Acknowledge cascade interrupt for IRQ 2 and 10
    if (IRQ == 2 || IRQ == 10) outportb (0xA0, 0x20);
    //Save buffer
    SaveBuffer (WBuffer);
    //Toggle between write buffers
    WBuffer ^= 1;
    }

    /************************************************** **************************
    ** This procedure allocates 32K of memory to the DMA buffer and makes sure **
    ** that no page boundary is crossed **
    ************************************************** **************************/
    void AssignBuffer ()
    {
    char *TempBuf; //Temporary pointer
    long LinearAddress;
    unsigned int Page1, Page2; //Words

    //Assign 32K of memory
    TempBuf = (char *)malloc(32768);

    //Calculate linear address
    LinearAddress = FP_SEG (TempBuf);
    LinearAddress = (LinearAddress << 4) + FP_OFF (TempBuf);

    //Calculate page at start of buffer
    Page1 = LinearAddress >> 16;

    //Calculate page at end of buffer}
    Page2 = (LinearAddress + 32767) >> 16;

    //Check to see if a page boundary is crossed
    if (Page1 != Page2) {
    //If so, assign another part of memory to the buffer
    DMABuffer = (char *)malloc(32768);
    free (TempBuf);
    } else //otherwise, use the part we've already allocated
    DMABuffer = TempBuf;

    memset (DMABuffer, 128, 0x7FFF);
    }

    void FindSB ()
    {
    int Temp;

    //Check for Sound Blaster, address: ports 220, 230, 240, 250, 260 or 280
    for (Temp = 1; Temp < 9; Temp++) {
    if (Temp != 7)
    if (ResetDSP (0x200 + (Temp << 4))) {
    break;
    }
    }
    if (Temp == 9) {
    //or none at all
    printf ("No Sound Blaster found\n");
    return;
    } else printf ("Sound Blaster found at %Xh\n", Base);
    }

    void InitIRQandDMA ()
    {
    printf ("Please specify DMA channel : "); scanf("%d", &DMA);
    printf ("Please specify IRQ level : "); scanf("%d", &IRQ);

    //Save old IRQ vector
    if (IRQ == 2 || IRQ == 10 || IRQ == 11) {
    if (IRQ == 2) OldIRQ = getvect (0x71);
    if (IRQ == 10) OldIRQ = getvect (0x72);
    if (IRQ == 11) OldIRQ = getvect (0x73);
    } else OldIRQ = getvect (8 + IRQ);

    //Set new IRQ vector
    if (IRQ == 2 || IRQ == 10 || IRQ == 11) {
    if (IRQ == 2) setvect (0x71, ServiceIRQ);
    if (IRQ == 10) setvect (0x72, ServiceIRQ);
    if (IRQ == 11) setvect (0x73, ServiceIRQ);
    } else setvect (8 + IRQ, ServiceIRQ);

    //Enable IRQ
    if (IRQ == 2 || IRQ == 10 || IRQ == 11) {
    if (IRQ == 2) outportb (0xA1, inportb (0xA1) & 253);
    if (IRQ == 10) outportb (0xA1, inportb (0xA1) & 251);
    if (IRQ == 11) outportb (0xA1, inportb (0xA1) & 247);
    outportb (0x21, inportb (0x21) & 251);
    } else outportb (0x21, inportb (0x21) & !(1 << IRQ));

    }

    void ReleaseIRQandDMA ()
    {
    //Free interrupt vectors used to service IRQs
    if (IRQ == 2 || IRQ == 10 || IRQ == 11) {
    if (IRQ == 2) setvect (0x71, OldIRQ);
    if (IRQ == 10) setvect (0x72, OldIRQ);
    if (IRQ == 11) setvect (0x73, OldIRQ);
    } else setvect (8 + IRQ, OldIRQ);

    //Mask IRQs
    if (IRQ == 2 || IRQ == 10 || IRQ == 11) {
    if (IRQ == 2) outportb (0xA1, inportb (0xA1) | 2);
    if (IRQ == 10) outportb (0xA1, inportb (0xA1) | 4);
    if (IRQ == 11) outportb (0xA1, inportb (0xA1) | 8);
    outportb (0x21, inportb (0x21) | 4);
    } else outportb (0x21, inportb (0x21) | (1 << IRQ));
    }

    void main ()
    {
    //Clear screen
    clrscr ();

    printf ("Demonstration of recording samples using DMA - by Steven Don\n");
    printf ("------------------------------------------------------------\n");

    //Look for the Sound Blaster
    FindSB ();

    //Assign memory to the DMA Buffer
    AssignBuffer ();

    //Set write buffer to first buffer
    WBuffer = 0;

    //Select microphone as the source
    SelectSource (Microphone);

    //Ask the user for a filename and prepare the file for output
    PrepareFile ();

    //Ask the user for IRQ and DMA channels
    InitIRQandDMA ();

    //Start playback
    StartRecording ();

    //Wait until escape is pressed
    do; while (getch () != 27);

    //End the recording
    EndRecording ();

    //Free the memory allocated to the sound buffer
    free (DMABuffer);

    //Release the IRQ and DMA channels
    ReleaseIRQandDMA ();
    }

    فایل های ضمیمه فایل های ضمیمه

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •