ناقل "موسيقى" رقمي مع واجهة UART

الصورة

مرحبًا Geektimes! هل تساءلت يومًا كيف تبدو "الإشارة الكهربائية" على طول مسارات لوحات الدوائر المطبوعة بين الدوائر الدقيقة والترانزستورات والثنائيات والمقاومات والمكثفات؟ أحد المتغيرات لهذه الإشارة في الإلكترونيات الحديثة هو ناقل رقمي ، وواحدة من الواجهات الشائعة لتبادل البيانات عبر الناقل هي UART. وغالبًا ما يتم استخدامه في وحدات التحكم الدقيقة للتواصل مع جهاز كمبيوتر أو نوع من الأطراف. للحصول على صوت في الحافلة ، ليس من الضروري على الإطلاق توصيل مكبر صوت بمضخم إلى ناقل حقيقي باستخدام UART أوم ، لأنه يمكن محاكاته في البرنامج. هل أنت مهتم بالأصوات التي انتهيت بها ، أم تحتاج إلى برنامج لتجربة نفسك؟ ثم أطلب القط.

نستمع إلى الملفات في الحافلة مع UART


ما الصوت الذي سينتج إذا قمت بنقل الملفات عبر UART ؟ فيما يلي بعض الأمثلة التي تم الحصول عليها باستخدام معلمات UART التالية:

  • 115200 معدل الباود
  • بت 8 بت
  • بت التكافؤ: بلا
  • طول بت التوقف: 1

صوت لعبة Stalker Shadow of Chernobyl (ملف XR_3DA.exe ، في نهاية المسار ، بدءًا من 2:36 ، هناك لحن).

صوت نص ورمز المقالة حول مُركِّب الكلام (المقالة نفسها هنا ).

كيف تبدو صورة لينا؟

الصورة

كانت النتيجة مجرد ضجيج .

صوت كتاب "الانتروبيا وتوقع السلاسل الزمنية في نظرية النظم الديناميكية" بتنسيق pdf.

صوت البرامج الثابتة لسلسلة متحكم سلسلة Atmega لمشغل wav.

ما يمكن استخدامه؟


نظريًا ، يمكن أن يكون هناك مثل هذه المعلومات في شكل نص ، أو صورة ، أو فيديو ، أو في شكل برنامج لن يكون له معنى وظيفي أو أهمية جمالية فحسب ، بل أيضًا الصوت "الجميل" للحافلة الرقمية ، ثم يتحول إلى نوع من الشعر "الرقمي" . يمكنك أيضًا تنويع عينات dubstep بشكل عام ، في رأيي ، فإن الاستماع إلى أصوات الحافلة الرقمية أمر مثير للاهتمام مثل الاستماع إلى ضجيج الموجات الراديوية في الموجات القصيرة ، بشكل عام ، للهواة.

كيف يعمل أو قليلا عن UART


ما هو UART يمكن قراءته على ويكيبيديا . من السهل جدًا محاكاة UART في البرنامج. في الواقع ، ما عليك سوى أن تكون قادرًا على إنشاء فرق إشارة من 0 إلى 1 والعكس صحيح (في حالة ملف WAV بسعة بت 16 بت ، هذه قيم من - A إلى + A ، حيث A هي سعة الإشارة) وتسجيلها في ملف صوتي. تعمل واجهة UART بشيء من هذا القبيل: بعد بت البداية ، وهو "صفر" منطقي ، تحتاج إلى تعيين المستوى اعتمادًا على البيانات المقدمة ، من الأدنى إلى الأعلى. يأتي بعد ذلك جزء من التكافؤ لا يمكنك استخدامه. يوجد في نهاية الرسالة بت توقف ("وحدة" منطقية) ، يمكن أن يختلف طولها. يمكن العثور على مثال من التعليمات البرمجية في التعليمات البرمجية المصدر الموجودة في نهاية المقالة. يمكن العثور على مزيد من المعلومات حول UART على الشبكة ، والكثير من المواد. يمكن استخدام UART لأغراض أخرى ، على سبيل المثال PWM ، ولكن في حالتنا ، هذا يعني أنه من الممكن نظريًا نقل إشارة صوتية كاملة مباشرة إلى السماعة ، كما هو الحال في مشغلات wav على وحدة التحكم الدقيقة. ومع ذلك ، أود أن أقترح استخدامه كمولد متعرج. يمكن توفير تردد النغمة وطور الإشارة في شكل بتات البيانات ، على سبيل المثال ، سوف يخلق 00001111 متعرجًا تكون فترته مساوية لـ 10 فترات من وقت الإرسال بتة واحدة (حيث يوجد في هذه الحالة أيضًا بت بدء تشغيل يساوي 0 وتوقف توقف يساوي 1). نظرًا لبتات البداية والتوقف ، لا يمكن نقل جميع فترات التعرج ، على سبيل المثال ، في هذه الحالة 01100110 ، حيث سنستمع في الأساس إلى مثل هذا التسلسل في الحافلة 0011001101 . إذا كنت تستخدم معدل نقل بيانات عاليًا ، على سبيل المثال 115200 بود ، فمن المنطقي إنشاء ترددات صوتية مسموعة عن طريق تمديد فترات meadras بعدة بايت.

