MIDI format1 -> format0 converter in MFC

1

Thank you for visiting my question.

I am writing a program to convert from MIDI format1 to format0 using MFC.

Reads MIDI file data in units of 1BYTE, declares TRACK CHUNK as a structure, and saves it in a vector. (To sort by SMPTE order)

If I debug using breakpoints, it reads well without any problems. However, while reading, all binary values ​​from the room of the 248th vector are being read as 0.

I tried to search, but I don't know how to search because 0 is being read even though the value of MIDI FILE is not 0.

Why is the value being read as 0??

#define HEADERCHUNK "MThd"
#define TRACKCHUNK "MTrk"
#define _CRTDBG_MAP_ALLOC

typedef struct head
{
    CHAR szHeader[5];
    UINT uHeaderLength;
    USHORT ushFormatNum;
    USHORT ushTrackOfNum;
    USHORT ushTimeDivision;

}HEAD;

typedef struct track
{
    CHAR szTrack[5];
    //UINT unTrackLength;
    UINT unSMPTE;
    UINT unDeltaTime;
    BYTE byteStatusByte;
    BYTE byteEventByte;
    UINT unDataLength;
    BYTE *pbyteTrackData;
    //struct track* pNext;

}TRACK;

#include "stdafx.h"
#include "CovertToFormat0.h"


CovertToFormat0::CovertToFormat0(void)
{
}


CovertToFormat0::~CovertToFormat0(void)
{
}

void CovertToFormat0::GethWnd(HWND hWnd)
{
    m_hWnd = hWnd;
}

void CovertToFormat0::LittleEndian(BYTE* pbyteData, int nCount)
{
    int nArrayCount1 = 0;
    int nArrayCount2 = 0;

    BYTE* pTempData = new BYTE[nCount];

    for(nArrayCount1=0, nArrayCount2=nCount-1; nArrayCount1<nCount; nArrayCount1++, nArrayCount2--)
    {
        pTempData[nArrayCount2] = pbyteData[nArrayCount1];
    
    }

    for(nArrayCount1=0; nArrayCount1<nCount; nArrayCount1++)
    {
        pbyteData[nArrayCount1] = pTempData[nArrayCount1];
    }

    delete[] pTempData;
}

BOOL CovertToFormat0::CovertMIDI(CString& strFormat1FilePath, CString& strFormat0FilePath)
{
    FILE* pFormat1File = fopen(strFormat1FilePath, _T("r"));
    m_bSequence = FALSE;
    //헤더 정보 읽기
    ReadHeadChunk(pFormat1File, strFormat1FilePath);    

    UINT unTrackCount = (UINT)m_head.ushTrackOfNum;
    m_head.ushTrackOfNum = 0x01;


    //트랙 정보 읽기
    m_unTrackLength = 0;
    
    UINT unTemp = 0;

    for(UINT unCount=0; unCount<2; unCount++)
    {
        ReadTrackChunk(pFormat1File, strFormat0FilePath, unTrackCount);
    }

    fclose(pFormat1File);

    for(UINT nSize=0; nSize<m_vector.size(); nSize++)
    {
        for(UINT nCount=0; nCount<m_vector.size()-nSize; nCount++)
        {
            if(m_vector[nCount].unSMPTE > m_vector[nSize].unSMPTE)
            {
                unTemp = m_vector[nCount].unSMPTE;
                m_vector[nCount].unSMPTE = m_vector[nSize].unSMPTE;
                m_vector[nSize].unSMPTE = unTemp;
            }
        }
    }

    //Write
    FILE* pFormat0File = fopen(strFormat0FilePath, _T("wb"));

    WriteHeader(pFormat0File, strFormat0FilePath);

    WriteTrack(pFormat0File);
    fclose(pFormat0File);

    return TRUE;
}

BOOL CovertToFormat0::ReadHeadChunk(FILE* pFormat1File, CString& strFormat1FilePath)
{

    if(!pFormat1File)
    {
        MessageBox(m_hWnd, _T("pFormat1File Open Failed"), _T("ERROR"), MB_OK);
        fclose(pFormat1File);
        return FALSE;
    }

    //MIDI 구조체의 헤더 0x00 초기화
    memset(m_head.szHeader, 0x00, 5);
    m_head.uHeaderLength = 0;
    m_head.ushFormatNum = 0;
    m_head.ushTrackOfNum = 0;
    m_head.ushTimeDivision = 0;

    //헤더 MThd 4바이트 읽어오기
    fread(m_head.szHeader, 4, 1, pFormat1File);
    
    //헤더가 MThd가 아니라면 return FALSE
    if(strcmp(m_head.szHeader, HEADERCHUNK) != 0)
    {
        MessageBox(m_hWnd, _T("헤더가 MThd이 아닙니다."), _T("오류"), MB_OK);
        fclose(pFormat1File);
        return FALSE;
    }

    //헤더 길이 읽기
    fread(&(m_head.uHeaderLength), 4, 1, pFormat1File);
    LittleEndian((BYTE*)&m_head.uHeaderLength, 4);

    //헤더정보가 잘못되었는지 체크
    if(m_head.uHeaderLength != 0x00000006)
    {
        MessageBox(m_hWnd, _T("헤더 길이가 잘못되었습니다."), _T("ERROR"), MB_OK);
        fclose(pFormat1File);
        return FALSE;
    }

    //포멧정도 읽기
    fread(&(m_head.ushFormatNum), 2, 1, pFormat1File);
    LittleEndian((BYTE*)&m_head.ushFormatNum, 2);
    //포멧0 로 값입력
    m_head.ushFormatNum = 0x00;

    //트랙개수 읽기
    fread(&(m_head.ushTrackOfNum), 2, 1, pFormat1File);
    LittleEndian((BYTE*)&m_head.ushTrackOfNum, 2);

    //분해능 읽기
    fread(&(m_head.ushTimeDivision), 2, 1, pFormat1File);
    LittleEndian((BYTE*)&m_head.ushTimeDivision, 2);

    return TRUE;
}

BOOL CovertToFormat0::ReadTrackChunk(FILE* pFormat1File, CString& strFormat0FilePath, UINT unTrackCount)
{
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

    //Track Chunk 읽기
    memset(m_track.szTrack, 0x00, 5);
    m_track.unSMPTE = 0;
    m_track.unDeltaTime = 0;
    m_track.byteStatusByte = 0x00;
    m_track.byteEventByte = 0x00;
    m_track.unDataLength = 0;
    m_track.pbyteTrackData = NULL;

    m_nEndTrack = FALSE;
    m_bRunning = FALSE;

    fread(m_track.szTrack, 4, 1, pFormat1File);
    if(strcmp(m_track.szTrack, TRACKCHUNK) != 0)
    {
        MessageBox(m_hWnd, _T("TRACK Chunk Not MTrk"), _T("ERROR"), MB_OK);
        fclose(pFormat1File);
        return FALSE;
    }
    UINT unTrackLanngth = 0;
    //트랙 길이 읽기
    fread(&(unTrackLanngth), 4, 1, pFormat1File);
    LittleEndian((BYTE*)&unTrackLanngth, 4);    


    UINT unDeltaTime = 0;

    while(!m_nEndTrack)
    {
        //1BYTE씩 읽기
        //DeltaTime 읽기
        fread(&(m_track.unDeltaTime), 1, 1, pFormat1File);
        m_unTrackLength++;

        if(m_track.unDeltaTime & 0x80)
        {
            unDeltaTime = 0;
            fread(&unDeltaTime, 1, 1, pFormat1File);

            m_track.unDeltaTime = m_track.unDeltaTime << 8;
            m_track.unDeltaTime += unDeltaTime;
            m_track.unSMPTE += m_track.unDeltaTime;
            m_unTrackLength++;
        }
        else
        {
            m_track.unSMPTE += m_track.unDeltaTime;
        }

        //상태바이트 읽기
        BYTE byteStatusByte = 0x00;
        fread(&(byteStatusByte), 1, 1, pFormat1File);

        if(byteStatusByte & 0x80)
        {
            m_track.byteStatusByte = byteStatusByte;
            m_unTrackLength++;
        }
        else
        {
            m_track.byteEventByte = byteStatusByte;
            m_unTrackLength++;
            m_bRunning = TRUE;
        }

        if((m_track.byteStatusByte & 0xF0) == 0xF0)
        {
            ReadSystemMessage(pFormat1File, m_track.byteStatusByte);
        }
        else
        {
            ReadChannelMessage(pFormat1File, m_track.byteStatusByte);
        }
        m_vector.push_back(m_track);

        if(m_track.pbyteTrackData != NULL)
        {
            delete[] m_track.pbyteTrackData;
        }

        m_track.byteEventByte = 0x00;
        m_track.unDataLength = 0x00;
        m_track.unDeltaTime = 0x00;
        m_track.pbyteTrackData = NULL;
    }
    return TRUE;
}
 
