How to change Mix_Chunk to Mix_Music in SDL2_Mixer

I couldn’t find any documentation about this. Can anyone help me?

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?

Have you tried: Mix_Music *music = Mix_LoadMUS("a.wav");

If you really need to modify the wave data before loading it as music, then you’ll need to prepend the raw data with a WAV header so the loader knows what format it’s in. Think about what you would need to do to write it back as a wave file.

I added header manually. Now it works. Thanks…
I will attach source I used for someone after me.

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);
	char c;
	cin >> c;

	Mix_FreeMusic(music);
	Mix_FreeChunk(wave);
	Mix_CloseAudio();
	free(wd);
	return 0;
}

1 Like

Thanks for your help, I could make music playable.
Now I have other problem.
After making music playable. I used Mix_SetMusicPosition function to set arbitrary position. It gives me “Position not implemented for music type” error.

Mix_SetMusicPosition Documentation says like this.

This function is only implemented for MOD music formats
 (set pattern order number) and for WAV, OGG, FLAC, 
MP3, and MODPLUG music at the moment.

So I think it should work. What is the problem?

Wav format does not allow setPosition. I had to change wav format to ogg with vorbis library.

What version of SDL_mixer are you using? Mix_SetMusicPosition() is implemented for WAV files in WAV_Seek(), in music_wav.c.