...


باستخدام هذا الرابط يمكنك تنزيل البرنامج لتحويل الملف إلى صوت ناقل UART . هناك أيضًا إصدار يستخدم OpenAL لتشغيل الصوت أثناء تشغيل البرنامج ، وهنا الرابط .

يتم توفير رمز البرنامج المصدر أدناه:

ملف الرأس SoundsDigitalBus.h
#ifndef SOUNDS_DIGITAL_BUS_H_INCLUDED #define SOUNDS_DIGITAL_BUS_H_INCLUDED #define SDB_WAV_FILE_NAME "sdb_output.wav" #define SDB_UART_BIT 8 #define SDB_UART_PARITY 0 #define SDB_UART_STOP_BIT 1 #define SDB_UART_BAUDRATE 9600 #define SDB_UART_BAUDRATE_MAX 921600 ///   ()   #define SDB_MAX_DATA 30000 ///    #define SDB_CANNEL 1 /// -  ()  #define SDB_BIT 16 ///    #define SDB_FREQUENCY 96000 ///     OpenAL #define OPENAL_NUM_OF_DYNBUF 32 ///  OpenAL #define SDB_OPENAL_BIT SDB_BIT #define SDB_OPENAL_CANNEL SDB_CANNEL #define SDB_OPENAL_FREQUENCY SDB_FREQUENCY #define SDB_OPENAL_FORMAT AL_FORMAT_MONO16 ///     #define SDB_BUFFER_MAX 4800 ///  OpenAL    ( ,   1) #define SDB_WITH_OPENAL 1 ///   ( ,   1) #define SDB_WITH_DEBUG_MODE 0 #if SDB_WITH_OPENAL == 1 //   OpenAL    #include <openal/al.h> #include <openal/alc.h> #endif #if SDB_WITH_DEBUG_MODE == 1 //    #include <stdio.h> #include <locale.h> #endif //    #include <stdio.h> //    #include <string.h> class sdb { private: #if SDB_WITH_OPENAL == 1 //   openAl    //   speesy ALCdevice* openAlDevice; ALCcontext* openAlContext; ALuint openAlSource; signed char openAlnBuf; //  #endif // ---------------------------------------- //    WAV  FILE *fpSave; unsigned short wavBlockAlign; unsigned long wavSubchunk2Size; unsigned long wavChunkSize; unsigned char wavLenDataType; // ---------------------------------------- //      double dTime; //    ,  . double allTime; //    short busState; //   ( ) short busDataOne[SDB_BUFFER_MAX]; // ,   wav short busDataTwo[SDB_BUFFER_MAX]; unsigned char switchBuffer; //    unsigned int posBufferOne, posBufferTwo; //    unsigned int posAllBuffer; //   char wavFileName[512]; //  wav  char isCreateWavFileFlag; // ,  wav    char isBufferOneFlag; // ,     char isBufferTwoFlag; unsigned int uartBaudrate; //  UART   unsigned int uartT; unsigned char uartBit; //   unsigned char uartStopBit; //    unsigned char uartParityBit; unsigned char isAudioOutput; unsigned char isWavFileOutput; #if SDB_WITH_OPENAL == 1 ALboolean CheckALCError(void); ALboolean CheckALError(void); char initOpenAL(void); void destroyOpenAL(void); void playOpenAlSound(void); void stopOpenAlSound(void); void closeOpenAlSound(void); int getBufferStatusOpenAl(void); void setBufferOpenAl(signed short *buf,unsigned long siz); char updateOpenAl(void); #endif char createWavFile(char * filename,unsigned long sampleRate,unsigned short bitsPerSample, unsigned short numChannels); void writeSampleWavFile(void *data); void writeDataBlockWavFile(void *data,unsigned long len); void closeWavFile(void); void busDelay(unsigned short us); public: sdb(void); ~sdb(void); /** @brief       1-wire @param[in] data     1-wire */ void oneWireSendByte(unsigned char data); /** @brief     1-wire */ void oneWireReset(void); /** @brief    1- wire */ void oneWireStop(void); /** @brief      UART @param[in] data    UART */ void uartSendByte(unsigned char data); /** @brief     UART @param[in] data    UART */ void uartSend(unsigned long data); /** @brief   UART @param[in] baudrate   UART */ void uartSetBaudrate(unsigned long baudrate); /** @brief     @param[in] bit  ,   UART    */ void uartSetBit(unsigned char bit); /** @brief          .     1. @param[in] bit    */ void uartSetStopBit(unsigned char bit); /** @brief          UART  .   1,     ,   0,     UART     . @param[in] state ,   . */ void uartSetParityBit(unsigned char state); /** @brief    UART     UART,     .         . */ void uartStop(void); /** @brief    wav  @param[in] filename  wav  */ void setWavFileName(char* filename); /** @brief     OpenAL */ void playAudioOn(void); /** @brief     OpenAL */ void playAudioOff(void); /** @brief     wav  */ void recordOn(void); /** @brief     wav  */ void recordOff(void); }; #endif // MUSICDIGITALBUS_H_INCLUDED 