BOOL CovertToFormat0::WriteHeader(FILE* pFormat0File, CString& strFormat0FilePath)
{
    if(!pFormat0File)
    {
        MessageBox(m_hWnd, _T("pFormat0Fole Open Failed!"), _T("ERROR"), MB_OK);
        fclose(pFormat0File);
        return FALSE;
    }

    fwrite(m_head.szHeader, 4, 1, pFormat0File);
    LittleEndian((BYTE*)&m_head.uHeaderLength, 4);
    fwrite(&(m_head.uHeaderLength), 4, 1, pFormat0File);
    LittleEndian((BYTE*)&m_head.ushFormatNum, 2);
    fwrite(&(m_head.ushFormatNum), 2, 1, pFormat0File);
    LittleEndian((BYTE*)&m_head.ushTrackOfNum, 2);
    fwrite(&(m_head.ushTrackOfNum), 2, 1, pFormat0File);
    LittleEndian((BYTE*)&m_head.ushTimeDivision, 2);
    fwrite(&(m_head.ushTimeDivision), 2, 1, pFormat0File);


    return TRUE;
}

BOOL CovertToFormat0::WriteTrack(FILE* pFormat0File)
{
    fwrite(m_track.szTrack, 4, 1, pFormat0File);
    LittleEndian((BYTE*)&m_head.ushTimeDivision, 4);
    fwrite(&(m_unTrackLength), 4, 1, pFormat0File);

    std::vector<TRACK>::iterator iter;

    for(iter=m_vector.begin(); iter!=m_vector.end(); iter++)
    {
        if(iter->unDeltaTime & 0x80)
        {
            fwrite(&(iter->unDeltaTime), 2, 1, pFormat0File);
        }
        else
        {
            fwrite(&(iter->unDeltaTime), 1, 1, pFormat0File);
        }

        if(iter->byteStatusByte != 0x00)
        {
            fwrite(&(iter->byteStatusByte), 1, 1, pFormat0File);
        }

        if(iter->byteEventByte != 0x00)
        {
            fwrite(&(iter->byteEventByte), 1, 1, pFormat0File);
        }

        if(iter->unDataLength != 0)
        {
            fwrite(&(iter->unDataLength), 1, 1, pFormat0File);
        }

        if(iter->pbyteTrackData != 0x00)
        {
            for(int n=0; n<iter->unDataLength; n++)
            {
                fwrite(&(iter->pbyteTrackData[n]), 1, 1, pFormat0File);
            }
        }
    }

    BYTE byteEnd1 = 0xFF;
    BYTE byteEnd2 = 0x2F;
    BYTE byteEnd3 = 0x00;
    fwrite(&byteEnd1, 1, 1, pFormat0File);
    fwrite(&byteEnd2, 1, 1, pFormat0File);
    fwrite(&byteEnd3, 1, 1, pFormat0File);


    return TRUE;
}

