我目前正在尝试学习如何使用 Alsa 播放音频文件。我似乎大部分时间都拥有它,文件加载和播放,但我必须将频率降低一半才能让它正确播放。为什么会这样,我该如何解决?
这是我目前使用的 Vala 代码:
using Alsa;
using Gee;
using OGG;
namespace SoundTest
{
public class Sound : Object
{
private PcmDevice sound_device;
private char[] sound_data;
private uint8[] alsa_data;
private long bit_rate;
public class Sound()
{
}
~Sound()
{
sound_device.drain();
sound_device.close();
}
public void init()
{
read_sound_file();
setup_sound_player();
}
public void play_sound_file()
{
sound_device.writei(alsa_data, sound_device.bytes_to_frames(alsa_data.length));
}
private uint8[] convert_data(char[] buffer)
{
uint8[] conversion;
// Just need to convert to an array of uint8s.
conversion = new uint8[buffer.length];
for (int i = 0; i < buffer.length; i++)
{
conversion[i] = (uint8)buffer[i];
}
return conversion;
}
private void setup_sound_player()
{
// Open the sound device.
if (PcmDevice.open(out sound_device, "default", PcmStream.PLAYBACK, 0) != 0)
{
critical("Unable to open a sound device\n");
return;
}
// Set the parameters to use for playback.
if (sound_device.set_params(PcmFormat.S16_LE, PcmAccess.RW_INTERLEAVED, 2, (int)bit_rate/2, 1, 500000) != 0)
{
critical("Could not set params properly\n");
return;
}
// Prepare the device for playback.
if (sound_device.prepare() != 0)
{
critical("Could not prepare the device\n");
return;
}
}
private void read_sound_file()
{
char[] buffer;
int stream;
long bytesRead;
string filename;
File inputFile;
Info? soundInfo = null;
Vorbis soundFile;
ArrayList<char> data;
filename = "./Median_test.ogg";
// Make sure the file exists.
inputFile = File.new_for_path(filename);
if (inputFile.query_exists())
{
// Set the file to be read.
message("Reading file: %s\n", filename);
soundFile = Vorbis(filename);
// Get the information about the sound file.
soundInfo = soundFile.get_info(-1);
if (soundInfo != null)
{
stdout.printf("Version: %d\nChannels: %d\nRate: %ld\nBitrate: %ld, %ld, %ld\n\n",
soundInfo.version, soundInfo.channels,
soundInfo.rate, soundInfo.bitrate_lower,
soundInfo.bitrate_nominal, soundInfo.bitrate_upper);
// Store the bitrate information of the sound file.
bit_rate = soundInfo.rate;
}
// Read the data from the file. Here I read a small array worth of
// data and then store it in an array list. I then need to turn
// that array list into a single array. I wish there was a function
// to do it from the list, but I'll just loop.
buffer = new char[4096];
stream = 0;
data = new ArrayList<char>();
bytesRead = soundFile.read(buffer, 0, 2, 1, ref stream);
while (bytesRead > 0)
{
for (int i = 0; i < bytesRead; i++)
{
data.add(buffer[i]);
}
bytesRead = soundFile.read(buffer, 0, 2, 1, ref stream);
}
stdout.printf("Bytes read: %ld\n", bytesRead);
sound_data = new char[data.size];
for (int i = 0; i < data.size; i++)
{
sound_data[i] = data[i];
}
// Now convert the vorbis data into the type of data alsa needs.
alsa_data = convert_data(sound_data);
}
else
{
critical("No such file:\n\t%s\n\n", filename);
}
}
public static int main(string[] args)
{
Sound test;
stdout.printf("Starting Sound Test\n");
test = new Sound();
test.init();
test.play_sound_file();
stdout.printf("Done\n");
return 0;
}
}
}
感谢您提供的任何帮助。