كود المصدر لملف SoundsDigitalBus.cpp
 #include "SoundsDigitalBus.h" #if SDB_WITH_OPENAL == 1 //   ALboolean sdb::CheckALCError(void) { ALenum ErrCode; ErrCode = alcGetError(openAlDevice); if (ErrCode != ALC_NO_ERROR) { return AL_FALSE; } return AL_TRUE; } ALboolean sdb::CheckALError(void) { ALenum ErrCode; if ((ErrCode = alGetError()) != AL_NO_ERROR) { return AL_FALSE; } return AL_TRUE; } //  OpenAL char sdb::initOpenAL(void) { ALfloat SourcePos[] = {0.0, 0.0, 0.0}; ALfloat SourceVel[] = {0.0, 0.0, 0.0}; //  . ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 }; //  . ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 }; //  . ( 3  –  «»,  3 – «») ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; #if SDB_WITH_DEBUG_MODE == 1 printf("alcOpenDevice\n"); #endif openAlDevice = alcOpenDevice(0); // open default device if (openAlDevice != 0) { openAlContext = alcCreateContext(openAlDevice,0); // create context if (openAlContext != 0) { #if SDB_WITH_DEBUG_MODE == 1 printf("alcMakeContextCurrent\n"); #endif alcMakeContextCurrent(openAlContext); // set active context } else { #if SDB_WITH_DEBUG_MODE == 1 printf("Error context\n"); #endif return 0; } } else { #if SDB_WITH_DEBUG_MODE == 1 printf("Error Open Device\n"); #endif return 0; } //  alListenerfv(AL_POSITION, ListenerPos); //  alListenerfv(AL_VELOCITY, ListenerVel); //  alListenerfv(AL_ORIENTATION, ListenerOri); alGenSources(1, &openAlSource); if (!CheckALError()) return false; alSourcef (openAlSource, AL_PITCH, 1.0f); alSourcef (openAlSource, AL_GAIN, 1.0f); alSourcefv(openAlSource, AL_POSITION, SourcePos); alSourcefv(openAlSource, AL_VELOCITY, SourceVel); alSourcei (openAlSource, AL_LOOPING, AL_FALSE); alSourcei(openAlSource, AL_LOOPING, AL_FALSE); openAlnBuf = 0; return 1; } void sdb::destroyOpenAL(void) { alSourceStop(openAlSource); //    alcMakeContextCurrent(0); //   alcDestroyContext(openAlContext); //    alcCloseDevice(openAlDevice); } void sdb::playOpenAlSound(void) { alSourcePlay(openAlSource); } void sdb::stopOpenAlSound(void) { alSourceStop(openAlSource); } void sdb::closeOpenAlSound(void) { alSourceStop(openAlSource); if (alIsSource(openAlSource)) alDeleteSources(1, &openAlSource); } int sdb::getBufferStatusOpenAl(void) { int processed = 0; if (openAlnBuf == 0) return 1; alGetSourcei(openAlSource, AL_BUFFERS_PROCESSED, &processed); CheckALError(); #if SDB_WITH_DEBUG_MODE == 1 printf("getBufferStatus: %d\n",processed); #endif if (processed != 0) { return processed; } return 0; } void sdb::setBufferOpenAl(signed short* buf, unsigned long siz) { int processed = 0; ALuint BufID = 0; #if _OPENAL_FORMAT == AL_FORMAT_MONO16 siz = siz*2; #endif // _OPENAL_FORMAT #if _OPENAL_FORMAT == AL_FORMAT_STEREO16 siz = siz*4; #endif // _OPENAL_FORMAT #if _OPENAL_FORMAT == AL_FORMAT_STEREO8 siz = siz*2; #endif // _OPENAL_FORMAT //     alGetSourcei(openAlSource, AL_BUFFERS_PROCESSED, &processed); CheckALError(); //   ,          if ((processed == 0) && (openAlnBuf < OPENAL_NUM_OF_DYNBUF)) { openAlnBuf++; //   alGenBuffers(1, &BufID); //   alBufferData(BufID,SDB_OPENAL_FORMAT,buf,siz,SDB_OPENAL_FREQUENCY); //     alSourceQueueBuffers(openAlSource, 1, &BufID); //    if (openAlnBuf == 1) alSourcePlay(openAlSource); } else { #if SDB_WITH_DEBUG_MODE == 1 printf("processed: %d openAlnBuf: %d\n",processed,openAlnBuf); #endif // ,        while (getBufferStatusOpenAl() == 0); //     alSourceUnqueueBuffers(openAlSource, 1, &BufID); CheckALError(); //    alBufferData(BufID,SDB_OPENAL_FORMAT,buf,siz,SDB_OPENAL_FREQUENCY); CheckALError(); alSourceQueueBuffers(openAlSource, 1, &BufID); CheckALError(); } } //        ,    //  1       char sdb::updateOpenAl(void) { int processed = 0; ALuint BufID; //     alGetSourcei(openAlSource, AL_BUFFERS_PROCESSED, &processed); #if SDB_WITH_DEBUG_MODE == 1 printf("updateOpenAl: %d\n",processed); #endif //     if (openAlnBuf == processed) { //     while (processed--) { //     alSourceUnqueueBuffers(openAlSource, 1, &BufID); if (!CheckALError()) return 0; alDeleteBuffers(1, &BufID); openAlnBuf--; } alSourceStop(openAlSource); #if SDB_WITH_DEBUG_MODE == 1 printf("alSourceStop: %d\n",openAlnBuf); #endif return 0; } return 1; } #endif //    .    void sdb::busDelay(unsigned short us) { double Time = (double)us/1000000.0; double locTime = allTime; char isFlag = 0; //  wav ,       if (isCreateWavFileFlag == 0) { if (isWavFileOutput == 1) { isFlag = createWavFile(wavFileName,SDB_FREQUENCY,SDB_BIT,SDB_CANNEL); //     ,    if (isFlag == 1) isCreateWavFileFlag = 1; } if (isAudioOutput == 1) { initOpenAL(); if (isWavFileOutput == 0) isCreateWavFileFlag = 1; } } allTime = allTime + Time; //     if (isCreateWavFileFlag == 1) //     while(locTime < allTime) { if (switchBuffer == 0) { if (posBufferOne >= SDB_BUFFER_MAX) { posBufferOne = 0; posBufferTwo = 0; busDataTwo[posBufferTwo++] = busState; isBufferOneFlag = 1; switchBuffer = 1; if (isWavFileOutput == 1) writeDataBlockWavFile(busDataOne,SDB_BUFFER_MAX); #if SDB_WITH_OPENAL == 1 if (isAudioOutput == 1) setBufferOpenAl(busDataOne,SDB_BUFFER_MAX); #endif } else { busDataOne[posBufferOne++] = busState; } } else if (switchBuffer == 1) { if (posBufferTwo >= SDB_BUFFER_MAX) { posBufferOne = 0; posBufferTwo = 0; busDataOne[posBufferOne++] = busState; isBufferTwoFlag = 1; switchBuffer = 0; if (isWavFileOutput == 1) writeDataBlockWavFile(busDataTwo,SDB_BUFFER_MAX); #if SDB_WITH_OPENAL == 1 if (isAudioOutput == 1) setBufferOpenAl(busDataTwo,SDB_BUFFER_MAX); #endif } else { busDataTwo[posBufferTwo++] = busState; } } posAllBuffer++; locTime = locTime + dTime; } } char sdb::createWavFile(char * filename,unsigned long sampleRate,unsigned short bitsPerSample, unsigned short numChannels) { char type[4]; const unsigned long subchunk1Size = 16; unsigned long byteRate; const unsigned short audioFormat = 1; unsigned short len_str = 0; char str_filename[512] = {0}; unsigned short i; //        wavLenDataType = bitsPerSample/8; wavSubchunk2Size = 0; wavChunkSize = wavSubchunk2Size + 44 - 8; //      wavBlockAlign = bitsPerSample / (8 * numChannels); // ,    . byteRate = sampleRate * wavBlockAlign; strcpy(str_filename,filename); len_str = strlen(str_filename); if (len_str < 4) return 0; //       .wav i = 0; while(i < len_str) { if (filename[i] == '.' && (i + 3) < len_str) { if (((filename[i + 1] == 'w') && (filename[i + 2] == 'a') && (filename[i + 3] == 'v')) || ((filename[i + 1] == 'W') && (filename[i + 2] == 'A') && (filename[i + 3] == 'V'))) { //     wav break; } else { if ((i + 3) >= 512) return 0; filename[i + 1] = 'w'; filename[i + 2] = 'a'; filename[i + 3] = 'v'; len_str = i + 4; break; } } else if ((i + 1) == len_str) { if ((i + 3) >= 512) return 0; filename[i + 1] = '.'; filename[i + 2] = 'w'; filename[i + 3] = 'a'; filename[i + 4] = 'v'; len_str = i + 5; break; } i++; } type[0] = filename[len_str - 4]; type[1] = filename[len_str - 3]; type[2] = filename[len_str - 2]; type[3] = filename[len_str - 1]; if (type[0]!='.'||type[1]!='w'||type[2]!='a'||type[3]!='v') { if (type[0]!='.'||type[1]!='W'||type[2]!='A'||type[3]!='V') { return 0; } } fpSave=fopen(str_filename,"wb"); type[0]='R'; type[1]='I'; type[2]='F'; type[3]='F'; fwrite(&type,sizeof(char),4,fpSave); fwrite(&wavChunkSize,sizeof(unsigned long),1,fpSave); type[0]='W'; type[1]='A'; type[2]='V'; type[3]='E'; fwrite(&type,sizeof(char),4,fpSave); type[0]='f'; type[1]='m'; type[2]='t'; type[3]=' '; fwrite(&type,sizeof(char),4,fpSave); fwrite(&subchunk1Size,sizeof(unsigned long),1,fpSave); fwrite(&audioFormat,sizeof(unsigned short),1,fpSave); fwrite(&numChannels,sizeof(unsigned short),1,fpSave); fwrite(&sampleRate,sizeof(unsigned long),1,fpSave); fwrite(&byteRate,sizeof(unsigned long),1,fpSave); fwrite(&wavBlockAlign,sizeof(unsigned short),1,fpSave); //    .   “”   . 8 , 16   .. fwrite(&bitsPerSample,sizeof(unsigned short),1,fpSave); type[0]='d'; type[1]='a'; type[2]='t'; type[3]='a'; // subchunk2Id //   “data” (0x64617461  big-endian ) fwrite(&type, sizeof(char), 4,fpSave); wavSubchunk2Size = 0; //    . fwrite(&wavSubchunk2Size, sizeof(unsigned long), 1,fpSave); return 1; } void sdb::writeSampleWavFile(void* data) { fwrite(data, wavLenDataType, wavBlockAlign, fpSave); wavSubchunk2Size = wavSubchunk2Size + wavLenDataType*wavBlockAlign; } void sdb::writeDataBlockWavFile(void* data, unsigned long len) { fwrite(data, wavLenDataType, len, fpSave); wavSubchunk2Size = wavSubchunk2Size + len*wavLenDataType; } //         . void sdb::closeWavFile(void) { wavChunkSize = wavSubchunk2Size + 44 - 8; fseek(fpSave,4,SEEK_SET); fwrite(&wavChunkSize,4,1,fpSave); fseek(fpSave,40,SEEK_SET); fwrite(&wavSubchunk2Size,4,1,fpSave); fclose(fpSave); } //  sdb::sdb(void) { openAlnBuf = 0; wavBlockAlign = 0; wavSubchunk2Size = 0; wavChunkSize = 0; wavLenDataType = 0; fpSave = NULL; strcat(wavFileName,SDB_WAV_FILE_NAME); dTime = 1.0/(double)SDB_OPENAL_FREQUENCY; allTime = 0.0; //      switchBuffer = 0; //    () posAllBuffer = 0; //     posBufferOne = 0; posBufferTwo = 0; isBufferOneFlag = 0; isBufferTwoFlag = 0; isCreateWavFileFlag = 0; busState = SDB_MAX_DATA; uartSetBaudrate(SDB_UART_BAUDRATE); uartSetBit(SDB_UART_BIT); uartSetStopBit(SDB_UART_STOP_BIT); uartSetParityBit(SDB_UART_PARITY); recordOn(); playAudioOn(); } //  sdb::~sdb() { if (isCreateWavFileFlag == 1) { if (posBufferOne > 0) { if (isWavFileOutput == 1) writeDataBlockWavFile(busDataOne,posBufferOne); #if SDB_WITH_OPENAL == 1 if (isAudioOutput == 1) setBufferOpenAl(busDataOne,posBufferTwo); #endif } else if (posBufferTwo > 0) { if (isWavFileOutput == 1) writeDataBlockWavFile(busDataTwo,posBufferTwo); #if SDB_WITH_OPENAL == 1 if (isAudioOutput == 1) setBufferOpenAl(busDataTwo,posBufferTwo); #endif } if (isWavFileOutput == 1) closeWavFile(); isCreateWavFileFlag = 0; #if SDB_WITH_OPENAL == 1 if (isAudioOutput == 1) { while (1) { // ,      if (updateOpenAl() == 0) break; } closeOpenAlSound(); destroyOpenAL(); } #endif } } //      one wire void sdb::oneWireSendByte(unsigned char data) { for (register unsigned char i = 0; i < 8; i++) { if((data & (1 << i)) == 1 << i) { busState = 0; busDelay(12); busState = SDB_MAX_DATA; busDelay(65); } else { busState = 0; busDelay(65); busState = SDB_MAX_DATA; busDelay(12); } } busState = SDB_MAX_DATA; } //       uart void sdb::uartSendByte(unsigned char data) { unsigned short pBit = 0; //     //   busState = SDB_MAX_DATA; busDelay(uartT); busState = -SDB_MAX_DATA; //  for (register unsigned char i = 0; i < 8; i++) { if((data & (1<<i)) == 1<<i) { busState = -SDB_MAX_DATA; busDelay(uartT); busState = -SDB_MAX_DATA; pBit++; } else { busState = SDB_MAX_DATA; busDelay(uartT); busState = -SDB_MAX_DATA; } } //   if (uartParityBit != 0) { if ((pBit & 0x0001) == 0) { busState = -SDB_MAX_DATA; busDelay(uartT); busState = -SDB_MAX_DATA; } else { busState = SDB_MAX_DATA; busDelay(uartT); busState = -SDB_MAX_DATA; } } //   busState = -SDB_MAX_DATA; for (register unsigned char i = 0; i < uartStopBit; i++) busDelay(uartT); busState = -SDB_MAX_DATA; } //      uart void sdb::uartSend(unsigned long data) { unsigned short pBit = 0; //     //   busState = SDB_MAX_DATA; busDelay(uartT); busState = -SDB_MAX_DATA; //  for (register unsigned char i = 0; i < uartBit; i++) { if((data & (1<<i)) == 1<<i) { busState = -SDB_MAX_DATA; busDelay(uartT); busState = -SDB_MAX_DATA; } else { busState = SDB_MAX_DATA; busDelay(uartT); busState = -SDB_MAX_DATA; } } //   if (uartParityBit != 0) { if ((pBit & 0x0001) == 0) { busState = -SDB_MAX_DATA; busDelay(uartT); busState = -SDB_MAX_DATA; } else { busState = SDB_MAX_DATA; busDelay(uartT); busState = -SDB_MAX_DATA; } } //   busState = -SDB_MAX_DATA; for (register unsigned char i = 0; i < uartStopBit; i++) busDelay(uartT); busState = -SDB_MAX_DATA; } //    UART void sdb::uartSetBaudrate(unsigned long baudrate) { if (baudrate > SDB_UART_BAUDRATE_MAX) baudrate = SDB_UART_BAUDRATE_MAX; uartBaudrate = baudrate; uartT = 1000000 / baudrate; } void sdb::uartSetBit(unsigned char bit) { if (bit > 32) bit = 32; if (bit == 0) bit = 1; if (bit < 8) bit = 8; uartBit = bit; } void sdb::uartSetStopBit(unsigned char bit) { if (bit == 0) bit = 1; uartStopBit = bit; } void sdb::uartSetParityBit(unsigned char state) { if (state > 1) state = 1; uartParityBit = state; } //       void sdb::oneWireReset(void) { busState = SDB_MAX_DATA; busDelay(100); busState = 0;// "0" busDelay(485);//  480 busState = SDB_MAX_DATA; busDelay(65);//  60      busState = 0;// "0" busDelay(400); busState = SDB_MAX_DATA; busDelay(100); } //    1-wire void sdb::oneWireStop(void) { if (isCreateWavFileFlag == 1) { if (posBufferOne > 0) { if (isWavFileOutput == 1) writeDataBlockWavFile(busDataOne,posBufferOne); #if SDB_WITH_OPENAL == 1 if (isAudioOutput == 1) setBufferOpenAl(busDataOne,posBufferOne); #endif } else if (posBufferTwo > 0) { if (isWavFileOutput == 1) writeDataBlockWavFile(busDataTwo,posBufferTwo); #if SDB_WITH_OPENAL == 1 if (isAudioOutput == 1) setBufferOpenAl(busDataTwo,posBufferTwo); #endif } #if SDB_WITH_OPENAL == 1 while (1) { // ,      if (updateOpenAl() == 0) break; } closeOpenAlSound(); destroyOpenAL(); #endif if (isWavFileOutput == 1) closeWavFile(); isCreateWavFileFlag = 0; } } void sdb::uartStop(void) { if (isCreateWavFileFlag == 1) { if (posBufferOne > 0) { if (isWavFileOutput == 1) writeDataBlockWavFile(busDataOne,posBufferOne); #if SDB_WITH_OPENAL == 1 if (isAudioOutput == 1) setBufferOpenAl(busDataOne,posBufferOne); #endif } else if (posBufferTwo > 0) { if (isWavFileOutput == 1) writeDataBlockWavFile(busDataTwo,posBufferTwo); #if SDB_WITH_OPENAL == 1 if (isAudioOutput == 1) setBufferOpenAl(busDataTwo,posBufferTwo); #endif } #if SDB_WITH_OPENAL == 1 if (isAudioOutput == 1) { while (1) { // ,      if (updateOpenAl() == 0) break; } closeOpenAlSound(); destroyOpenAL(); } #endif if (isWavFileOutput == 1) closeWavFile(); isCreateWavFileFlag = 0; } } void sdb::setWavFileName(char* filename) { strcat(wavFileName,filename); } void sdb::playAudioOn(void) { if (isCreateWavFileFlag == 0) isAudioOutput = 1; } void sdb::playAudioOff(void) { if (isCreateWavFileFlag == 0) isAudioOutput = 0; } void sdb::recordOn(void) { if (isCreateWavFileFlag == 0) isWavFileOutput = 1; } void sdb::recordOff(void) { if (isCreateWavFileFlag == 0) { if (isAudioOutput == 1) isWavFileOutput = 0; else isWavFileOutput = 1; } } 