void CovertToFormat0::ReadSystemMessage(FILE* pFormat1File, BYTE byteStatusByte)
{
    switch(byteStatusByte & 0x0F)
    {
    case 0x00:  //Exclusive Change
    case 0x07:  //End Of Exclusive

        //SystemExclusiveMessage
        break;  

    case 0x01:  //Cutter Frame Change
    case 0x02:  //Song Position Pointer
    case 0x03:  //Song Selector     
    case 0x04:  //current Running Status is cancel
    case 0x05:  //current Running Status is cancel
    case 0x06:  //Tune Request

        //SystemCommonMessage
        break;

    case 0x08:  //Timing Clock
    case 0x0A:  //Start
    case 0x0B:  //continue
    case 0x0C:  //Stop  
    case 0x0E:  //Active Sensing
    case 0x0F:  //System Reset  
        ReadMetaEventMessage(pFormat1File);
        break;
    }

    return;
}

void CovertToFormat0::ReadMetaEventMessage(FILE* pFormat1File)
{
    UINT unLength = 0;
    BYTE byteData = NULL; 
    //Event Byte Read
    if(m_track.byteEventByte == 0x00)
    {
        fread(&(m_track.byteEventByte), 1, 1, pFormat1File);
        m_unTrackLength++;
    }

    switch(m_track.byteEventByte)
    {
    case 0x00 :
        ReadText(pFormat1File);
        break;
    case 0x01 :
        ReadText(pFormat1File);
        break;
    case 0x02 :
        ReadText(pFormat1File);
        break;
    case 0x03 :
        if(!m_bSequence)
        {
            ReadText(pFormat1File);
            m_bSequence = TRUE;
        }
        else
        {
            fread(&(unLength), 1, 1, pFormat1File);
            for(UINT nCount=0; nCount<unLength; nCount++)
            {
                fread(&byteData, 1, 1, pFormat1File);
            }

            m_track.byteStatusByte = 0x00;
            m_track.byteEventByte = 0x00;
        }
        break;
    case 0x04 :
        ReadText(pFormat1File);
        break;
    case 0x05 :
        ReadText(pFormat1File);
        break;
    case 0x06 :
        ReadText(pFormat1File);
        break;
    case 0x07 :
        ReadText(pFormat1File);
        break;
    case 0x20 :
        ReadText(pFormat1File);
        break;
    case 0x2F :
        m_unTrackLength -= 2;
        fread(&unLength, 1, 1, pFormat1File);
        m_track.byteStatusByte = 0x00;
        m_track.byteEventByte = 0x00;
        m_nEndTrack = TRUE;
        break;
    case 0x51:
        ReadText(pFormat1File);
        break;
    case 0x54 :
        ReadText(pFormat1File);
        break;
    case 0x58 :
        ReadText(pFormat1File);
        break;
    case 0x59 :
        ReadText(pFormat1File);
        break;
    }

    return;
}

void CovertToFormat0::ReadText(FILE* pFormat1File)
{
    fread(&(m_track.unDataLength), 1, 1, pFormat1File);
    //m_track.unDataLength = 0;
    m_unTrackLength++;

    BYTE* pText = new BYTE[m_track.unDataLength+1];
    m_track.pbyteTrackData = new BYTE[m_track.unDataLength+1];
    memset(m_track.pbyteTrackData, 0x00, m_track.unDataLength+1);

    for(UINT nCount=0; nCount<m_track.unDataLength; nCount++)
    {
        fread(&(m_track.pbyteTrackData[nCount]), 1, 1, pFormat1File);
        m_unTrackLength++;
    }


    

    return;
}

