12/08/2018, 12:59

LibGDX Tutorial 8: Làm việc với Audio

Tutorial này rất đơn giản, cũng bởi vì LibGDX thao tác với Audio vô cùng dễ dàng. LibGDX hỗ trợ 3 định dạng Audio: ogg, mp3, và wav. MP3 là định dạng dễ dính vào các vấn đề pháp lý, trong khi WAV lại quá lớn, còn lại OGG thường là lựa chọn tốt nhất. Điều đó cũng có nghĩa là định dạng Ogg cũng có ...

Tutorial này rất đơn giản, cũng bởi vì LibGDX thao tác với Audio vô cùng dễ dàng. LibGDX hỗ trợ 3 định dạng Audio: ogg, mp3, và wav. MP3 là định dạng dễ dính vào các vấn đề pháp lý, trong khi WAV lại quá lớn, còn lại OGG thường là lựa chọn tốt nhất. Điều đó cũng có nghĩa là định dạng Ogg cũng có những vấn đề vì không được hỗ trợ rộng rãi trên các trình duyệt. Đây chính là lý do tại sau nhiều định dạng vẫn tồn tại và tiếp tục được sử dụng phổ biến.

Copy những file audio vào project giống như đã làm với những file font chữ và hình ảnh trong các tutorial trước vào trong thư mục assets của android project. Cũng như những tutorial trước, tôi copy những file audio vào như sau:

libgdx-project.png

Như bạn thấy, tôi đã thêm mỗi file cho mỗi định dạng, mp3.mp3, ogg.ogg và wav.wav.

Load các file vào vô cùng đơn giản:

Sound wavSound = Gdx.audio.newSound(Gdx.files.internal("wav.wav"));
Sound oggSound = Gdx.audio.newSound(Gdx.files.internal("ogg.ogg"));
Sound mp3Sound = Gdx.audio.newSound(Gdx.files.internal("mp3.mp3"));

Hàm này trả về đối tượng Sound bằng các truyền vào tên file. Khi có đối tượng Sound rồi, sử dụng method play() để chơi nhạc:

wavSound.play();

Bạn có thể thay đổi volume khi gọi phương thức play():

oggSound.play(0.5f);

Đoạn này sẽ chạy đối tượng oggSound với 50% volume.

Bạn cũng có thể chơi lặp lại một đối tượng Sound liên tục sử dụng method play() và loop(). Khi bạn chạy nó trả về một id để bạn tương tác với Sound. Cách làm việc như sau:

long id = mp3Sound.loop();
Timer.schedule(new Task(){
   @Override
   public void run(){
      mp3Sound.stop(id);
      }
   }, 5.0f);

Ở đây bạn bắt đầu một lặp một tệp tin mp3, và nhận được một giá trị id. Sau đó chúng ta thiết lập schedule cho một task sau 5 giây stop file mp3 đang được chạy. Lưu ý: khi gọi method stop, chúng ta đã truyền giá trị id, điều này cho phép bạn quản lý một thể hiện riêng của đối tượng Sound, tức là bạn có thể chạy nhiều đối tượng Sound cùng một lúc. Một điều cũng rất quan trọng, các đối tượng Sound cũng là một người tài nguyên được quản lý, vì vậy bạn cũng cần gọi phương thức dispose() để hủy nó khi không sử dụng nữa.

wavSound.dispose();
oggSound.dispose();
mp3Sound.dispose();

Khi có đối tượng Sound, bạn có thể thay đổi giá trị pitch (tốc độ):

long id = wavSound.play();
wavSound.setPitch(id, 0.5f);

Tham số đầu tiên là id của sound để thay đổi, tham số thức 2 mới là pitch. Giá trị nên là > 0.5 và < 2.0. Nhỏ hơn 1 là chậm hơn và lớn hơn 1 là nhanh hơn.

Bạn có thể thay đổi volume:

long id = wavSound.play();
wavSound.setVolume(id, 1.0f);

Một lần nữa bạn truyền vào id của sound, cũng như volume để phát. Giá trị 0 là im lặng, trong khi 1 là max volume. Bạn cũng có thể thiết lập Pan ( stereo position ) giống như vậy:

long id = wavSound.play();
wavSound.setPan(id, 1f, 1f);

Trong trường hợp này, tham số là id của sound, giá trị pan (1 là full left, 0 là center, -1 là full right) như là volume. Bạn cũng có thể chỉ định pitch, pan và volume khi gọi phương thức play() hoặc loop(). Một điều quan trọng, không ai dám đảo bảo rằng các phương thức trên có thể làm việc trên WebGL/HTML5. Ngoài ra các định dạng file khác nhau có thể không được hỗ trợ trên một số trình duyệt (điều này vô cùng khó chịu).

Ngoài ra để để chơi nhạc, LibGDX có hỗ trợ một cách chuyên biệt hơn. Sự khác biệt là LibGDX sẽ stream các hiệu ứng âm thanh, làm giảm đáng kể nhu cầu về bộ nhớ. Điều này được thực hiện bằng cách sử dụng Music class. May mắn thay nó là khá đơn giản:

Music mp3Music = Gdx.audio.newMusic(Gdx.files.internal("mp3.mp3"));
mp3Music.play();

Và đó là tất cả những gì bạn cần để stream 1 file audio. Các điều khiển khác nhau cho một file Music. Trước hết, không có id, vì vậy điều này nghĩa là bạn có thể chơi nhiều thể hiện của 1 file Music một lúc. Thứ 2, có một loạt các tùy chọn điều khiển với Music. Dưới đây là một vị dụ để chơi 1 file Music:

Music mp3Music = Gdx.audio.newMusic(Gdx.files.internal("mp3.mp3"));
mp3Music.play();
mp3Music.setVolume(1.0f);
mp3Music.pause();
mp3Music.stop();
mp3Music.play();
Gdx.app.log("SONG",Float.toString(mp3Music.getPosition()));

Sau khi Music được load, chúng ta play, sau đó thay thiết lập volume 100%. Tiếp theo chúng ta pause, stop và play nó một lần nữa. Như bạn có thể nhìn thấy hàm log() được gọi, bạn có thể có được vị trí playback của Music object bằng cách gọi getPosition(). Bạn có thể sẽ thắc mắc sự khác biệt thực sự giữa pause() và stop()? Gọi play() sau khi gọi pause(), nó sẽ chơi tiếp tục bài hát ở vị trí hiện tại. Còn gọi play() sau khi gọi stop() sẽ khởi động lại bài hát.

Một lần nữa, Music cũng là một tài nguyên được quản lý, vì vậy bạn cũng cần dispose() nó khi không sử dụng.

0