Làm thế nào để lặp phần từ một bài hát chính xác?


8

Tôi đang lập trình một Music Engine nhỏ cho trò chơi của mình bằng C # và XNA, và một khía cạnh từ đó là khả năng lặp một phần từ một bài hát. Ví dụ: bài hát của tôi có một đoạn intropart và khi bài hát đến cuối (hoặc bất kỳ điểm cụ thể nào khác), nó sẽ nhảy trở lại nơi đoạn intropart vừa kết thúc. (A - B - B - B ...)

Bây giờ tôi đang sử dụng WatersKlank, hoạt động hoàn hảo, không có bất kỳ khoảng trống nào, nhưng tôi gặp một vấn đề:

Điểm để nhảy trở lại là một chút không chính xác. Dưới đây là một số mã ví dụ:

public bool Passed(float time)
    {
        if ( PlayPosition >= time )
            return true;
        return false;
    }
//somewhere else
if( song.Passed( 10.0f ) )
   song.JumpTo( 5.0f );

Bây giờ vấn đề là, bài hát vượt qua 10 giây, nhưng phát vài mili giây cho đến 10.1f hoặc lâu hơn, và sau đó nhảy lên 5 giây. Nó không ấn tượng lắm, nhưng rất không đúng với nhu cầu của tôi. Tôi đã cố gắng sửa nó như thế:

public bool Passed( float time )
{
      if( PlayPosition + 3 * dt >= time && PlayPosition <= time )
             return true;
      return false;
}

(dt là thời gian delta, thời gian trôi qua kể từ khung cuối cùng)

Nhưng tôi không nghĩ rằng, đó là một giải pháp tốt cho điều đó.

Tôi hy vọng, bạn có thể hiểu vấn đề của tôi (và tiếng Anh của tôi, yay / o /) và giúp tôi :)


Bạn có thể chọn giữa phát trực tiếp âm thanh hoặc tải tất cả cùng một lúc không?
t shipode

Tôi nghĩ rằng nó có thể. Hiện tại tôi đang tải bài hát hoàn chỉnh, vì tôi nghĩ, nhảy xung quanh bài hát sẽ nhanh hơn. Tôi đang thử Đa luồng để giải quyết vấn đề này, nhưng tôi vẫn không may mắn: /
Teflo

Thay vào đó hãy thử phát trực tiếp âm thanh. Rốt cuộc, nó sẽ có thể tải một đoạn nhỏ của bài hát gần như ngay lập tức.
t shipode

Bài hát của bạn được mã hóa như thế nào?
michael.bartnett

Có lẽ thay vì sử dụng "đã qua", bạn có thể thêm ques (như các sự kiện) thực hiện chức năng gọi lại. Tôi không biết làm thế nào bạn quản lý thời gian của bạn. Nhưng bạn không thể sử dụng số lượng byte đã đọc cho đến nay và so sánh nó với tổng số byte dịch nó thành một thời gian chính xác? Bạn sẽ có thể tính toán lượng dữ liệu được đọc trong một giây. Tôi không biết điều này sẽ diễn ra nhanh như thế nào. Nhưng có lẽ sau đó bạn có thể đọc thời gian chính xác hơn.
Sidar

Câu trả lời:


3

Theo tôi, một giải pháp đơn giản và thông thường hơn là có hai bản nhạc khác nhau: phần giới thiệu và phần vòng lặp. Sau đó, vấn đề duy nhất là phát hiện khi phần giới thiệu kết thúc (khá dễ dàng, mặc dù không hoàn toàn chính xác nếu sử dụng 30fps). Sau đó, bản nhạc thứ hai có thể được phát với tính năng lặp.

Do đó, bạn giảm các lỗi trong quá trình sao chép xuống một chút độ trễ khi bắt đầu vòng lặp lần đầu tiên, thay vì mỗi lần phần vòng lặp phải được tua lại.


0

Giải pháp lý tưởng là biết trước phần nào của bài hát cần được tải tiếp theo vào bộ đệm. Mỗi 'phần' A - B - C sẽ có thời gian bắt đầu và kết thúc, và đó sẽ là hệ thống truyền phát cấp thấp hơn của bạn sẽ tải các phần chính xác của tệp theo đúng thứ tự. Bạn sẽ phải có một bitrate cố định để điều này hoạt động, và có thể khá khó khăn để tìm vị trí trong tệp bạn cần bỏ qua để tiếp theo.

Tôi đã xem nhanh trang web irKlang và họ tự hào về khả năng viết trình đọc / giải mã định dạng tệp của riêng bạn để mở rộng công cụ với nó, vì vậy bạn có thể muốn đưa ra một cú đánh.

Ngoài ra còn có một hướng dẫn ở đây để ghi đè quyền truy cập tệp - bạn có thể đưa ra ý tưởng ban đầu của tôi hoặc bạn có thể kết hợp nó với nhiều âm thanh như Elideb nói. Bạn có thể mở rộng lớp CMyReadFile của mình để có quyền truy cập vào nhiều tệp (như PartA.wav, PartB.wav, PartC.wav) và bạn có thể ghi đè phương thức đọc, thay vì chỉ:

return (s32)fread(buffer, 1, sizeToRead, File);

Bạn có thể làm một cái gì đó như:

switch(CurrentSectionToPlay)
{
case A:
    return (s32)fread(buffer, 1, sizeToRead, FileA);
case B:
    return (s32)fread(buffer, 1, sizeToRead, FileB);
}

Điều đó có nghĩa là bài hát sẽ thay đổi liên tục phần mà không cần phải đồng bộ Plays & Stops.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.