void CovertToFormat0::ReadChannelMessage(FILE* pFormat1File,  BYTE byteStatusByte)
{
    switch(byteStatusByte & 0xF0)
    {
    case 0x80 :
    case 0x90 :
    case 0xA0 :
    case 0xB0 :
    case 0xE0 :
        //음 값
        if(!m_bRunning)
        {
            fread(&(m_track.byteEventByte), 1, 1, pFormat1File);
            m_unTrackLength++;
        }
        m_bRunning = FALSE;
        //Velocity
        fread(&(m_track.unDataLength), 1, 1, pFormat1File);
        m_unTrackLength++;
        break;

    case 0xC0 :
    case 0xD0 :
        fread(&(m_track.byteEventByte), 1, 1, pFormat1File);
        m_unTrackLength++;
        break;
    }
    return;
}
c++
c
mfc
midi
asked on Stack Overflow May 12, 2021 by Jungwon

1 Answer

2
#include "stdafx.h"
#include "CovertToFormat0.h"


CovertToFormat0::CovertToFormat0(void)
{
}


CovertToFormat0::~CovertToFormat0(void)
{
}

void CovertToFormat0::GethWnd(HWND hWnd)
{
    m_hWnd = hWnd;
}

void CovertToFormat0::LittleEndian(BYTE* pbyteData, int nCount)
{
    int nArrayCount1 = 0;
    int nArrayCount2 = 0;

    BYTE* pTempData = new BYTE[nCount];

    for(nArrayCount1=0, nArrayCount2=nCount-1; nArrayCount1<nCount; nArrayCount1++, nArrayCount2--)
    {
        pTempData[nArrayCount2] = pbyteData[nArrayCount1];
    
    }

    for(nArrayCount1=0; nArrayCount1<nCount; nArrayCount1++)
    {
        pbyteData[nArrayCount1] = pTempData[nArrayCount1];
    }

    delete[] pTempData;
}

BOOL CovertToFormat0::CovertMIDI(CString& strFormat1FilePath, CString& strFormat0FilePath)
{
    FILE* pFormat1File = fopen(strFormat1FilePath, _T("rb"));
    m_bSequence = FALSE;
    //헤더 정보 읽기
    ReadHeadChunk(pFormat1File, strFormat1FilePath);    

    UINT unTrackCount = (UINT)m_head.ushTrackOfNum;
    m_head.ushTrackOfNum = 0x01;


    //트랙 정보 읽기
    m_unTrackLength = 0;
    
    UINT unTemp = 0;

    for(UINT unCount=0; unCount<2; unCount++)
    {
        ReadTrackChunk(pFormat1File, strFormat0FilePath, unTrackCount);
    }

    fclose(pFormat1File);

    for(UINT nSize=0; nSize<m_vector.size(); nSize++)
    {
        for(UINT nCount=0; nCount<m_vector.size()-nSize; nCount++)
        {
            if(m_vector[nCount].unSMPTE > m_vector[nSize].unSMPTE)
            {
                unTemp = m_vector[nCount].unSMPTE;
                m_vector[nCount].unSMPTE = m_vector[nSize].unSMPTE;
                m_vector[nSize].unSMPTE = unTemp;
            }
        }
    }

    //Write
    FILE* pFormat0File = fopen(strFormat0FilePath, _T("wb"));

    WriteHeader(pFormat0File, strFormat0FilePath);

    WriteTrack(pFormat0File);
    fclose(pFormat0File);

    return TRUE;
}

BOOL CovertToFormat0::ReadHeadChunk(FILE* pFormat1File, CString& strFormat1FilePath)
{

    if(!pFormat1File)
    {
        MessageBox(m_hWnd, _T("pFormat1File Open Failed"), _T("ERROR"), MB_OK);
        fclose(pFormat1File);
        return FALSE;
    }

    //MIDI 구조체의 헤더 0x00 초기화
    memset(m_head.szHeader, 0x00, 5);
    m_head.uHeaderLength = 0;
    m_head.ushFormatNum = 0;
    m_head.ushTrackOfNum = 0;
    m_head.ushTimeDivision = 0;

    //헤더 MThd 4바이트 읽어오기
    fread(m_head.szHeader, 4, 1, pFormat1File);
    
    //헤더가 MThd가 아니라면 return FALSE
    if(strcmp(m_head.szHeader, HEADERCHUNK) != 0)
    {
        MessageBox(m_hWnd, _T("헤더가 MThd이 아닙니다."), _T("오류"), MB_OK);
        fclose(pFormat1File);
        return FALSE;
    }

    //헤더 길이 읽기
    fread(&(m_head.uHeaderLength), 4, 1, pFormat1File);
    LittleEndian((BYTE*)&m_head.uHeaderLength, 4);

    //헤더정보가 잘못되었는지 체크
    if(m_head.uHeaderLength != 0x00000006)
    {
        MessageBox(m_hWnd, _T("헤더 길이가 잘못되었습니다."), _T("ERROR"), MB_OK);
        fclose(pFormat1File);
        return FALSE;
    }

    //포멧정도 읽기
    fread(&(m_head.ushFormatNum), 2, 1, pFormat1File);
    LittleEndian((BYTE*)&m_head.ushFormatNum, 2);
    //포멧0 로 값입력
    m_head.ushFormatNum = 0x00;

    //트랙개수 읽기
    fread(&(m_head.ushTrackOfNum), 2, 1, pFormat1File);
    LittleEndian((BYTE*)&m_head.ushTrackOfNum, 2);

    //분해능 읽기
    fread(&(m_head.ushTimeDivision), 2, 1, pFormat1File);
    LittleEndian((BYTE*)&m_head.ushTimeDivision, 2);

    return TRUE;
}

BOOL CovertToFormat0::ReadTrackChunk(FILE* pFormat1File, CString& strFormat0FilePath, UINT unTrackCount)
{
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

    //Track Chunk 읽기
    memset(m_track.szTrack, 0x00, 5);
    m_track.unSMPTE = 0;
    m_track.unDeltaTime = 0;
    m_track.byteStatusByte = 0x00;
    m_track.byteEventByte = 0x00;
    m_track.unDataLength = 0;
    m_track.pbyteTrackData = NULL;

    m_nEndTrack = FALSE;
    m_bRunning = FALSE;

    fread(m_track.szTrack, 4, 1, pFormat1File);
    if(strcmp(m_track.szTrack, TRACKCHUNK) != 0)
    {
        MessageBox(m_hWnd, _T("TRACK Chunk Not MTrk"), _T("ERROR"), MB_OK);
        fclose(pFormat1File);
        return FALSE;
    }
    UINT unTrackLanngth = 0;
    //트랙 길이 읽기
    fread(&(unTrackLanngth), 4, 1, pFormat1File);
    LittleEndian((BYTE*)&unTrackLanngth, 4);    


    UINT unDeltaTime = 0;

    while(!m_nEndTrack)
    {
        //1BYTE씩 읽기
        //DeltaTime 읽기
        fread(&(m_track.unDeltaTime), 1, 1, pFormat1File);
        m_unTrackLength++;

        if(m_track.unDeltaTime & 0x80)
        {
            unDeltaTime = 0;
            fread(&unDeltaTime, 1, 1, pFormat1File);

            m_track.unDeltaTime = m_track.unDeltaTime << 8;
            m_track.unDeltaTime += unDeltaTime;
            m_track.unSMPTE += m_track.unDeltaTime;
            m_unTrackLength++;
        }
        else
        {
            m_track.unSMPTE += m_track.unDeltaTime;
        }

        //상태바이트 읽기
        BYTE byteStatusByte = 0x00;
        fread(&(byteStatusByte), 1, 1, pFormat1File);

        if(byteStatusByte & 0x80)
        {
            m_track.byteStatusByte = byteStatusByte;
            m_unTrackLength++;
        }
        else
        {
            m_track.byteEventByte = byteStatusByte;
            m_unTrackLength++;
            m_bRunning = TRUE;
        }

        if((m_track.byteStatusByte & 0xF0) == 0xF0)
        {
            ReadSystemMessage(pFormat1File, m_track.byteStatusByte);
        }
        else
        {
            ReadChannelMessage(pFormat1File, m_track.byteStatusByte);
        }
        m_vector.push_back(m_track);

        if(m_track.pbyteTrackData != NULL)
        {
            delete[] m_track.pbyteTrackData;
        }

        m_track.byteEventByte = 0x00;
        m_track.unDataLength = 0x00;
        m_track.unDeltaTime = 0x00;
        m_track.pbyteTrackData = NULL;
    }
    return TRUE;
}
 
BOOL CovertToFormat0::WriteHeader(FILE* pFormat0File, CString& strFormat0FilePath)
{
    if(!pFormat0File)
    {
        MessageBox(m_hWnd, _T("pFormat0Fole Open Failed!"), _T("ERROR"), MB_OK);
        fclose(pFormat0File);
        return FALSE;
    }

    fwrite(m_head.szHeader, 4, 1, pFormat0File);
    LittleEndian((BYTE*)&m_head.uHeaderLength, 4);
    fwrite(&(m_head.uHeaderLength), 4, 1, pFormat0File);
    LittleEndian((BYTE*)&m_head.ushFormatNum, 2);
    fwrite(&(m_head.ushFormatNum), 2, 1, pFormat0File);
    LittleEndian((BYTE*)&m_head.ushTrackOfNum, 2);
    fwrite(&(m_head.ushTrackOfNum), 2, 1, pFormat0File);
    LittleEndian((BYTE*)&m_head.ushTimeDivision, 2);
    fwrite(&(m_head.ushTimeDivision), 2, 1, pFormat0File);


    return TRUE;
}

BOOL CovertToFormat0::WriteTrack(FILE* pFormat0File)
{
    fwrite(m_track.szTrack, 4, 1, pFormat0File);
    LittleEndian((BYTE*)&m_head.ushTimeDivision, 4);
    fwrite(&(m_unTrackLength), 4, 1, pFormat0File);

    std::vector<TRACK>::iterator iter;

    for(iter=m_vector.begin(); iter!=m_vector.end(); iter++)
    {
        if(iter->unDeltaTime & 0x80)
        {
            fwrite(&(iter->unDeltaTime), 2, 1, pFormat0File);
        }
        else
        {
            fwrite(&(iter->unDeltaTime), 1, 1, pFormat0File);
        }

        if(iter->byteStatusByte != 0x00)
        {
            fwrite(&(iter->byteStatusByte), 1, 1, pFormat0File);
        }

        if(iter->byteEventByte != 0x00)
        {
            fwrite(&(iter->byteEventByte), 1, 1, pFormat0File);
        }

        if(iter->unDataLength != 0)
        {
            fwrite(&(iter->unDataLength), 1, 1, pFormat0File);
        }

        if(iter->pbyteTrackData != 0x00)
        {
            for(int n=0; n<iter->unDataLength; n++)
            {
                fwrite(&(iter->pbyteTrackData[n]), 1, 1, pFormat0File);
            }
        }
    }

    BYTE byteEnd1 = 0xFF;
    BYTE byteEnd2 = 0x2F;
    BYTE byteEnd3 = 0x00;
    fwrite(&byteEnd1, 1, 1, pFormat0File);
    fwrite(&byteEnd2, 1, 1, pFormat0File);
    fwrite(&byteEnd3, 1, 1, pFormat0File);


    return TRUE;
}

void CovertToFormat0::ReadSystemMessage(FILE* pFormat1File, BYTE byteStatusByte)
{
    switch(byteStatusByte & 0x0F)
    {
    case 0x00:  //Exclusive Change
    case 0x07:  //End Of Exclusive

        //SystemExclusiveMessage
        break;  

    case 0x01:  //Cutter Frame Change
    case 0x02:  //Song Position Pointer
    case 0x03:  //Song Selector     
    case 0x04:  //current Running Status is cancel
    case 0x05:  //current Running Status is cancel
    case 0x06:  //Tune Request

        //SystemCommonMessage
        break;

    case 0x08:  //Timing Clock
    case 0x0A:  //Start
    case 0x0B:  //continue
    case 0x0C:  //Stop  
    case 0x0E:  //Active Sensing
    case 0x0F:  //System Reset  
        ReadMetaEventMessage(pFormat1File);
        break;
    }

    return;
}

