sdl-2sdl-mixer

How to change Mix_Chunk to Mix_Music in SDL2


if (SDL_Init(SDL_INIT_AUDIO) < 0) return -1;
        
if( Mix_OpenAudio( 48000, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ) return -1; 
Mix_Chunk *wave = Mix_LoadWAV("a.wav");
auto *p = SDL_RWFromMem(wave->abuf, wave->alen);
if(!p || !wave) return -1;
Mix_Music *music = Mix_LoadMUSType_RW(p, MUS_WAV, 0);
if(!music) cout <<"load Mus error " << SDL_GetError() << endl;
Mix_PlayMusic(music, 2);
//Mix_PlayChannel(-1, wave, 1);
char c;
cin >> c;

Mix_FreeMusic(music);
Mix_FreeChunk(wave);
Mix_CloseAudio();

I want to manipulate some wave data and store it in Mix_Music format with SDL2_Mixer. Above code gives me "load Mus error unknown wave format" error.

commented Mix_PlayChannel function works fine.

How can I change this code to make Mix_PlayMusic function work?


Solution

  • I had to add Wav header to make it work properly.

    I did this manually, but, there might be a better way.

    struct WavHeader
    {
        char riff[4] = {'R', 'I', 'F', 'F'};
        uint32_t size = 0;
        char type[4] = {'W', 'A', 'V', 'E'};
        char fmt[4] = {'f', 'm', 't', ' '};
        uint32_t len = 16;
        uint16_t pcm = 1;
        uint16_t channel = 2;
        uint32_t sample = 48000;
        uint32_t sam = 48000 * 16 * 2 / 8;
        uint16_t bitstereo = 4;
        uint16_t bitpsample = 16;
        char data[4] = {'d', 'a', 't', 'a'};
        uint32_t datasize = 0;
        WavHeader(int sz) {
            datasize = sz;
            size = sz + 44;
        }
    };
    
    int main(int argc, char* argv[]) 
    {
        if (SDL_Init(SDL_INIT_AUDIO) < 0) return -1;
        if( Mix_OpenAudio( 48000, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ) return -1; 
    
        Mix_Chunk *wave = Mix_LoadWAV(WAV_PATH);
        WavHeader h{wave->alen};
        void *wd = malloc(wave->alen + 44);
        memcpy(wd, &h, 44);
        memcpy(wd + 44, wave->abuf, wave->alen);
        if(!wave) cout << SDL_GetError() << endl;
        auto *p = SDL_RWFromMem(wd, wave->alen + 44);
        if(!p) cout << SDL_GetError() << endl;
    
        Mix_Music *music = Mix_LoadMUSType_RW(p, MUS_WAV, 0);
        if(!music) cout <<" loasMus error " << SDL_GetError() << endl;
        Mix_PlayMusic(music, 2);
        //Mix_PlayChannel(-1, wave, 1);
        
        if(Mix_SetMusicPosition(3) == -1) cout << SDL_GetError() << endl;;
    
        char c;
        cin >> c;
    
        Mix_FreeMusic(music);
        Mix_FreeChunk(wave);
        Mix_CloseAudio();
        free(wd);
        
        return 0;
    }
    
    

    But there is another problem, Mix_SetMusicPosition function does not work. It says "Position not implemented for Music type".