Skip to content

SPDIF IEC61937 encapsulated AAC(adts stream) through D2VOX device(hw:1,0) using ALSA outputs noise data. #222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
VanithaChannaiah opened this issue Nov 6, 2013 · 11 comments

Comments

@VanithaChannaiah
Copy link

D2VOX device is USB based device used as second card to play the output.

I have played wav file using below command through D2VOX device ,
aplay -D plughw:1,0 filename1.wav

similar way, i tried to play IEC61937 encapsulated adts(aac) stream named as IEC61937_data.aac in which the contents are as [ 72 f8 1f 4e 07 00 68 00 ff f8 50 40 01 a2 44 d5 8b 00 c8 00 07.... ]
here :
72 f8 1f 4e 07 00 68 00 : are spdif header.
ff f8 50 40 01 a2 44 d5 8b 00 c8 00 07... : ADTS stream

  1. aplay -f S16_LE -Dplughw:1,0 IEC61937_data.aac
    Playing raw data 'IEC61937_data.bin' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono

It outputs only noise ( kkrrr sound ) and not the audio data.

If i use mplayer as below ::
2. mplayer -ao alsa:device=hw=1,0 IEC61937_data.bin

through D2VOX device, audio output works fine. Audi o data can be listened.

I want to know the difference of above 2 commands( 1 and 2 ) .
does IEC61937 encapsulated AAC data cant pass through ALSA directly without using mplayer????
If can be played what are the steps... please reply......

@lnicola
Copy link

lnicola commented Nov 6, 2013

aplay only knows to play raw audio and not AAC or anything else. mplayer will detect the file format and properly decode it before playback.

@popcornmix
Copy link
Contributor

Try adding:
hdmi_stream_channels=1
no_hdmi_resample=1
to config.txt and reboot.

Also see #183 for how to correctly produce a IEC61937 formatted wav file.

@VanithaChannaiah
Copy link
Author

@GrayShade : Thank u for the above information.

I want to play IEC61937 encoded AAC data through the D2VOX device without decoding.
later one more device (Pioneer)which decodes the data coming from D2VOX will be decoded and played out.

So, [ 72 f8 1f 4e 07 00 68 00 ff f8 50 40 01 a2 44 d5 8b 00 c8 00 07.... ] complete data need to be sent to D2VOX.

Is it possible using ALSA directly to pass out IEC AAC data out to D2VOX.????

Below is the code i used as an application using ALSA API's to send IEC AAC data to D2VOX :

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>

int main() {
  long loops;
  int rc;
  int size;
  snd_pcm_t *handle;
  snd_pcm_hw_params_t *params;
  unsigned int val;
  int dir;
  snd_pcm_uframes_t frames;
  char *buffer;

  /* ALSA API to Open PCM device for playback. */
  rc = snd_pcm_open(&handle, "hw:1,0", SND_PCM_STREAM_PLAYBACK, 0);
  if (rc < 0) {
    fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc));
    exit(1);
  }

  /* Allocate a hardware parameters object. */
  snd_pcm_hw_params_alloca(&params);

  /*  Fill it in with device/card values. */
  snd_pcm_hw_params_any(handle, params);

  /* Set the desired hardware parameters. */
  snd_pcm_hw_params_set_access(handle, params,SND_PCM_ACCESS_RW_INTERLEAVED);

  /* Signed 16-bit little-endian format */
  snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_S16_LE);

  /* Two channels (stereo) */
  snd_pcm_hw_params_set_channels(handle, params, 2);

  /* frequency of the input stream */
  val = 32000;
  snd_pcm_hw_params_set_rate_near(handle, params,&val, &dir);

  /* Set period size to 32 frames. */
  frames = 32;
  snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);

  /* Write the parameters to the driver */
  rc = snd_pcm_hw_params(handle, params);
  if (rc < 0) {
    fprintf(stderr,"unable to set hw parameters: %s\n", snd_strerror(rc));
    exit(1);
  }

  /* Use a buffer large enough to hold one period */
  snd_pcm_hw_params_get_period_size(params, &frames, &dir);
  size = frames * 4; 
  buffer = (char *) malloc(size);

  /* We want to loop for time seconds */
  snd_pcm_hw_params_get_period_time(params,&val, &dir);
  /* 5 seconds in microseconds divided by period time */
  loops = 5000000 / val;

  while (loops > 0) {
   loops--;
    rc = read(0, buffer, size);
    rc = snd_pcm_writei(handle, buffer, frames);
  }

  snd_pcm_close(handle);
  free(buffer);

  return 0;
}

This above code play out noise. I recorded the output and checked the HEX values but no spdif header is seen....
If i record the output from D2VOX i need complete [ 72 f8 1f 4e 07 00 68 00 ff f8 50 40 01 a2 44 d5 8b 00 c8 00 07.... ] complete data.

@lnicola
Copy link

lnicola commented Nov 7, 2013

@shamyavani: Right.

I doubt any of these will help, but can you check the following:

  1. The device name: you should probably go for hw:1,0 instead of plug:hw:1,0 to make sure the stream isn't resampled.
  2. The return values of read and snd_pcm_writei. You're safe with testing with aplay: it doesn't do anything weird and if you manage to get that working, you'll be able to do the same thing from your code if you need it.
  3. The -v argument of aplay will dump information about the way the audio device is set up; for example, using your first command ("aplay -f S16_LE -Dplughw:1,0 IEC61937_data.aac") gives me a resampling plugin.
  4. Do the stream parameters (sampling rate, format, channels) matter for your hardware decoder?

@VanithaChannaiah
Copy link
Author