void CovertToFormat0::ReadMetaEventMessage(FILE* pFormat1File)
{
    UINT unLength = 0;
    BYTE byteData = NULL; 
    //Event Byte Read
    if(m_track.byteEventByte == 0x00)
    {
        fread(&(m_track.byteEventByte), 1, 1, pFormat1File);
        m_unTrackLength++;
    }

    switch(m_track.byteEventByte)
    {
    case 0x00 :
        ReadText(pFormat1File);
        break;
    case 0x01 :
        ReadText(pFormat1File);
        break;
    case 0x02 :
        ReadText(pFormat1File);
        break;
    case 0x03 :
        if(!m_bSequence)
        {
            ReadText(pFormat1File);
            m_bSequence = TRUE;
        }
        else
        {
            fread(&(unLength), 1, 1, pFormat1File);
            for(UINT nCount=0; nCount<unLength; nCount++)
            {
                fread(&byteData, 1, 1, pFormat1File);
            }

            m_track.byteStatusByte = 0x00;
            m_track.byteEventByte = 0x00;
        }
        break;
    case 0x04 :
        ReadText(pFormat1File);
        break;
    case 0x05 :
        ReadText(pFormat1File);
        break;
    case 0x06 :
        ReadText(pFormat1File);
        break;
    case 0x07 :
        ReadText(pFormat1File);
        break;
    case 0x20 :
        ReadText(pFormat1File);
        break;
    case 0x2F :
        m_unTrackLength -= 2;
        fread(&unLength, 1, 1, pFormat1File);
        m_track.byteStatusByte = 0x00;
        m_track.byteEventByte = 0x00;
        m_nEndTrack = TRUE;
        break;
    case 0x51:
        ReadText(pFormat1File);
        break;
    case 0x54 :
        ReadText(pFormat1File);
        break;
    case 0x58 :
        ReadText(pFormat1File);
        break;
    case 0x59 :
        ReadText(pFormat1File);
        break;
    }

    return;
}

void CovertToFormat0::ReadText(FILE* pFormat1File)
{
    fread(&(m_track.unDataLength), 1, 1, pFormat1File);
    //m_track.unDataLength = 0;
    m_unTrackLength++;

    BYTE* pText = new BYTE[m_track.unDataLength+1];
    m_track.pbyteTrackData = new BYTE[m_track.unDataLength+1];
    memset(m_track.pbyteTrackData, 0x00, m_track.unDataLength+1);

    for(UINT nCount=0; nCount<m_track.unDataLength; nCount++)
    {
        fread(&(m_track.pbyteTrackData[nCount]), 1, 1, pFormat1File);
        m_unTrackLength++;
    }


    

    return;
}

void CovertToFormat0::ReadChannelMessage(FILE* pFormat1File,  BYTE byteStatusByte)
{
    switch(byteStatusByte & 0xF0)
    {
    case 0x80 :
    case 0x90 :
    case 0xA0 :
    case 0xB0 :
    case 0xE0 :
        //음 값
        if(!m_bRunning)
        {
            fread(&(m_track.byteEventByte), 1, 1, pFormat1File);
            m_unTrackLength++;
        }
        m_bRunning = FALSE;
        //Velocity
        fread(&(m_track.unDataLength), 1, 1, pFormat1File);
        m_unTrackLength++;
        break;

    case 0xC0 :
    case 0xD0 :
        fread(&(m_track.byteEventByte), 1, 1, pFormat1File);
        m_unTrackLength++;
        break;
    }
    return;
}
answered on Stack Overflow May 12, 2021 by Jungwon

User contributions licensed under CC BY-SA 3.0