2017-01-11 3 views
-1

안녕하세요 저는 보드에서 녹음하려고하는데 4 초를 성공적으로 녹음했습니다. 문제는 내가 더 많은 시간 동안 기록하려 할 때, 충분한 메모리가 없다는 오류가 발생했습니다. 제 목표는 5 분짜리 파일을 녹음하는 것입니다. 지금까지 샘플이있는 snIn [256]이라는 버퍼를 만들었습니다. 나는 그것을 [16K * 4sec]의 큰 버퍼로 보내고 그것이 가득 차면 wav 파일을 만듭니다. wavfile의 "데이터 필드"를 채우는 방법

#include "SAI_InOut.hpp" 
#include "F746_GUI.hpp" 
#include "Delay.hpp" 
#include "WaveformDisplay.hpp" 
#include "SDFileSystem.h" 
#include "wavfile.h" 
using namespace Mikami; 

#define RES_STR_SIZE 0x20 
#define WAVFILE_SAMPLES_PER_SECOND 16000 
#define REC_TIME 4 

    //Create an SDFileSystem object 
SDFileSystem sd("sd"); 

bool flag = 1; 
int count = 0; 
char *res_buf; 
int rp = 0; 
const int NUM_SAMPLES = WAVFILE_SAMPLES_PER_SECOND * REC_TIME; 
Array<int16_t> my_buffer(NUM_SAMPLES); 
int j = 0; 
static const char *target_filename = "/sd/rectest.wav";  
const int SEG_SIZE = 256; 
int sent_array = 0; 


int rec(const char *filename, Array<int16_t> my_buffer) 
{ 
    j = 0; 
    flag = 0; 
    sent_array = 0; 

    WavFileResult result; 
    wavfile_info_t info; 
    wavfile_data_t data; 

    WAVFILE_INFO_AUDIO_FORMAT(&info) = 1; 
    WAVFILE_INFO_NUM_CHANNELS(&info) = 1; 
    WAVFILE_INFO_SAMPLE_RATE(&info)  = WAVFILE_SAMPLES_PER_SECOND; 
    WAVFILE_INFO_BITS_PER_SAMPLE(&info) = 16; 
    WAVFILE_INFO_BYTE_RATE(&info)  = WAVFILE_INFO_NUM_CHANNELS(&info) * WAVFILE_INFO_SAMPLE_RATE(&info) * (WAVFILE_INFO_BITS_PER_SAMPLE(&info)/8); 
    WAVFILE_INFO_BLOCK_ALIGN(&info)  = 2; 


    WAVFILE *wf = wavfile_open(filename, WavFileModeWrite, &result); 
    if (result != WavFileResultOK) { 
     wavfile_result_string(result, res_buf, RES_STR_SIZE); 
     printf("%s", res_buf); 
     return result; 
    } else printf ("Open file success \r\n"); 

    rp = 0; 
    WAVFILE_DATA_NUM_CHANNELS(&data) = 1; 

     result = wavfile_write_info(wf, &info); 
     if (result != WavFileResultOK) { 
      wavfile_result_string(result, res_buf, RES_STR_SIZE); 
      printf("%s", res_buf); 
      return result; } else printf ("Write info success \r\n"); 

    while (rp < NUM_SAMPLES) { 
     WAVFILE_DATA_CHANNEL_DATA(&data, 0) = my_buffer[rp];  
     result = wavfile_write_data(wf, &data); 
     rp += 1; 
    } 

    if (result != WavFileResultOK) { 
     wavfile_result_string(result, res_buf, RES_STR_SIZE); 
     printf("%s", res_buf); 
     return result; } else printf ("Write Data file success \r\n"); 

    result = wavfile_close(wf); 
    if (result != WavFileResultOK) { 
     wavfile_result_string(result, res_buf , RES_STR_SIZE); 
     printf("%s", res_buf); 
     return result; } else printf ("Close file success \r\n"); 

    //UnMount the filesystem 
    sd.unmount(); 

    printf("Success rec !\r\n"); 
    return 0; 
} 


