2013-02-22 104 views
2

我目前正试图学习如何使用Alsa来播放音频文件。我似乎有大部分的方式,文件加载和播放,但我必须减少一半的频率,以使其正确播放。为什么会这样,我该如何解决它?Alsa以2倍的频率播放vorbis

这是我目前使用的瓦拉代码:

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; 
     } 
    } 
} 

感谢您的帮助,您可以给。

+0

那个文件的费率是多少? – 2013-02-22 07:34:13

+0

@CL该文件显示速率为44100.我用于测试的文件可以在这里找到(http://en.wikipedia.org/wiki/File:Median_test.ogg)。 – 2013-02-23 03:17:46

回答

2

您正在为两个通道配置声音设备,但该文件实际上只有一个。

+0

谢谢。这正是我的问题。好的,我猜我需要用这些信息制作一个声源结构。再次感谢你。 – 2013-02-23 17:17:33