الملف main.h
 #ifndef MAIN_H_INCLUDED #define MAIN_H_INCLUDED #define LINUX 0x00 #define WINDOWS 0x01 #define RU 0x00 #define EN 0x01 ///    #define TYPE_OS WINDOWS ///   #define LANGUAGE_PROGRAM RU #define UART_BUS 0x01 #define ONE_WIRE_BUS 0x02 #include <iostream> #include "SoundsDigitalBus.h" #include "stdlib.h" #include <stdio.h> #endif // MAIN_H_INCLUDED 


ملف main.cpp
 #include "main.h" sdb soundsDigitalBus; int main() { static FILE *fp = NULL; //    char strData[512]; //    char strChar = 0; //  unsigned char busType; //    int strPos = 0; //    int uartBaudrate = 0; //  UART int uartBit = 8; int uartStopBit = 0; //int uartParityBit = 0; #if TYPE_OS==WINDOWS and LANGUAGE_PROGRAM==RU setlocale(LC_ALL, "Russian"); printf("  UART  ,   0,   1-wire.\n"); #else printf("Enter the UART baud rate, or specify 0 if you want 1-wire.\n"); #endif printf("UART Baudrate: "); memset(strData,0,512); while(1) { strChar = getchar(); if ((strChar >= '0') && (strChar <= '9')) { strData[strPos++] = strChar; } else break; } uartBaudrate = atoi(strData); if (uartBaudrate == 0) { busType = ONE_WIRE_BUS; } else { busType = UART_BUS; soundsDigitalBus.uartSetBaudrate(uartBaudrate); } printf("\n"); if (busType == UART_BUS) { #if TYPE_OS==WINDOWS and LANGUAGE_PROGRAM==RU printf("   UART\n"); #else printf("Enter the number of bits UART.\n"); #endif printf("UART bit: "); memset(strData,0,512); while(1) { strChar = getchar(); if ((strChar >= '0') && (strChar <= '9')) { strData[strPos++] = strChar; } else break; } uartBit = atoi(strData); soundsDigitalBus.uartSetBit(uartBit); printf("\n"); #if TYPE_OS==WINDOWS and LANGUAGE_PROGRAM==RU printf("    UART\n"); #else printf("Enter the number of stop bits UART.\n"); #endif printf("UART stop bit: "); memset(strData,0,512); while(1) { strChar = getchar(); if ((strChar >= '0') && (strChar <= '9')) { strData[strPos++] = strChar; } else break; } uartStopBit = atoi(strData); soundsDigitalBus.uartSetStopBit(uartStopBit); printf("\n"); #if TYPE_OS==WINDOWS and LANGUAGE_PROGRAM==RU printf("    UART? (Y/n)\n"); #else printf("Use the parity bit in the UART? (Y/n)\n"); #endif strChar = getchar(); if ((strChar == 'n') || (strChar == 'N') || (strChar == '') || (strChar == '')) { soundsDigitalBus.uartSetParityBit(0); printf("not used\n"); } else { soundsDigitalBus.uartSetParityBit(1); printf("Yes, use\n"); } getchar(); printf("\n"); } FILE_M: printf("\n"); #if TYPE_OS==WINDOWS printf("        .\n"); printf(": D: \\ Games \\ SR2 \\ Rangers.txt\n"); printf(": "); #else printf("Specify the file to convert it to record digital bus.\n"); printf("For example: D: \\ Games \\ SR2 \\ Rangers.txt\n"); printf("File: "); #endif memset(strData,0,512); strPos = 0; while(1) { strChar = getchar(); if (strChar != '\n') { strData[strPos++] = strChar; } else break; } fp = fopen(strData,"rb"); if (fp == NULL) { printf("\n"); #if TYPE_OS==WINDOWS printf("!  %s  !\n",strData); printf("     .\n"); printf("...\n"); #else printf("Error! File %s not found!\n",strData); printf("Try to correctly specify the path to the file.\n"); printf("...\n"); #endif getchar(); goto FILE_M; } //soundsDigitalBus.setWavFileName(strData); printf("\n"); #if SDB_WITH_OPENAL == 1 #if TYPE_OS==WINDOWS printf("      ? (Y/n)\n"); #else printf("Play audio while working digital bus? (Y/n)\n"); #endif strChar = getchar(); if ((strChar == 'n') || (strChar == 'N') || (strChar == '') || (strChar == '')) { soundsDigitalBus.playAudioOff(); printf("not used\n"); } else { soundsDigitalBus.playAudioOn(); printf("Yes, use\n"); } getchar(); printf("\n"); #if TYPE_OS==WINDOWS printf("      ? (Y/n)\n"); #else printf("Record audio while working digital bus? (Y/n)\n"); #endif strChar = getchar(); if ((strChar == 'n') || (strChar == 'N') || (strChar == '') || (strChar == '')) { soundsDigitalBus.recordOff(); printf("not used\n"); } else { soundsDigitalBus.recordOn(); printf("Yes, use\n"); } getchar(); #else soundsDigitalBus.recordOn(); #endif printf("\n"); #if TYPE_OS==WINDOWS printf(" .\n"); #else printf("The transformation started.\n"); #endif unsigned char uartData[8]; if (busType == ONE_WIRE_BUS) { soundsDigitalBus.oneWireReset(); } while(1) { if (fread(uartData,sizeof(unsigned char),1,fp) > 0) { if (busType == UART_BUS) { if (uartBit == 8) { soundsDigitalBus.uartSendByte(uartData[0]); } else { soundsDigitalBus.uartSend(uartData[0]); } } else if (busType == ONE_WIRE_BUS) { soundsDigitalBus.oneWireSendByte(uartData[0]); } } else break; } fclose(fp); if (busType == ONE_WIRE_BUS) { soundsDigitalBus.oneWireStop(); } else if (busType == UART_BUS) { soundsDigitalBus.uartStop(); } #if TYPE_OS==WINDOWS printf(" .\n"); #else printf("Conversion completed.\n"); #endif return 0; //soundsDigitalBus.oneWireReset(); soundsDigitalBus.uartSetBaudrate(1200); for (int i = 0; i < 256; i ++) { for (int len = 0; len < 8; len++) { soundsDigitalBus.uartSendByte(i); } printf("%d\n",i); } soundsDigitalBus.oneWireStop(); return 0; } 


ملاحظة لاحظت خطأ في شفرة المصدر أن بت البداية هو المنطقي 1 ، وليس 0 ، وأن بت التوقف هي 0 ، وليس 1. من يحتاج إلى تطابق أساسي لإشارة صوت الواقع يمكنه إصلاح الخطأ نفسه.

Source: https://habr.com/ru/post/ar408485/


All Articles