int main() 
{ 
    //Mount the filesystem 
     sd.mount(); 

    const float MAX_DELAY = 0.5f;  // 最大遅延,単位:秒 
    const int FS = I2S_AUDIOFREQ_16K; // 標本化周波数: 16 kHz 
    const uint32_t MAX_ARRAY_SIZE = (uint32_t)(MAX_DELAY*FS); 
    SaiIO mySai(SaiIO::BOTH, 256, FS, INPUT_DEVICE_DIGITAL_MICROPHONE_2); 
    Label myLabel(185, 10, "Delay System", Label::CENTER, Font16); 
    // ButtonGroup: "ON", "OFF" 
    const uint16_t BG_LEFT = 370; 
    const uint16_t BG_WIDTH = 100; 
    const uint16_t BG_HEIGHT = 45; 
    ButtonGroup onOff(BG_LEFT, 40, BG_WIDTH/2, BG_HEIGHT, 
         2, (string[]){"ON", "OFF"}, 0, 0, 2, 1); 
    const uint16_t SB_LEFT = BG_LEFT - 320; 
    const uint16_t SB_WIDTH = 270; 
    const uint16_t SB_Y0 = 240; 
    char str[20]; 
    sprintf(str, " %3.1f [s]", MAX_DELAY); 
    SeekBar barDelay(SB_LEFT, SB_Y0, SB_WIDTH, 
        0, MAX_ARRAY_SIZE, 0, "0", "", str); 
    NumericLabel<float> labelDelay(SB_LEFT+SB_WIDTH/2, SB_Y0-40, "DELEY: %4.2f", 0, Label::CENTER); 
    DelaySystem delaySystem(MAX_ARRAY_SIZE); 
    WaveformDisplay displayIn(*GuiBase::GetLcdPtr(), SB_LEFT+7, 70, 256, 9,LCD_COLOR_WHITE, LCD_COLOR_CYAN,GuiBase::ENUM_BACK); 
    Label inLabel(SB_LEFT-30, 65, "IN"); 
    WaveformDisplay displayOut(*GuiBase::GetLcdPtr(), SB_LEFT+7, 130, 256, 9,LCD_COLOR_WHITE, LCD_COLOR_CYAN,GuiBase::ENUM_BACK); 
    Label outLabel(SB_LEFT-30, 125, "OUT"); 

    int runStop = 1; 
    Array<int16_t> snIn(mySai.GetLength()); 
    Array<int16_t> snOut(mySai.GetLength()); 

    mySai.RecordIn(); 
    mySai.PlayOut(); 
    mySai.PauseOut(); 


    while (true) 
    { 
     // On/OFF 
     int num; 
     if (onOff.GetTouchedNumber(num)) 
      if (runStop != num) 
      { 
       if (num == 0) mySai.ResumeOut(); 
       else   mySai.PauseOut(); 
       runStop = num; 
      } 

     if (mySai.IsCompleted()) 
     { 
      for (int n=0; n<mySai.GetLength() ; n++) 
      { 
       int16_t xL, xR; 
       mySai.Input(xL,xR); 
       int16_t xn = xL + xR; 
       snIn[n] = xn; 
       my_buffer[j] = xn; 
       j++; 
       if (j == NUM_SAMPLES && flag == 1) { 
        rec (target_filename , my_buffer); } 

       int16_t yn = delaySystem.Execute(xn); 
       mySai.Output(yn, yn); 
       snOut[n] = yn; 
      } 

      mySai.Reset();  
      displayIn.Execute(snIn); 

     }  
    } 
} 

가 다시 다시 직접 (대신 my_buffer를 사용)를 snIn [256] 버퍼와 wavefile의 "데이터 영역"을 채우기 위해, 가능한 해결책을 생각하고 끝에 wavfile를 닫는다. 내가 그와 다른 솔루션

에 대해 어떻게 생각하는지 알려주세요 주의 할
+2

게시 된 코드가 컴파일되지 않고 C보다 C++와 비슷합니다. 포함 된 헤더 파일, 게시판, OS 등을 제안하십시오. – user3629249

+0

은 https : //developer.mbed 라이브러리입니다. .net/shintamainjp/code/wavfile/# c853ba46d0b9 나는 keil ide와 함께 stm32f746을 사용하고있다. – gab55

+0

어쩌면 4 초를 다룰 수 있기 때문에 작은 패킷의 패킷을 쓰는 것이 좋다. 그래서 다른 하나는 쓴다.) 제한된 메모리로 잘 작동한다는 것이 확실합니다. 예를 들어, _Tant of Phantasia_는 ROM에서 사운드 프로세서의 32kB RAM으로 작은 클립을 지속적으로로드하여 SNES가 완전히 열창있는 노래를 재생할 수있는 방법이라고 생각합니다. (그것은 또한 사운드 램을 효과적으로 두 배로 관리 할 수있는 커스텀 사운드 드라이버를 가지고 있었지만 나는 빗나갔습니다 ...) –

답변

0

일 :. 쓰기 작업이 수행되는 동안 1), 더 많은 데이터가 여전히오고 최소한

내가 버퍼를 두 배로 것이라고 데이터이므로 한 버퍼를 쓰고 다른 버퍼는 채 웁니다.

는 일반적으로이 샘플을 수집하기 위해 인터럽트를 사용하는 수단 (어느 버퍼가 현재 출원중인에있다.) 현재의 버퍼가 '전체'가 될 때까지

전경 프로그램은, 다음 기록 동작을 개시 기다린다.,

다음에 버퍼가 가득 찰 때까지 다시 대기합니다.

인터럽트 기능은 채워지는 버퍼와 현재 버퍼의 인덱스를 추적합니다. 버퍼가 가득 차면 포 그라운드 프로그램이 어떤 버퍼를 쓸 준비가되었는지 알 수 있도록 '글로벌'상태를 설정하십시오.

전경 프로그램은 버퍼를 쓰고 그 버퍼의 상태를 재설정합니다.

+0

나는 당신이 말하는 것을 이해합니다. 그러나 이것은 현재 내 문제가 아닙니다. 나는 5 분 파일을 위해 기록하려고 노력하고있다. 그러나 나는 판자 위에서 단지 320 k의 숫양을 가지고있다. 그리고 나는 이것을 우회 할 필요가있다. 거대한 배열을 만들지 않고 긴 wav 파일을 만드는 방법? – gab55

+0

당신은 오직 320K의 램을 가지고 있습니다. 44.1kHz에서 4 초의 오디오를 사용하면 더 많은 메모리를 사용할 수 있습니다. 당신은 어쩌면 1024 샘플의 청크로 버퍼와 프로세스를 두배로 늘릴 필요가 있습니다. . –

관련 문제