void OutputMessage::addU32(uint32_t val) { m_buffer.grow(m_buffer.size() + 4); if (m_order == ByteOrder::BigEndian) writeBE32(&m_buffer[m_pos], val); else writeLE32(&m_buffer[m_pos], val); m_pos += 4; }
int addField(int handle, unsigned int field_id, char *field_value, int numfieldvalues) { int i; int ret = 0; long field_length = strlen(field_value); ret = writeLE16(handle, field_id, CURRENT_POS); field_length += 3; ret += writeLE32(handle, field_length, CURRENT_POS); field_length -= 3; ret += write(handle, (unsigned long)&numfieldvalues << 1, 1); //numfields the 01 above ret = writeLE16(handle, field_length, CURRENT_POS); for(i=0; i<field_length; i++) { write(handle, (unsigned long)&field_value[i] << 1, 1); ret += 1; } // ret += write(handle, (unsigned long) &field_value << 1, field_length + 1); return(ret); }
static int recordAudio(char *pkgName, char *cursor, BOOL relatedToLastPlayed) { unsigned long getAvailRand(); int handle, ret = -1; char temp[PATH_LENGTH]; char filepath[PATH_LENGTH]; char unique_id[PATH_LENGTH], digits[16]; long start, end, prev; CtnrFile *file; int key; int low_voltage, v; unsigned long wrk1; char *cp, *cp1, category[9]; long metadata_start; long metadata_numfields; unsigned long rand1; long previousBitRate; previousBitRate = BIT_RATE; // set to return BIT_RATE to orig value at end of fct, in case BIT_RATE is changed below rand1 = getAvailRand(); // pick random value to identify this recording unsignedlongToHexString((long)rand1,digits); if (strcmp(cursor,TRANSLATE_TEMP_DIR) == 0) { strcpy(filepath,LANGUAGES_PATH); strcat(filepath,TRANSLATE_TEMP_DIR); strcat(filepath,"/"); strcat(filepath,pkgName); strcat(filepath,AUDIO_FILE_EXT); BIT_RATE = MAX_BIT_RATE; } else if (*cursor == SYS_MSG_CHAR) { strcpy(filepath,LANGUAGES_PATH); catLangDir(filepath); // strcat(filepath,pkgName); cp1 = filepath + strlen(filepath); // save this position strcat(filepath, (char *)TB_SERIAL_NUMBER_ADDR + CONST_TB_SERIAL_PREFIX_LEN); strcat(filepath, "_"); strcat(filepath, digits); strcpy(pkgName, cp1); // change pkgName to show file name we used strcat(filepath,AUDIO_FILE_EXT); } else { strcpy(filepath,USER_PATH); // strcat(filepath,pkgName); cp1 = filepath + strlen(filepath); // save this position strcat(filepath, (char *)TB_SERIAL_NUMBER_ADDR + CONST_TB_SERIAL_PREFIX_LEN); strcat(filepath, "_"); strcat(filepath, digits); strcpy(pkgName, cp1); // change pkgName to show file name we used strcat(filepath,AUDIO_FILE_EXT); } file = getTempFileFromName(cursor,0); if (strcmp(cursor,TRANSLATE_TEMP_DIR) != 0) insertSound(file,NULL,FALSE); if (context.keystroke == KEY_HOME) { //let context.keystroke propogate through ret = 1; // signals no audio recorded but not necessary to throw exception } else { start = getRTCinSeconds(); strcpy(temp,"\x0d\x0a"); longToDecimalString(start,temp+2,8); strcat(temp,(const char *)": RECORD "); LBstrncat(temp,pkgName,60); LBstrncat(temp," -> ",60); LBstrncat(temp,cursor,60); logString(temp,BUFFER); // play record prompt message unless running translation app or if a button was just pressed if (!context.keystroke && strcmp(cursor,TRANSLATE_TEMP_DIR) != 0) { insertSound(&pkgSystem.files[SPEAK_SOUND_FILE_IDX],NULL,FALSE); if (context.keystroke == KEY_HOME) ret = 1; // signals no audio recorded but not necessary to throw exception else context.keystroke = 0; } else context.keystroke = 0; // reset context.keystroke so a second action doesn't take place stop(); start = getRTCinSeconds(); prev = end = start; //asm("INT OFF"); // to prevent recordings with bad blocks } // only open file to record if HOME was not pressed and only proceed if file opens correctly if (ret != 1 && ((handle = tbOpen((LPSTR)filepath,O_CREAT|O_RDWR)) != -1)) { setLED(LED_RED,TRUE); playBip(); turnAmpOff(); Snd_SACM_RecFAT(handle, C_CODEC_AUDIO1800, BIT_RATE); low_voltage = 0; do { end = getRTCinSeconds(); if (0==(end%2) && (prev != end)) { // blink LED every three seconds prev = end; setLED(LED_RED,FALSE); wait (100); setLED(LED_RED,TRUE); while((v = getCurVoltageSample()) == 0xffff); if(vCur_1 < V_MIN_SDWRITE_VOLTAGE) { low_voltage = 1; } } key = keyCheck(0); if (key == KEY_PLAY) { // pause TODO: this key press to pause shouldn't be hard coded pause(); setLED(LED_RED,FALSE); // insertSound(&pkgSystem.files[REC_PAUSED_FILE_IDX],NULL,FALSE); ---need to play this from memory do key = keyCheck(0); // TODO: NEED CODE HERE TO SAFELY SAVE FILE WHEN PAUSED FOR EXTENDED PERIOD OF TIME (maybe 60 min?) // checkInactivity(key); --- this would cause recording to be lost in just 30-300 sec inactivity while (!key); if (key == KEY_PLAY) { setLED(LED_RED,TRUE); resume(); } } } while ((!key || (key == KEY_PLAY)) && (low_voltage == 0)); // TODO: this key press to stop shouldn't be hard coded // while ((end - start) < 3) { // must be at least 2.0 second recording // end = getRTCinSeconds(); // } SACM_Stop(); //Snd_Stop(); // no need to call stop() and flush the log setLED(LED_RED,FALSE); turnAmpOn(); playDing(); //lseek(handle, 6, SEEK_SET ); //Seek to the start of the file input //write(handle,(LPSTR)header<<1,6); // write meta data to end of file close(handle); // rhm: I think its already closed, I can't write to it here systemCounts.recordingNumber++; // bump global recording number saveSystemCounts(); handle = tbOpen((LPSTR)filepath,O_RDWR); metadata_start = lseek(handle, 0L, SEEK_END); // offset to start of metadata metadata_numfields = 0L; // init num fields wrk1 = METADATA_VERSION; writeLE32(handle, wrk1, CURRENT_POS); //meta data version = 1 writeLE32(handle, metadata_numfields, CURRENT_POS); // 4 byte for num fields strcpy(unique_id, (char *)TB_SERIAL_NUMBER_ADDR + CONST_TB_SERIAL_PREFIX_LEN); // skip serial number prefix strcat(unique_id, "_"); strcat(unique_id, digits); addField(handle, DC_IDENTIFIER, unique_id, 1); metadata_numfields += 1; addField(handle, DTB_REVISION, (char *)"0", 1); metadata_numfields += 1; strcpy(unique_id, (char *)TB_SERIAL_NUMBER_ADDR + CONST_TB_SERIAL_PREFIX_LEN); // skip serial number prefix strcat(unique_id, "_"); longToDecimalString(systemCounts.powerUpNumber,(char *)temp,4); strcat(unique_id, temp); strcat(unique_id, "_"); longToDecimalString(systemCounts.recordingNumber,(char *)temp,4); strcat(unique_id, temp); strcat(unique_id, "_"); strncat(unique_id, digits, 8); addField(handle, DC_TITLE, unique_id, 1); metadata_numfields += 1; // strcpy(unique_id, (char *)TB_SERIAL_NUMBER_ADDR + CONST_TB_SERIAL_PREFIX_LEN); // skip serial number prefix // strcat(unique_id, "_"); // strcat(unique_id, digits); // addField(handle, DC_AUDIO_ITEM_ID, unique_id, 1); // metadata_numfields += 1; if (pkgSystem.idxLanguageCode != -1) { strcpy(unique_id,&pkgSystem.strHeapStack[pkgSystem.idxLanguageCode]); addField(handle, DC_LANGUAGE, unique_id, 1); metadata_numfields += 1; } cp = cursor; if(cp != NULL) { if(*cp >= '0' && *cp <= '9') { strcpy(category, cursor); } else if(!strncmp(cp, "AGR", 3)) strcpy(category, CAT_AGRICULTURE); else if(!strncmp(cp, "HEA", 3)) strcpy(category, CAT_HEALTH); else if(!strncmp(cp, "EDU", 3)) strcpy(category, CAT_EDUCATION); else if(!strncmp(cp, "STO", 3)) strcpy(category, CAT_STORIES); else if(!strncmp(cp, "BUS", 3)) strcpy(category, CAT_BUSINESS); else if(!strncmp(cp, "GOV", 3)) strcpy(category, CAT_GOVERNANCE); else if(!strncmp(cp, "MUS", 3)) strcpy(category, CAT_MUSIC); else if(!strncmp(cp, "DIA", 3)) strcpy(category, CAT_DIARY); else strcpy(category, CAT_OTHER); } addField(handle, DC_CATEGORY, category, 1); metadata_numfields += 1; if(relatedToLastPlayed) { strcpy(unique_id, STAT_FN); // DC_IDENTIFIER read at open if(strlen(unique_id)) { addField(handle,DC_RELATION,unique_id,1); metadata_numfields += 1; } } strcpy(unique_id, (char *)TB_SERIAL_NUMBER_ADDR + CONST_TB_SERIAL_PREFIX_LEN); // skip serial number prefix addField(handle,DC_SOURCE,unique_id,1); metadata_numfields += 1; longToDecimalString(systemCounts.powerUpNumber,(char *)temp,4); addField(handle,DC_DATE,temp,1); metadata_numfields += 1; // add other fields here writeLE32(handle, metadata_numfields, metadata_start + 4); // write correct num meta data fields close(handle); // done with meta data //asm("INT FIQ, IRQ"); -- see INT OFF above used once to prevent corrupted recordings (now possibly handled by SD_Initial() after USB Device mode // *P_WatchDog_Ctrl &= ~0x8000; // clear bit 15 to disable if (strcmp(cursor,TRANSLATE_TEMP_DIR) != 0) { insertSound(&pkgSystem.files[POST_REC_FILE_IDX],NULL,FALSE); if (!context.keystroke) insertSound(file,NULL,FALSE); // replay subject } // Leaving this out now, because I believe it gets created when it is first played if non-existent. // The delay of having it in recordAudio is too long. // createStatsFile(rand1); // Assumes no name collision from using a 32-bit semi-random number // Checking all past names was causing a long delay, but maybe (TODO:) we can // add in a check if the open() fails and then generate a new number in that unlikely case strcpy(temp,"TIME RECORDED (secs): "); longToDecimalString((long)end-start,temp+strlen(temp),4); strcat(temp,"\x0d\x0a"); logString(temp,BUFFER); //logString(temp,ASAP); ret = 0; // used to set this based on fileExists() check, but too slow } else if (ret == -1) { logException(16, filepath,RESET); //can't open file for new recording } BIT_RATE = previousBitRate; return ret; }