2017-01-11 5 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); 

     }  
    } 
} 

я подумал о возможном решении, непосредственно заполнить «поле данных» из wavefile с snIn [256] буфера (вместо использования my_buffer) снова и снова и в конце закрыть WAVFile. Пожалуйста, дайте мне знать, что вы думаете о том, что и других решениях

+2

опубликованный код не компилируется и больше похож на C++, чем C. Предложите, по крайней мере, опубликовать заголовочные файлы, которые включены, какая плата, какая ОС и т. Д. – user3629249

+0

вот библиотека https: //developer.mbed .org/users/shintamainjp/code/wavfile/# c853ba46d0b9 Я использую stm32f746, mbed with keil ide – gab55

+0

Хм ... возможно, попробуйте записать меньшие пакеты данных (так как вы можете обрабатывать 4 секунды, возможно, попробуйте двухсекундные пакеты , так что вы можете буферизовать один, а другой пишет)? Я уверен, что хорошо работает с ограниченной памятью; Я считаю, что, например, _Tales of Phantasia_ удалось заставить SNES сыграть полностью озвученную начальную песню, постоянно загружая крошечные клипы из ПЗУ в 32-Кбайтную RAM-память звукового процессора. (У него также был собственный звуковой драйвер, хотя ему удалось эффективно удвоить звуковую RAM, но я отвлекся) –

ответ

0

вещи. Примечание: 1) в то время как операция записи выполняются, больше данных по-прежнему приходят в

По крайней мере, я бы двойной буфер, данные, поэтому можно написать один буфер, а другой - заполнить.

Обычно это означает использование прерывания для сбора образцов (в которых когда-либо буфер в настоящее время подан.)

на переднем плане программа ожидает текущий буфер, чтобы быть «полным», а затем инициирует операцию записи.,

затем снова ожидает для буфера, чтобы быть «полной»

прерывание от функциональных дорожек, которые буфер заполняется и текущий индекс в этот буфер. Когда буфер заполнен, установите «глобальный» статус, чтобы программа переднего плана знала, какой буфер готов к записи.

Программа переднего плана записывает буфер, а затем сбрасывает статус для этого буфера.

+0

Я понимаю, что вы говорите, но пока это не моя проблема. Я пытаюсь записать файл за 5 минут, но у меня всего 320 тыс. бара на доске, и мне нужно обойти это. как сделать длинный wav-файл без создания огромного массива? – gab55

+0

У вас есть только 320 КБ. Таким образом, 4 секунды аудио на 44,1 кГц будут потреблять больше памяти. Вам нужно удвоить буфер и обработать в кусках, возможно, 1024 сэмплов, возможно, подойдёт, если вы будете делать некоторые привилегии. , –

 Смежные вопросы

  • Нет связанных вопросов^_^