Help! About audio playback, use [cpal] and [lewton]

#1


I am writing an audio player.Use cpal and lewton.

Cpal is a Cross-Platform Audio Library.
Lewton is the decoder of ogg.

My code is here:

use std::io::Read;
use std::io::SeekFrom;
use cpal::EventLoop;
use cpal;
use cpal::StreamData;
use cpal::UnknownTypeInputBuffer;
use cpal::UnknownTypeOutputBuffer;
use std::vec::IntoIter;

fn main() {
    let event_loop = EventLoop::new();
    let output_device = cpal::default_output_device().unwrap();
    let output_format = output_device.default_output_format().unwrap();

    let stream_id = event_loop.build_output_stream(&output_device, &output_format).unwrap();
    event_loop.play_stream(stream_id.clone());

    let file_path = "assets/music.ogg";
    let file = File::open(file_path).unwrap();
    let mut ogg_stream_reader = OggStreamReader::new(file).unwrap();
   
    let sample_rate = ogg_stream_reader.ident_hdr.audio_sample_rate as f32;
    let channels = ogg_stream_reader.ident_hdr.audio_channels as f32;

    let mut data = Vec::new();
    while let Some(pcks) = ogg_stream_reader.read_dec_packet().unwrap() {
        for mut pck in pcks {
            data.append(&mut pck);
        }
    }
    let mut data = data.into_iter();

    let mut next_value = || {
        let sample = data.next().unwrap_or(0) as f32;
        let sample = sample / sample_rate;
        sample
    };

    event_loop.run(|stream_id, stream_data| {
        match stream_data {
            StreamData::Input { buffer} => {
                match buffer {
                    UnknownTypeInputBuffer::U16(buffer) => {}
                    UnknownTypeInputBuffer::I16(buffer) => {}
                    UnknownTypeInputBuffer::F32(buffer) => {}
                }
            }
            StreamData::Output { buffer } => {
                match buffer {
                    UnknownTypeOutputBuffer::U16(mut buffer) => {}
                    UnknownTypeOutputBuffer::I16(mut buffer) => {}
                    UnknownTypeOutputBuffer::F32(mut buffer) => {
                        for d in buffer.iter_mut() {
                            *d = next_value();
                        }
                    }
                }
            }
        }
    });
}

The audio can be played, but it sounds weird! (The melody is correct, but tone is incorrect)

I am not professional about audio.

I probably think the reason it is following code:

    let mut next_value = || {
        // data is a Vec<i16> raw samples from OggDecoder
        let sample = data.next().unwrap_or(0) as f32;
        let sample = sample / sample_rate;  // I feel that here is not right!
        sample
    };

Can someone guide me the correct way?
Thank yout.

#2

I don’t think you want to divide the sample value by the sample rate. Sample value is essentially the amplitude of the wave at that moment in time, and the sample rate says how many samples were taken in a second.