// registers[AK4558_CTRL_1] |= AK4558_DIF1 | AK4558_DIF0; | // registers[AK4558_CTRL_1] |= AK4558_DIF1 | AK4558_DIF0; | ||||
// | // | ||||
// after manipulation, we can write the entire register value on the CODEC | // after manipulation, we can write the entire register value on the CODEC | ||||
unit8_t n = 0; | |||||
uint8_t n = 0; | |||||
Wire.requestFrom(AK4558_I2C_ADDR,10); | Wire.requestFrom(AK4558_I2C_ADDR,10); | ||||
while(Wire.available()) { | while(Wire.available()) { | ||||
#if AK4558_SERIAL_DEBUG > 0 | #if AK4558_SERIAL_DEBUG > 0 | ||||
void AudioControlAK4558::readConfig(void) | void AudioControlAK4558::readConfig(void) | ||||
{ | { | ||||
// reads registers values | // reads registers values | ||||
unit8_t n = 0; | |||||
unit8_t c = 0; | |||||
uint8_t n = 0; | |||||
uint8_t c = 0; | |||||
Wire.requestFrom(AK4558_I2C_ADDR, 10); | Wire.requestFrom(AK4558_I2C_ADDR, 10); | ||||
while(Wire.available()) { | while(Wire.available()) { | ||||
Serial.print("Register "); | Serial.print("Register "); | ||||
return true; | return true; | ||||
} | } | ||||
unsigned char AudioControlAK4558::convertVolume(float vol) | |||||
uint8_t AudioControlAK4558::convertVolume(float vol) | |||||
{ | { | ||||
// Convert float (range 0.0-1.0) to unsigned char (range 0x00-0xFF) | // Convert float (range 0.0-1.0) to unsigned char (range 0x00-0xFF) | ||||
uint8_t temp = vol>>22; | |||||
uint8_t temp = ((uint32_t)vol)>>22; | |||||
return temp; | return temp; | ||||
} | } | ||||
bool AudioControlAK4558::volume(float n) | bool AudioControlAK4558::volume(float n) | ||||
{ | { | ||||
// Set DAC output volume | // Set DAC output volume | ||||
unit8_t vol = convertVolume(n); | |||||
uint8_t vol = convertVolume(n); | |||||
registers[AK4558_LOUT_VOL] = vol; | registers[AK4558_LOUT_VOL] = vol; | ||||
registers[AK4558_ROUT_VOL] = vol; | registers[AK4558_ROUT_VOL] = vol; | ||||
Wire.beginTransmission(AK4558_I2C_ADDR); | Wire.beginTransmission(AK4558_I2C_ADDR); | ||||
return (Wire.endTransmission(true)==0); | return (Wire.endTransmission(true)==0); | ||||
} | } | ||||
bool AudioControlAK4558:::volumeLeft(float n) | |||||
bool AudioControlAK4558::volumeLeft(float n) | |||||
{ | { | ||||
// Set DAC left output volume | // Set DAC left output volume | ||||
unit8_t vol = convertVolume(n); | |||||
uint8_t vol = convertVolume(n); | |||||
registers[AK4558_LOUT_VOL] = vol; | registers[AK4558_LOUT_VOL] = vol; | ||||
bool ret = write(AK4558_LOUT_VOL, registers[AK4558_LOUT_VOL]); | bool ret = write(AK4558_LOUT_VOL, registers[AK4558_LOUT_VOL]); | ||||
#if AK4558_SERIAL_DEBUG > 0 | #if AK4558_SERIAL_DEBUG > 0 | ||||
bool AudioControlAK4558::volumeRight(float n) | bool AudioControlAK4558::volumeRight(float n) | ||||
{ | { | ||||
// Set DAC right output volume | // Set DAC right output volume | ||||
unit8_t vol = convertVolume(n); | |||||
uint8_t vol = convertVolume(n); | |||||
registers[AK4558_ROUT_VOL] = vol; | registers[AK4558_ROUT_VOL] = vol; | ||||
write(AK4558_EOUT_VOL, registers[AK4558_ROUT_VOL]); | |||||
bool ret = write(AK4558_ROUT_VOL, registers[AK4558_ROUT_VOL]); | |||||
#if AK4558_SERIAL_DEBUG > 0 | #if AK4558_SERIAL_DEBUG > 0 | ||||
Serial.print("AK4558: ROUT_VOL set to "); | Serial.print("AK4558: ROUT_VOL set to "); | ||||
Serial.println(registers[AK4558_ROUT_VOL], BIN); | Serial.println(registers[AK4558_ROUT_VOL], BIN); |
bool volumeLeft(float n); //sets LOUT volume to n (range 0.0 - 1.0) | bool volumeLeft(float n); //sets LOUT volume to n (range 0.0 - 1.0) | ||||
bool volumeRight(float n); //sets ROUT volume to n (range 0.0 - 1.0) | bool volumeRight(float n); //sets ROUT volume to n (range 0.0 - 1.0) | ||||
bool inputLevel(float n) { return false; } //not supported by AK4558 | bool inputLevel(float n) { return false; } //not supported by AK4558 | ||||
bool inputSelect(int n); {return false; } //sets inputs to mono left, mono right, stereo (default stereo), not yet implemented | |||||
bool inputSelect(int n) { return false; } //sets inputs to mono left, mono right, stereo (default stereo), not yet implemented | |||||
private: | private: | ||||
unit8_t registers[10]; | |||||
uint8_t registers[10]; | |||||
void initConfig(void); | void initConfig(void); | ||||
void readConfig(void); | void readConfig(void); | ||||
bool write(unsigned int reg, unsigned int val); | bool write(unsigned int reg, unsigned int val); | ||||
unit8_t convertVolume(float vol); | |||||
uint8_t convertVolume(float vol); | |||||
}; | }; | ||||
#endif | #endif |
AudioMemory(12); | AudioMemory(12); | ||||
while (!Serial); | while (!Serial); | ||||
ak4558.enable(); | ak4558.enable(); | ||||
ak4558.enableIn(); | |||||
ak4558.enableOut(); | |||||
} | } | ||||
void loop() { | void loop() { |
AudioMemory(12); | AudioMemory(12); | ||||
while (!Serial); | while (!Serial); | ||||
ak4558.enable(); | ak4558.enable(); | ||||
ak4558.enableOut(); | |||||
AudioNoInterrupts(); | AudioNoInterrupts(); | ||||
sine1.frequency(440); | sine1.frequency(440); | ||||
sine2.frequency(440); | sine2.frequency(440); |
</div> | </div> | ||||
</script> | </script> | ||||
<script type="text/x-red" data-help-name="AudioControlAK4558"> | |||||
<h3>Summary</h3> | |||||
<p>Control the AK4558 chip on the <a href="https://hackaday.io/project/8567-hifi-audio-codec-module" target="_blank">HiFi Audio CODEC Module</a> | |||||
in slave mode, where the Teensy controls all I2S timing.</p> | |||||
<h3>Audio Connections</h3> | |||||
<p>This object has no audio inputs or outputs. Separate I2S objects | |||||
are used to send and receive audio data. | |||||
</p> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>enable</span>();</p> | |||||
<p class=desc>Enables the CODEC to work with 44.1 KHz - 16 bit data. This function does not enable the ADC/DAC modules. | |||||
</p> | |||||
<p class=func><span class=keyword>enableIn</span>();</p> | |||||
<p class=desc>Enables the ADC module. | |||||
</p> | |||||
<p class=func><span class=keyword>enableOut</span>();</p> | |||||
<p class=desc>Enables the DAC module. | |||||
</p> | |||||
<p class=func><span class=keyword>disable</span>();</p> | |||||
<p class=desc>Disables the ADC and the DAC modules. | |||||
</p> | |||||
<p class=func><span class=keyword>disableIn</span>();</p> | |||||
<p class=desc>Disable the ADC module. | |||||
</p> | |||||
<p class=func><span class=keyword>disableOut</span>();</p> | |||||
<p class=desc>Disable the DAC module. | |||||
</p> | |||||
<p class=func><span class=keyword>volume</span>(level);</p> | |||||
<p class=desc>Accepts a float in range 0.0-1.0 and sets the line output volume accordingly. | |||||
</p> | |||||
<p class=func><span class=keyword>volumeLeft</span>(level);</p> | |||||
<p class=desc>Accepts a float in range 0.0-1.0 and sets the left line output volume accordingly. | |||||
</p> | |||||
<p class=func><span class=keyword>volumeRight</span>(level);</p> | |||||
<p class=desc>Accepts a float in range 0.0-1.0 and sets the right line output volume accordingly. | |||||
</p> | |||||
<p class=func><span class=keyword>inputLevel</span>(level);</p> | |||||
<p class=desc>NOT SUPPORTED BY THE AK4558 | |||||
</p> | |||||
<p class=func><span class=keyword>inputSelect</span>(input);</p> | |||||
<p class=desc>not implemented yet | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > AK4558 > PassthroughTest | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > AK4558 > SineOutTest | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>TODO: Implement inputSelect() function to enable mono left, mono right, stereo operation.</p> | |||||
<p>TODO: Implement ADC and DAC filters control.</p> | |||||
<p>TODO: Implement DAC level attenuator attack rate modifier.</p> | |||||
</script> | |||||
<script type="text/x-red" data-template-name="AudioControlWM8731master"> | |||||
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> | |||||
</script> | |||||
</body> | </body> | ||||
</html> | </html> |