02-10-2011 01:59 PM
02-11-2011 07:18 PM
Hi treespicer,
To clarify, are you using any NI products, or do you have any questions about using NI products? If not, you may have better luck posting this on a forum for the products you are using.
It doesn't look like your post was formatted correctly, so I'm re-posting it below to make it easier to read.
Regards,
Andrew
02-14-2011 10:09 AM
Sorry, I should have previewed my post. I am using LabWindows/CVI to make a sound card oscilloscope/spectrum analyzer. I saw that others on the forum had done similar projects, so I thought someone might be familiar with the topic.
I've modified my code to fix the line-in volume to 50%. Whenever I click a "RECORD" button on my interface, the callback function performs this:
MMRESULT result; HWAVEIN waveHandle; WAVEFORMATEX waveFormat; short int waveData[220500]; WAVEHDR waveHeader; HMIXER mixerHandle; MIXERLINE mixerLine; MIXERLINECONTROLS mixerLineControls; MIXERCONTROL mixerControl; MIXERCONTROLDETAILS mixerDetails; MIXERCONTROLDETAILS_UNSIGNED lineInVolume; waveFormat.wFormatTag = WAVE_FORMAT_PCM; // standard uncompressed PCM waveFormat.nChannels = 1; // mono waveFormat.nSamplesPerSec = 44100; // 44.1 kHz sample rate waveFormat.wBitsPerSample = 16; // 16 bits per sample waveFormat.nBlockAlign = 2; // 2 bytes per sample waveFormat.nAvgBytesPerSec = 88200; // 44.1 kHz * 2 bytes per sample waveFormat.cbSize = 0; // no extra data appended for PCM // open waveform audio input, no ACM result = waveInOpen( &waveHandle, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL | WAVE_FORMAT_DIRECT ); // open mixer associated with waveform input result = mixerOpen( &mixerHandle, (UINT)waveHandle, 0, 0, MIXER_OBJECTF_HWAVEIN ); mixerLine.cbStruct = sizeof(MIXERLINE); // initialize size mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE; // look for line-in source mixer line // get line info about the line-in source mixer line result = mixerGetLineInfo( (HMIXEROBJ)mixerHandle, &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE ); mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS); // initialize size mixerLineControls.dwLineID = mixerLine.dwLineID; // line-in source mixer line ID mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; // look for volume control of line-in mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL); // initialize size mixerLineControls.cControls = 1; // one control (volume) mixerLineControls.pamxctrl = &mixerControl; // assign control storage structure // get the volume control of the line-in source mixer line result = mixerGetLineControls( (HMIXEROBJ)mixerHandle, &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE ); mixerDetails.cbStruct = sizeof(MIXERCONTROLDETAILS); // initialize size mixerDetails.dwControlID = mixerControl.dwControlID; // line-in volume control ID mixerDetails.cChannels = 1; // one channel (mono) mixerDetails.hwndOwner = 0; // no window handle mixerDetails.cMultipleItems = 0; // no multiple items mixerDetails.paDetails = &lineInVolume; // assign volume storage structure mixerDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); // initialize size lineInVolume.dwValue = 0x7FFF; // set volume to this value (50%) // set volume control of the line-in source mixer line result = mixerSetControlDetails( (HMIXEROBJ)mixerHandle, &mixerDetails, MIXER_GETCONTROLDETAILSF_VALUE ); waveHeader.dwBufferLength = 5 * 88200; // 5 seconds * 88200 bytes per second waveHeader.dwFlags = 0; // initialize flags to 0 waveHeader.lpData = (LPSTR)waveData; // assign waveform data storage structure // prepare header result = waveInPrepareHeader( waveHandle, &waveHeader, sizeof(waveHeader) ); // add buffer result = waveInAddBuffer( waveHandle, &waveHeader, sizeof(waveHeader) ); // start recording result = waveInStart( waveHandle ); // wait until recording is finished while ( waveInUnprepareHeader ( waveHandle, &waveHeader, sizeof(waveHeader) ) == WAVERR_STILLPLAYING ); // close waveform input and mixer devices result = waveInClose( waveHandle ); result = mixerClose( mixerHandle ); DeleteGraphPlot (panelHandle, PANEL_CHANNEL_LEFT, -1, VAL_IMMEDIATE_DRAW); PlotWaveform (panelHandle, PANEL_CHANNEL_LEFT, waveData, 220500, VAL_SHORT_INTEGER, 1.0, 0.0, 0.0, 1.0/44100, VAL_THIN_LINE, VAL_NO_POINT, VAL_SOLID, 1, VAL_RED);
However, the data plotted to the graph window is not at a static volume level. In the next three samples, I am recording 5 seconds with no input to line-in, so I should record low-level white noise at constant amplitude. But I get the following:
And I don't have a clue as to what is happening. It's as though there's some sort of AGC or compression on, but I have no idea how to control it. Does anybody have any ideas?
02-15-2011 12:46 PM
Hi treespicer,
It looks like you are using Windows calls to get the data from the sound card. Because of this, the National Instruments forum may not be the best forum to get help with your application. You might try posting your question on a Windows development forum.