@popcornmix : can u pls tell where will be the config.txt. I am new to linux and ALSA

@lnicola
Copy link

lnicola commented Nov 7, 2013

It's in /boot.

@VanithaChannaiah
Copy link
Author

@GrayShade : Please check below outputs for above queries

  1. The device name: you should probably go for hw:1,0 instead of plug:hw:1,0 to make sure the stream isn't resampled.
yes, i have already done with the above solution.(hw:1,0)

If i give hw:1,0 : 
    root@Athrey-6: aplay -f S16_LE -Dhw:1,0 IEC61937_data.bin 
    Playing raw data 'IEC61937_data.bin' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
    Warning: rate is not accurate (requested = 8000Hz, got = 32000Hz)
    please, try the plug plugin
So tried with below :
    root@Athrey-6: aplay -f S16_LE -Dplughw:1,0 IEC61937_data.bin 
    Playing raw data 'IEC61937_data.bin' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
  1. The return values of read and snd_pcm_writei. You're safe with testing with aplay:
    it doesn't do anything weird and if you manage to get that working, you'll be able to do the same thing from your code if you need it.
I have added check conditions for return value for each ALSA API's return in the above code.
No where the API returns unsuccesfull.
Each API's returns successfully.
  1. The -v argument of aplay will dump information about the way the audio device is set up; for example, using your first command ("aplay -f S16_LE -Dplughw:1,0 IEC61937_data.aac") gives me a resampling plugin.
    a. aplay -v -f S16_LE -Dhw:1,0 IEC61937_data.bin 

            Playing raw data 'IEC61937_data.bin' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
            Warning: rate is not accurate (requested = 8000Hz, got = 32000Hz)
                     please, try the plug plugin 
            Hardware PCM card 1 'D2VOX USB Audio Device' device 0 subdevice 0
            Its setup is:
              stream       : PLAYBACK
              access       : RW_INTERLEAVED
              format       : S16_LE
              subformat    : STD
              channels     : 1
              rate         : 32000
              exact rate   : 32000 (32000/1)
              msbits       : 16
              buffer_size  : 16000
              period_size  : 4000
              period_time  : 125000
              tstamp_mode  : NONE
              period_step  : 1
              avail_min    : 4000
              period_event : 0
              start_threshold  : 16000
              stop_threshold   : 16000
              silence_threshold: 0
              silence_size : 0
              boundary     : 9007199254740992000
              appl_ptr     : 0
              hw_ptr       : 0 


    b. aplay -v -f S16_LE -Dplughw:1,0 IEC61937_data.bin 
            Playing raw data 'IEC61937_data.bin' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
            Plug PCM: Rate conversion PCM (32000, sformat=S16_LE)
            Converter: libspeex (builtin)
            Protocol version: 10002
            Its setup is:
              stream       : PLAYBACK
              access       : RW_INTERLEAVED
              format       : S16_LE
              subformat    : STD
              channels     : 1
              rate         : 8000
              exact rate   : 8000 (8000/1)
              msbits       : 16
              buffer_size  : 4000
              period_size  : 1000
              period_time  : 125000
              tstamp_mode  : NONE
              period_step  : 1
              avail_min    : 1000
              period_event : 0
              start_threshold  : 4000
              stop_threshold   : 4000
              silence_threshold: 0
              silence_size : 0
              boundary     : 2251799813685248000
            Slave: Hardware PCM card 1 'D2VOX USB Audio Device' device 0 subdevice 0
            Its setup is:
              stream       : PLAYBACK
              access       : MMAP_INTERLEAVED
              format       : S16_LE
              subformat    : STD
              channels     : 1
              rate         : 32000
              exact rate   : 32000 (32000/1)
              msbits       : 16
              buffer_size  : 16004
              period_size  : 4000
              period_time  : 125000
              tstamp_mode  : NONE
              period_step  : 1
              avail_min    : 4000
              period_event : 0
              start_threshold  : 16000
              stop_threshold   : 16004
              silence_threshold: 0
              silence_size : 0
              boundary     : 9009451054554677248
              appl_ptr     : 0
              hw_ptr       : 0
  1. Do the stream parameters (sampling rate, format, channels) matter for your hardware decoder?
    No, it is not necessary. I have removed those API's in above code and verified.

But still i can hear only noise as output.

@lnicola
Copy link

lnicola commented Nov 7, 2013

I have added check conditions for return value for each ALSA API's return in the above code. No where the API returns unsuccesfull. Each API's returns successfully.

I was worried about things like read() not filling the whole buffer, which could lead to some of the header bytes missing from the output. If you use aplay you should be fine.

Do the stream parameters (sampling rate, format, channels) matter for your hardware decoder?
No, it is not necessary. I have removed those API's in above code and verified.

But maybe the decoder doesn't like that 32 KHz, 1 channel stream? Can you try with something more common (like 44100 Hz)?

@popcornmix
Copy link
Contributor

Yes, HDMI PCM output always uses at least 44.1kHz (and will resample lower frequencies), so 32kHz won't work as passthrough.

It would be possible to add 32kHz PCM, but open a new github issue if that is required.

@shamyavani Is it working if you follow the procedure in #183.

@Ruffio
Copy link

Ruffio commented Jun 24, 2015

@popcornmix there has been any response to your requestion for 2 years, I think the issue can be closed

@popcornmix
Copy link
Contributor

Yes. I'm not convinced there exist any devices that support AAC passthrough.
xbmc used to have a gui option to enable AAC passthough support and never found any equipment that really supported it. It is now removed from the gui. See:
http://forum.kodi.tv/showthread.php?tid=152691&pid=1304248#pid1304248

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants