0
0

When I record audio to a wav file,first time, the wave is all right.But from the second time, the wave become wrong.There is about 0.4s empty audio in the head of the wave.the code is like below.

    FMOD_RESULT result;
unsigned int   datalength = 0, soundlength;
FILE      *fp;

uint length;

float volume;

bool mute;

m_result = system->init(32, FMOD_INIT_NORMAL, 0);

FMOD_CREATESOUNDEXINFO exinfo;
memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));

exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
exinfo.numchannels = m_iChannels;
exinfo.format = FMOD_SOUND_FORMAT_PCM16;
exinfo.defaultfrequency = m_iSampleRate;
exinfo.length = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels;
result = system->createSound(0, FMOD_2D |FMOD_OUTPUTTYPE_WINMM| FMOD_OPENUSER, &exinfo, &sound);
result = system->recordStart(recorddriver, sound, true);
if (result != FMOD_OK)
{
    emit sigDriveErr();
    return;
}


fp = fopen(fileName.toStdString().c_str(), "wb");
if (!fp)
{
    printf("ERROR : could not open record.wav for writing.\n");
    return;
}

/*
Write out the wav header.  As we don't know the length yet it will be 0.
*/
WriteWavHeader(fp, sound, datalength);

result = sound->getLength(&soundlength, FMOD_TIMEUNIT_PCM);
ERRCHECK(result);
QVector<float> waveData;

do
{
    static unsigned int lastrecordpos = 0;
    static unsigned int index = 0;
    unsigned int recordpos = 0;
    system->getRecordPosition(recorddriver, &recordpos);
    ERRCHECK(result);

    if (recordpos != lastrecordpos)
    {
        void *ptr1, *ptr2;
        int blocklength;
        unsigned int len1, len2;

        blocklength = (int)recordpos - (int)lastrecordpos;
        if (blocklength < 0)
        {
            blocklength += soundlength;
        }

        /*
        Lock the sound to get access to the raw data.
        */
        sound->lock(lastrecordpos * exinfo.numchannels * 2, blocklength * exinfo.numchannels * 2, &ptr1, &ptr2, &len1, &len2);   /* * exinfo.numchannels * 2 = stereo 16bit.  1 sample = 4 bytes. */                                                                                                                             /*                                                                                                                          Write it to disk.
                                                                                                                                 */
        if (ptr1 && len1)
        {
            datalength += fwrite(ptr1, 1, len1, fp);
            signed short *data = (signed short *)ptr1;

            /*for (int i = 0, n = 0; i < len1; i += step, n++) 
            {
                waveData.append(data[n]);
            }
            index++;
            if (index % 5 == 0)
            {
                emit waveDataReceive(waveData);
                waveData.clear();
            }*/
        }
        if (ptr2 && len2)
        {
            datalength += fwrite(ptr2, 1, len2, fp);
            ushort *data = (ushort *)ptr2;
            //QVector<float> waveData;
            /*for (int i = 0, n = 0; i < len1; i += step, n++) 
            {
                waveData.append(data[n]);
            }
            index++;
            if (index % 5 == 0)
            {
                emit waveDataReceive(waveData);
                waveData.clear();
            }*/
        }

        /*
        Unlock the sound to allow FMOD to use it again.
        */
        sound->unlock(ptr1, ptr2, len1, len2);
    }

    lastrecordpos = recordpos;


    system->update();

    Sleep(10);

} while (isStopWave != true);

WriteWavHeader(fp, sound, datalength);
fclose(fp);
  • You must to post comments
0
0

its a pretty random thing to do to put FMOD_OUTPUTTYPE_WINMM in the middle of the mode bits that are supposed to only be from the FMOD_MODE list.

because FMOD_OUTPUTTYPE_WINMM = 7, the FMOD_MODE bits that it equivocates to are
#define FMOD_LOOP_OFF 0x00000001
#define FMOD_LOOP_NORMAL 0x00000002
#define FMOD_LOOP_BIDI 0x00000004
and FMOD_LOOP_OFF overides the other 2, so it would mean the sound would only play the start it it was played.

You said it has a delay, but from what I can see you haven’t posted the whole code.

Is recordStop called?

  • wenyu

    When I delete FMOD_OUTPUTTYPE_WINMM choice,it is still wrong. I do not call recordStop function.Here is WriteWavHeader function code.

    void WriteWavHeader(FILE *fp, FMOD::Sound *sound, int length)
    {
    int channels, bits;
    float rate;

    if (!sound)
    {
    return;
    }

    fseek(fp, 0, SEEK_SET);

    sound->getFormat(0, 0, &channels, &bits);
    sound->getDefaults(&rate, 0);

    {
    #if defined(WIN32) || defined(_WIN64) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__)
    #pragma pack(1)
    #endif

    /*
    WAV Structures
    */
    typedef struct
    {
    signed char id[4];
    int size;
    } RiffChunk;

    struct
    {
    RiffChunk chunk __PACKED;
    unsigned short wFormatTag __PACKED; /* format type */
    unsigned short nChannels __PACKED; /* number of channels (i.e. mono, stereo…) */
    unsigned int nSamplesPerSec __PACKED; /* sample rate */
    unsigned int nAvgBytesPerSec __PACKED; /* for buffer estimation */
    unsigned short nBlockAlign __PACKED; /* block size of data */
    unsigned short wBitsPerSample __PACKED; /* number of bits per sample of mono data */
    } FmtChunk = { { { ‘f’,’m’,’t’,’ ‘ }, sizeof(FmtChunk) – sizeof(RiffChunk) }, 1, channels, (int)rate, (int)rate * channels * bits / 8, 1 * channels * bits / 8, bits } __PACKED;

    struct
    {
    RiffChunk chunk;
    } DataChunk = { { { ‘d’,’a’,’t’,’a’ }, length } };

    struct
    {
    RiffChunk chunk;
    signed char rifftype[4];
    } WavHeader = { { { ‘R’,’I’,’F’,’F’ }, sizeof(FmtChunk) + sizeof(RiffChunk) + length },{ ‘W’,’A’,’V’,’E’ } };

    #if defined(WIN32) || defined(_WIN64) || defined(__WATCOMC__) || defined(_WIN32) || defined(__WIN32__)
    #pragma pack()
    #endif

    /*
    Write out the WAV header.
    */
    fwrite(&WavHeader, sizeof(WavHeader), 1, fp);
    fwrite(&FmtChunk, sizeof(FmtChunk), 1, fp);
    fwrite(&DataChunk, sizeof(DataChunk), 1, fp);
    }
    }

  • brett

    the reason you have a delay is becase you are not stopping the record system and lock/write code at the same time. The 2nd time you are starting the file writing after it has already recorded something. You should stop/start each time.

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.