Code: play.cpp while (mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK) { ao_play(dev, reinterpret_cast<char*>(buffer), done); fprintf(stderr, "Frame: %li\n", mpg123_tellframe(mh)); } //===========reinterpret_cast<char*>(buffer) : digunakan untuk mengkonversikan type buffer unsigned char menjadi char.
cuplikan kode tersebut jika dikompilasi menggunakan mingw gcc akan error, karena gcc tidak mengenal fungsi reinterpret_cast tersebut.
jika diinginkan dapat dicari cara lain untuk melakukan type casting dari unsigned char menjadi char, namun setelah fungsi ao_play() dioprek langsung dari kode sumber libao, maka kita dapat merubah type data char yang digunakan menjadi unsigned char, sehingga tidak perlu melakukan terlalu banyak effort.
berikut ini prosedurnya:
1. extract kode sumber libao (<a href="http://downloads.xiph.org/releases/ao/libao-1.1.0.zip">http://downloads.xiph.org/releases/ao/libao-1.1.0.zip</a>) dan explore kedalam folder src.
2. edit file audio_out.c dengan codeblock dan silahkan cari (ctrl+f) ao_play.
3. didalam fungsi ao_play tersebut lakukan persesuaian type data
int ao_play(ao_device *device, char* output_samples, uint_32 num_bytes) { char *playback_buffer; if (device == NULL) return 0; if (device->swap_buffer != NULL) { int out_bytes = num_bytes*device->output_channels/device->input_channels; if (_realloc_swap_buffer(device, out_bytes)) { int i; int swap = (device->bytewidth>1 && device->client_byte_format != device->driver_byte_format); for(i=0;i<device->output_channels;i++){ int ic = device->inter_permute ? device->inter_permute[i] : i; if(ic==-1){ _buffer_zero(device->swap_buffer,i,device->bytewidth,device->output_channels, out_bytes); }else if(swap){ _buffer_permute_swap(device->swap_buffer,i,device->bytewidth,device->output_channels, out_bytes, output_samples, ic, device->input_channels); }else{ _buffer_permute(device->swap_buffer,i,device->bytewidth,device->output_channels, out_bytes, output_samples, ic, device->input_channels); } } playback_buffer = device->swap_buffer; num_bytes = out_bytes; } else return 0; /* Could not expand swap buffer */ } else playback_buffer = output_samples; return device->funcs->play(device, playback_buffer, num_bytes); }
4. lihat argumen output_samples disana didefinisikan sebagai char* rubahlah menjadi unsigned char* output_samples.
5. lihat deklarasi playback_buffer ia juga didefinisikan sebagai char* rubahlah menjadi unsigned char*.
berikut perubahannya:
int ao_play(ao_device *device, unsigned char* output_samples, uint_32 num_bytes) { unsigned char *playback_buffer; if (device == NULL) return 0; if (device->swap_buffer != NULL) { int out_bytes = num_bytes*device->output_channels/device->input_channels; if (_realloc_swap_buffer(device, out_bytes)) { int i; int swap = (device->bytewidth>1 && device->client_byte_format != device->driver_byte_format); for(i=0;i<device->output_channels;i++){ int ic = device->inter_permute ? device->inter_permute[i] : i; if(ic==-1){ _buffer_zero(device->swap_buffer,i,device->bytewidth,device->output_channels, out_bytes); }else if(swap){ _buffer_permute_swap(device->swap_buffer,i,device->bytewidth,device->output_channels, out_bytes, output_samples, ic, device->input_channels); }else{ _buffer_permute(device->swap_buffer,i,device->bytewidth,device->output_channels, out_bytes, output_samples, ic, device->input_channels); } } playback_buffer = device->swap_buffer; num_bytes = out_bytes; } else return 0; /* Could not expand swap buffer */ } else playback_buffer = output_samples; return device->funcs->play(device, playback_buffer, num_bytes); }
6. Simpan perubahan tersebut, dan silahkan buka folder include, edit file ao/ao.h, lakukan pencarian (ctrl+f) ao_play juga, dan lakukan persesuaian lagi.
int ao_play(ao_device *device, char *output_samples, uint_32 num_bytes);
sesuaikan menjadi:
int ao_play(ao_device *device, unsigned char *output_samples, uint_32 num_bytes);
7. Simpan dan kompilasi ulang library libao tersebut (./configure via msys dan mingw32-make).
8. Jadikan library libao hasil kompilasi menjadi opsi linker yang digunakan oleh codeblok / visual studio.
9. Sedangkan source kode player kita akan menjadi sbb:
#include <mpg123.h> #include <ao/ao.h> #include <malloc.h> #include <stdlib.h> #include <windows.h> #define BITS 8 int main(int argc, char *argv[]) { mpg123_handle *mh; unsigned char *buffer; size_t buffer_size; size_t done; int err, driver, channels, encoding; ao_device *dev; ao_sample_format format; long rate; ao_initialize(); driver = ao_default_driver_id(); // ========= inisial library ============= mpg123_init(); mh = mpg123_new(NULL, &err); buffer_size = mpg123_outblock(mh); buffer = (unsigned char*)malloc(buffer_size * sizeof(unsigned char)); mpg123_param(mh, MPG123_RESYNC_LIMIT, -1, 0); char* filename=argv[1]; mpg123_open(mh, filename); mpg123_getformat(mh, &rate, &channels, &encoding); // ************************************ format.bits = mpg123_encsize(encoding) * BITS; format.rate = rate; format.channels = channels; format.byte_format = AO_FMT_NATIVE; format.matrix = 0; double secs; dev = ao_open_live(driver, &format, NULL); while (mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK) { ao_play(dev, buffer, done); fprintf(stderr, "Frame: %li\n", mpg123_tellframe(mh)); mpg123_position(mh, 0, 0, NULL, NULL, &secs, NULL); fprintf(stderr,"[%d:%02d] Decoding of %s finished.\n", (int)(secs / 60), ((int)secs) % 60, filename); } /* clean up */ free(buffer); ao_close(dev); mpg123_close(mh); mpg123_delete(mh); mpg123_exit(); ao_shutdown(); return 0; }nah kode diatas sudah tidak menggunakan reinterpret_cast<>() lagi, ini dapat dikompilasi oleh mingw gcc. selamat mencoba...